diff --git a/CMakeLists.txt b/CMakeLists.txt index c3fb17317..36e496376 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,7 +35,7 @@ ENDIF(LMMS_HOST_X86_64) OPTION(WANT_ALSA "Include ALSA (Advanced Linux Sound Architecture) support" ON) OPTION(WANT_CAPS "Include C* Audio Plugin Suite (LADSPA plugins)" ON) OPTION(WANT_CMT "Include Computer Music Toolkit LADSPA plugins" ON) -OPTION(WANT_FFTW3F "Include SpectrumAnalyzer plugin" ON) +OPTION(WANT_FFTW3F "Include SpectrumAnalyzer and ZynAddSubFX plugin" ON) OPTION(WANT_JACK "Include JACK (Jack Audio Connection Kit) support" ON) OPTION(WANT_OGGVORBIS "Include OGG/Vorbis support" ON) OPTION(WANT_PULSEAUDIO "Include PulseAudio support" ON) @@ -606,6 +606,7 @@ MESSAGE( "* CMT LADSPA plugins : ${STATUS_CMT}\n" "* TAP LADSPA plugins : ${STATUS_TAP}\n" "* SWH LADSPA plugins : ${STATUS_SWH}\n" +"* ZynAddSubFX : ${STATUS_FFTW3F}\n" ) MESSAGE( diff --git a/data/presets/CMakeLists.txt b/data/presets/CMakeLists.txt index 79240a551..f72ecc4aa 100644 --- a/data/presets/CMakeLists.txt +++ b/data/presets/CMakeLists.txt @@ -1,4 +1,5 @@ INCLUDE(InstallHelpers) INSTALL_DATA_SUBDIRS("presets" "*.xpf") +INSTALL_DATA_SUBDIRS("presets" "*.xiz") diff --git a/data/presets/ZynAddSubFX/Arpeggios/0001-Arpeggio1.xiz b/data/presets/ZynAddSubFX/Arpeggios/0001-Arpeggio1.xiz new file mode 100644 index 000000000..396d9622a Binary files /dev/null and b/data/presets/ZynAddSubFX/Arpeggios/0001-Arpeggio1.xiz differ diff --git a/data/presets/ZynAddSubFX/Arpeggios/0002-Arpeggio2.xiz b/data/presets/ZynAddSubFX/Arpeggios/0002-Arpeggio2.xiz new file mode 100644 index 000000000..09ff70196 Binary files /dev/null and b/data/presets/ZynAddSubFX/Arpeggios/0002-Arpeggio2.xiz differ diff --git a/data/presets/ZynAddSubFX/Arpeggios/0003-Arpeggio3.xiz b/data/presets/ZynAddSubFX/Arpeggios/0003-Arpeggio3.xiz new file mode 100644 index 000000000..d163b4368 Binary files /dev/null and b/data/presets/ZynAddSubFX/Arpeggios/0003-Arpeggio3.xiz differ diff --git a/data/presets/ZynAddSubFX/Arpeggios/0004-Arpeggio4.xiz b/data/presets/ZynAddSubFX/Arpeggios/0004-Arpeggio4.xiz new file mode 100644 index 000000000..c30f998c9 Binary files /dev/null and b/data/presets/ZynAddSubFX/Arpeggios/0004-Arpeggio4.xiz differ diff --git a/data/presets/ZynAddSubFX/Arpeggios/0005-Arpeggio5.xiz b/data/presets/ZynAddSubFX/Arpeggios/0005-Arpeggio5.xiz new file mode 100644 index 000000000..cf8d7646a Binary files /dev/null and b/data/presets/ZynAddSubFX/Arpeggios/0005-Arpeggio5.xiz differ diff --git a/data/presets/ZynAddSubFX/Arpeggios/0006-Aporggio6.xiz b/data/presets/ZynAddSubFX/Arpeggios/0006-Aporggio6.xiz new file mode 100644 index 000000000..2d1c9e7b4 Binary files /dev/null and b/data/presets/ZynAddSubFX/Arpeggios/0006-Aporggio6.xiz differ diff --git a/data/presets/ZynAddSubFX/Arpeggios/0007-Arpeggio7.xiz b/data/presets/ZynAddSubFX/Arpeggios/0007-Arpeggio7.xiz new file mode 100644 index 000000000..0261a1880 Binary files /dev/null and b/data/presets/ZynAddSubFX/Arpeggios/0007-Arpeggio7.xiz differ diff --git a/data/presets/ZynAddSubFX/Arpeggios/0008-Arpeggio8.xiz b/data/presets/ZynAddSubFX/Arpeggios/0008-Arpeggio8.xiz new file mode 100644 index 000000000..63a3a62d9 Binary files /dev/null and b/data/presets/ZynAddSubFX/Arpeggios/0008-Arpeggio8.xiz differ diff --git a/data/presets/ZynAddSubFX/Arpeggios/0009-Arpeggio9.xiz b/data/presets/ZynAddSubFX/Arpeggios/0009-Arpeggio9.xiz new file mode 100644 index 000000000..a36770352 Binary files /dev/null and b/data/presets/ZynAddSubFX/Arpeggios/0009-Arpeggio9.xiz differ diff --git a/data/presets/ZynAddSubFX/Arpeggios/0010-Arpeggio10.xiz b/data/presets/ZynAddSubFX/Arpeggios/0010-Arpeggio10.xiz new file mode 100644 index 000000000..0ebd284af Binary files /dev/null and b/data/presets/ZynAddSubFX/Arpeggios/0010-Arpeggio10.xiz differ diff --git a/data/presets/ZynAddSubFX/Arpeggios/0011-Arpeggio11.xiz b/data/presets/ZynAddSubFX/Arpeggios/0011-Arpeggio11.xiz new file mode 100644 index 000000000..226b30579 Binary files /dev/null and b/data/presets/ZynAddSubFX/Arpeggios/0011-Arpeggio11.xiz differ diff --git a/data/presets/ZynAddSubFX/Arpeggios/0033-Sequence1.xiz b/data/presets/ZynAddSubFX/Arpeggios/0033-Sequence1.xiz new file mode 100644 index 000000000..2f04b62e9 Binary files /dev/null and b/data/presets/ZynAddSubFX/Arpeggios/0033-Sequence1.xiz differ diff --git a/data/presets/ZynAddSubFX/Arpeggios/0034-Sequence2.xiz b/data/presets/ZynAddSubFX/Arpeggios/0034-Sequence2.xiz new file mode 100644 index 000000000..732091a9a Binary files /dev/null and b/data/presets/ZynAddSubFX/Arpeggios/0034-Sequence2.xiz differ diff --git a/data/presets/ZynAddSubFX/Arpeggios/0036-Echoed Synth.xiz b/data/presets/ZynAddSubFX/Arpeggios/0036-Echoed Synth.xiz new file mode 100644 index 000000000..2d9dd54d4 Binary files /dev/null and b/data/presets/ZynAddSubFX/Arpeggios/0036-Echoed Synth.xiz differ diff --git a/data/presets/ZynAddSubFX/Arpeggios/0037-Echo FX.xiz b/data/presets/ZynAddSubFX/Arpeggios/0037-Echo FX.xiz new file mode 100644 index 000000000..c41564c6f Binary files /dev/null and b/data/presets/ZynAddSubFX/Arpeggios/0037-Echo FX.xiz differ diff --git a/data/presets/ZynAddSubFX/Arpeggios/0039-Soft Arpeggio1.xiz b/data/presets/ZynAddSubFX/Arpeggios/0039-Soft Arpeggio1.xiz new file mode 100644 index 000000000..3ae201fe2 Binary files /dev/null and b/data/presets/ZynAddSubFX/Arpeggios/0039-Soft Arpeggio1.xiz differ diff --git a/data/presets/ZynAddSubFX/Arpeggios/0040-Soft Arpeggio2.xiz b/data/presets/ZynAddSubFX/Arpeggios/0040-Soft Arpeggio2.xiz new file mode 100644 index 000000000..54d9a7d77 Binary files /dev/null and b/data/presets/ZynAddSubFX/Arpeggios/0040-Soft Arpeggio2.xiz differ diff --git a/data/presets/ZynAddSubFX/Arpeggios/0041-Soft Arpeggio3.xiz b/data/presets/ZynAddSubFX/Arpeggios/0041-Soft Arpeggio3.xiz new file mode 100644 index 000000000..b6f854fed Binary files /dev/null and b/data/presets/ZynAddSubFX/Arpeggios/0041-Soft Arpeggio3.xiz differ diff --git a/data/presets/ZynAddSubFX/Arpeggios/0042-Soft Arpeggio4.xiz b/data/presets/ZynAddSubFX/Arpeggios/0042-Soft Arpeggio4.xiz new file mode 100644 index 000000000..b62440482 Binary files /dev/null and b/data/presets/ZynAddSubFX/Arpeggios/0042-Soft Arpeggio4.xiz differ diff --git a/data/presets/ZynAddSubFX/Arpeggios/0043-Soft Arpeggio5.xiz b/data/presets/ZynAddSubFX/Arpeggios/0043-Soft Arpeggio5.xiz new file mode 100644 index 000000000..f88e96822 Binary files /dev/null and b/data/presets/ZynAddSubFX/Arpeggios/0043-Soft Arpeggio5.xiz differ diff --git a/data/presets/ZynAddSubFX/Arpeggios/0065-Hyper Organ1.xiz b/data/presets/ZynAddSubFX/Arpeggios/0065-Hyper Organ1.xiz new file mode 100644 index 000000000..c2b83f943 Binary files /dev/null and b/data/presets/ZynAddSubFX/Arpeggios/0065-Hyper Organ1.xiz differ diff --git a/data/presets/ZynAddSubFX/Arpeggios/0066-Hyper Arpeggio.xiz b/data/presets/ZynAddSubFX/Arpeggios/0066-Hyper Arpeggio.xiz new file mode 100644 index 000000000..be3eeae86 Binary files /dev/null and b/data/presets/ZynAddSubFX/Arpeggios/0066-Hyper Arpeggio.xiz differ diff --git a/data/presets/ZynAddSubFX/Arpeggios/0068-Glass Arpeggio.xiz b/data/presets/ZynAddSubFX/Arpeggios/0068-Glass Arpeggio.xiz new file mode 100644 index 000000000..6e3bd476c Binary files /dev/null and b/data/presets/ZynAddSubFX/Arpeggios/0068-Glass Arpeggio.xiz differ diff --git a/data/presets/ZynAddSubFX/Bass/0001-Bass 1.xiz b/data/presets/ZynAddSubFX/Bass/0001-Bass 1.xiz new file mode 100644 index 000000000..8d507e004 Binary files /dev/null and b/data/presets/ZynAddSubFX/Bass/0001-Bass 1.xiz differ diff --git a/data/presets/ZynAddSubFX/Bass/0002-Bass 2.xiz b/data/presets/ZynAddSubFX/Bass/0002-Bass 2.xiz new file mode 100644 index 000000000..2181ed591 Binary files /dev/null and b/data/presets/ZynAddSubFX/Bass/0002-Bass 2.xiz differ diff --git a/data/presets/ZynAddSubFX/Bass/0003-Bass 3 _analog_.xiz b/data/presets/ZynAddSubFX/Bass/0003-Bass 3 _analog_.xiz new file mode 100644 index 000000000..9d9fa4f2c Binary files /dev/null and b/data/presets/ZynAddSubFX/Bass/0003-Bass 3 _analog_.xiz differ diff --git a/data/presets/ZynAddSubFX/Bass/0004-Bass 4.xiz b/data/presets/ZynAddSubFX/Bass/0004-Bass 4.xiz new file mode 100644 index 000000000..3326da6d5 Binary files /dev/null and b/data/presets/ZynAddSubFX/Bass/0004-Bass 4.xiz differ diff --git a/data/presets/ZynAddSubFX/Bass/0005-Bass 5.xiz b/data/presets/ZynAddSubFX/Bass/0005-Bass 5.xiz new file mode 100644 index 000000000..6df414ee6 Binary files /dev/null and b/data/presets/ZynAddSubFX/Bass/0005-Bass 5.xiz differ diff --git a/data/presets/ZynAddSubFX/Bass/0006-Analogue Bass.xiz b/data/presets/ZynAddSubFX/Bass/0006-Analogue Bass.xiz new file mode 100644 index 000000000..167fabfb6 Binary files /dev/null and b/data/presets/ZynAddSubFX/Bass/0006-Analogue Bass.xiz differ diff --git a/data/presets/ZynAddSubFX/Bass/0033-Wah Bass.xiz b/data/presets/ZynAddSubFX/Bass/0033-Wah Bass.xiz new file mode 100644 index 000000000..e34c3c1c6 Binary files /dev/null and b/data/presets/ZynAddSubFX/Bass/0033-Wah Bass.xiz differ diff --git a/data/presets/ZynAddSubFX/Bass/0035-FM Bass 1.xiz b/data/presets/ZynAddSubFX/Bass/0035-FM Bass 1.xiz new file mode 100644 index 000000000..ce5bc146b Binary files /dev/null and b/data/presets/ZynAddSubFX/Bass/0035-FM Bass 1.xiz differ diff --git a/data/presets/ZynAddSubFX/Bass/0036-FM Bass 2.xiz b/data/presets/ZynAddSubFX/Bass/0036-FM Bass 2.xiz new file mode 100644 index 000000000..00efafc27 Binary files /dev/null and b/data/presets/ZynAddSubFX/Bass/0036-FM Bass 2.xiz differ diff --git a/data/presets/ZynAddSubFX/Brass/0001-FM Thrumpet.xiz b/data/presets/ZynAddSubFX/Brass/0001-FM Thrumpet.xiz new file mode 100644 index 000000000..e8bd54e91 Binary files /dev/null and b/data/presets/ZynAddSubFX/Brass/0001-FM Thrumpet.xiz differ diff --git a/data/presets/ZynAddSubFX/Brass/0003-Synth Brazz 1.xiz b/data/presets/ZynAddSubFX/Brass/0003-Synth Brazz 1.xiz new file mode 100644 index 000000000..ee3637324 Binary files /dev/null and b/data/presets/ZynAddSubFX/Brass/0003-Synth Brazz 1.xiz differ diff --git a/data/presets/ZynAddSubFX/Brass/0004-Synth Brazz 2.xiz b/data/presets/ZynAddSubFX/Brass/0004-Synth Brazz 2.xiz new file mode 100644 index 000000000..c60c0678f Binary files /dev/null and b/data/presets/ZynAddSubFX/Brass/0004-Synth Brazz 2.xiz differ diff --git a/data/presets/ZynAddSubFX/Brass/0005-Synth Brass 3.xiz b/data/presets/ZynAddSubFX/Brass/0005-Synth Brass 3.xiz new file mode 100644 index 000000000..99d16cc90 Binary files /dev/null and b/data/presets/ZynAddSubFX/Brass/0005-Synth Brass 3.xiz differ diff --git a/data/presets/ZynAddSubFX/Brass/0006-Synth Brass 4.xiz b/data/presets/ZynAddSubFX/Brass/0006-Synth Brass 4.xiz new file mode 100644 index 000000000..d476134aa Binary files /dev/null and b/data/presets/ZynAddSubFX/Brass/0006-Synth Brass 4.xiz differ diff --git a/data/presets/ZynAddSubFX/Brass/0007-Synth Brass 5.xiz b/data/presets/ZynAddSubFX/Brass/0007-Synth Brass 5.xiz new file mode 100644 index 000000000..4db26a9aa Binary files /dev/null and b/data/presets/ZynAddSubFX/Brass/0007-Synth Brass 5.xiz differ diff --git a/data/presets/ZynAddSubFX/Brass/0008-Brass Pad.xiz b/data/presets/ZynAddSubFX/Brass/0008-Brass Pad.xiz new file mode 100644 index 000000000..d6d51a085 Binary files /dev/null and b/data/presets/ZynAddSubFX/Brass/0008-Brass Pad.xiz differ diff --git a/data/presets/ZynAddSubFX/Brass/0009-Wah Brass.xiz b/data/presets/ZynAddSubFX/Brass/0009-Wah Brass.xiz new file mode 100644 index 000000000..a13532e3a Binary files /dev/null and b/data/presets/ZynAddSubFX/Brass/0009-Wah Brass.xiz differ diff --git a/data/presets/ZynAddSubFX/Brass/0010-Solo Synth1.xiz b/data/presets/ZynAddSubFX/Brass/0010-Solo Synth1.xiz new file mode 100644 index 000000000..96f1b144b Binary files /dev/null and b/data/presets/ZynAddSubFX/Brass/0010-Solo Synth1.xiz differ diff --git a/data/presets/ZynAddSubFX/Brass/0011-Brazz 1.xiz b/data/presets/ZynAddSubFX/Brass/0011-Brazz 1.xiz new file mode 100644 index 000000000..f3d097d4b Binary files /dev/null and b/data/presets/ZynAddSubFX/Brass/0011-Brazz 1.xiz differ diff --git a/data/presets/ZynAddSubFX/Brass/0012-Brazz 2.xiz b/data/presets/ZynAddSubFX/Brass/0012-Brazz 2.xiz new file mode 100644 index 000000000..fc1b4f086 Binary files /dev/null and b/data/presets/ZynAddSubFX/Brass/0012-Brazz 2.xiz differ diff --git a/data/presets/ZynAddSubFX/Brass/0033-Analog Brass 1.xiz b/data/presets/ZynAddSubFX/Brass/0033-Analog Brass 1.xiz new file mode 100644 index 000000000..a67142aef Binary files /dev/null and b/data/presets/ZynAddSubFX/Brass/0033-Analog Brass 1.xiz differ diff --git a/data/presets/ZynAddSubFX/Brass/0034-Analog Brass 2.xiz b/data/presets/ZynAddSubFX/Brass/0034-Analog Brass 2.xiz new file mode 100644 index 000000000..5aabda40a Binary files /dev/null and b/data/presets/ZynAddSubFX/Brass/0034-Analog Brass 2.xiz differ diff --git a/data/presets/ZynAddSubFX/Brass/0035-Analog Brass 3.xiz b/data/presets/ZynAddSubFX/Brass/0035-Analog Brass 3.xiz new file mode 100644 index 000000000..aa2cfe2a4 Binary files /dev/null and b/data/presets/ZynAddSubFX/Brass/0035-Analog Brass 3.xiz differ diff --git a/data/presets/ZynAddSubFX/Brass/0036-Analog Brass 4.xiz b/data/presets/ZynAddSubFX/Brass/0036-Analog Brass 4.xiz new file mode 100644 index 000000000..2b965c23f Binary files /dev/null and b/data/presets/ZynAddSubFX/Brass/0036-Analog Brass 4.xiz differ diff --git a/data/presets/ZynAddSubFX/Brass/0065-Simple Brass.xiz b/data/presets/ZynAddSubFX/Brass/0065-Simple Brass.xiz new file mode 100644 index 000000000..40cd58df6 Binary files /dev/null and b/data/presets/ZynAddSubFX/Brass/0065-Simple Brass.xiz differ diff --git a/data/presets/ZynAddSubFX/Brass/0066-Fat Brass.xiz b/data/presets/ZynAddSubFX/Brass/0066-Fat Brass.xiz new file mode 100644 index 000000000..cc516075c Binary files /dev/null and b/data/presets/ZynAddSubFX/Brass/0066-Fat Brass.xiz differ diff --git a/data/presets/ZynAddSubFX/ChoirAndVoice/0001-AHH Choir 1.xiz b/data/presets/ZynAddSubFX/ChoirAndVoice/0001-AHH Choir 1.xiz new file mode 100644 index 000000000..6184fdcd2 Binary files /dev/null and b/data/presets/ZynAddSubFX/ChoirAndVoice/0001-AHH Choir 1.xiz differ diff --git a/data/presets/ZynAddSubFX/ChoirAndVoice/0002-AHH Choir 2.xiz b/data/presets/ZynAddSubFX/ChoirAndVoice/0002-AHH Choir 2.xiz new file mode 100644 index 000000000..ff177acd9 Binary files /dev/null and b/data/presets/ZynAddSubFX/ChoirAndVoice/0002-AHH Choir 2.xiz differ diff --git a/data/presets/ZynAddSubFX/ChoirAndVoice/0003-EHH Choir 1.xiz b/data/presets/ZynAddSubFX/ChoirAndVoice/0003-EHH Choir 1.xiz new file mode 100644 index 000000000..6eda8d22d Binary files /dev/null and b/data/presets/ZynAddSubFX/ChoirAndVoice/0003-EHH Choir 1.xiz differ diff --git a/data/presets/ZynAddSubFX/ChoirAndVoice/0004-Voice OOH.xiz b/data/presets/ZynAddSubFX/ChoirAndVoice/0004-Voice OOH.xiz new file mode 100644 index 000000000..d89e5b465 Binary files /dev/null and b/data/presets/ZynAddSubFX/ChoirAndVoice/0004-Voice OOH.xiz differ diff --git a/data/presets/ZynAddSubFX/ChoirAndVoice/0005-Choir Pad1.xiz b/data/presets/ZynAddSubFX/ChoirAndVoice/0005-Choir Pad1.xiz new file mode 100644 index 000000000..0f6b6e4fb Binary files /dev/null and b/data/presets/ZynAddSubFX/ChoirAndVoice/0005-Choir Pad1.xiz differ diff --git a/data/presets/ZynAddSubFX/ChoirAndVoice/0006-Choir Pad2.xiz b/data/presets/ZynAddSubFX/ChoirAndVoice/0006-Choir Pad2.xiz new file mode 100644 index 000000000..67d30c5a6 Binary files /dev/null and b/data/presets/ZynAddSubFX/ChoirAndVoice/0006-Choir Pad2.xiz differ diff --git a/data/presets/ZynAddSubFX/ChoirAndVoice/0007-Choir Pad3.xiz b/data/presets/ZynAddSubFX/ChoirAndVoice/0007-Choir Pad3.xiz new file mode 100644 index 000000000..531299034 Binary files /dev/null and b/data/presets/ZynAddSubFX/ChoirAndVoice/0007-Choir Pad3.xiz differ diff --git a/data/presets/ZynAddSubFX/ChoirAndVoice/0008-Choir Pad4.xiz b/data/presets/ZynAddSubFX/ChoirAndVoice/0008-Choir Pad4.xiz new file mode 100644 index 000000000..a390e6215 Binary files /dev/null and b/data/presets/ZynAddSubFX/ChoirAndVoice/0008-Choir Pad4.xiz differ diff --git a/data/presets/ZynAddSubFX/ChoirAndVoice/0009-Choir Pad5.xiz b/data/presets/ZynAddSubFX/ChoirAndVoice/0009-Choir Pad5.xiz new file mode 100644 index 000000000..8b9e2631c Binary files /dev/null and b/data/presets/ZynAddSubFX/ChoirAndVoice/0009-Choir Pad5.xiz differ diff --git a/data/presets/ZynAddSubFX/ChoirAndVoice/0010-Choir Pad6.xiz b/data/presets/ZynAddSubFX/ChoirAndVoice/0010-Choir Pad6.xiz new file mode 100644 index 000000000..475474aad Binary files /dev/null and b/data/presets/ZynAddSubFX/ChoirAndVoice/0010-Choir Pad6.xiz differ diff --git a/data/presets/ZynAddSubFX/ChoirAndVoice/0033-Choir.xiz b/data/presets/ZynAddSubFX/ChoirAndVoice/0033-Choir.xiz new file mode 100644 index 000000000..9511e4244 Binary files /dev/null and b/data/presets/ZynAddSubFX/ChoirAndVoice/0033-Choir.xiz differ diff --git a/data/presets/ZynAddSubFX/ChoirAndVoice/0034-Slow Morph_Choir.xiz b/data/presets/ZynAddSubFX/ChoirAndVoice/0034-Slow Morph_Choir.xiz new file mode 100644 index 000000000..fad34e287 Binary files /dev/null and b/data/presets/ZynAddSubFX/ChoirAndVoice/0034-Slow Morph_Choir.xiz differ diff --git a/data/presets/ZynAddSubFX/ChoirAndVoice/0035-Wah Choir.xiz b/data/presets/ZynAddSubFX/ChoirAndVoice/0035-Wah Choir.xiz new file mode 100644 index 000000000..4bcffcf95 Binary files /dev/null and b/data/presets/ZynAddSubFX/ChoirAndVoice/0035-Wah Choir.xiz differ diff --git a/data/presets/ZynAddSubFX/ChoirAndVoice/0036-Eooooo.xiz b/data/presets/ZynAddSubFX/ChoirAndVoice/0036-Eooooo.xiz new file mode 100644 index 000000000..018c4452d Binary files /dev/null and b/data/presets/ZynAddSubFX/ChoirAndVoice/0036-Eooooo.xiz differ diff --git a/data/presets/ZynAddSubFX/ChoirAndVoice/0037-Voiced Synth.xiz b/data/presets/ZynAddSubFX/ChoirAndVoice/0037-Voiced Synth.xiz new file mode 100644 index 000000000..e7518d15b Binary files /dev/null and b/data/presets/ZynAddSubFX/ChoirAndVoice/0037-Voiced Synth.xiz differ diff --git a/data/presets/ZynAddSubFX/ChoirAndVoice/0039-Ohh Choir.xiz b/data/presets/ZynAddSubFX/ChoirAndVoice/0039-Ohh Choir.xiz new file mode 100644 index 000000000..eb21ea520 Binary files /dev/null and b/data/presets/ZynAddSubFX/ChoirAndVoice/0039-Ohh Choir.xiz differ diff --git a/data/presets/ZynAddSubFX/ChoirAndVoice/0065-Vocal Morph 1.xiz b/data/presets/ZynAddSubFX/ChoirAndVoice/0065-Vocal Morph 1.xiz new file mode 100644 index 000000000..a96975adf Binary files /dev/null and b/data/presets/ZynAddSubFX/ChoirAndVoice/0065-Vocal Morph 1.xiz differ diff --git a/data/presets/ZynAddSubFX/ChoirAndVoice/0066-Vocal Morph 2.xiz b/data/presets/ZynAddSubFX/ChoirAndVoice/0066-Vocal Morph 2.xiz new file mode 100644 index 000000000..f46bef70e Binary files /dev/null and b/data/presets/ZynAddSubFX/ChoirAndVoice/0066-Vocal Morph 2.xiz differ diff --git a/data/presets/ZynAddSubFX/ChoirAndVoice/0067-Vocal Morph 3.xiz b/data/presets/ZynAddSubFX/ChoirAndVoice/0067-Vocal Morph 3.xiz new file mode 100644 index 000000000..61c17b473 Binary files /dev/null and b/data/presets/ZynAddSubFX/ChoirAndVoice/0067-Vocal Morph 3.xiz differ diff --git a/data/presets/ZynAddSubFX/ChoirAndVoice/0068-Vocal Morph 4.xiz b/data/presets/ZynAddSubFX/ChoirAndVoice/0068-Vocal Morph 4.xiz new file mode 100644 index 000000000..f33f21c31 Binary files /dev/null and b/data/presets/ZynAddSubFX/ChoirAndVoice/0068-Vocal Morph 4.xiz differ diff --git a/data/presets/ZynAddSubFX/ChoirAndVoice/0069-Vocal Morph 5.xiz b/data/presets/ZynAddSubFX/ChoirAndVoice/0069-Vocal Morph 5.xiz new file mode 100644 index 000000000..aa5ed565a Binary files /dev/null and b/data/presets/ZynAddSubFX/ChoirAndVoice/0069-Vocal Morph 5.xiz differ diff --git a/data/presets/ZynAddSubFX/ChoirAndVoice/0070-Vocal Morph 6.xiz b/data/presets/ZynAddSubFX/ChoirAndVoice/0070-Vocal Morph 6.xiz new file mode 100644 index 000000000..a9db003cb Binary files /dev/null and b/data/presets/ZynAddSubFX/ChoirAndVoice/0070-Vocal Morph 6.xiz differ diff --git a/data/presets/ZynAddSubFX/ChoirAndVoice/0071-Vocal Morph 7.xiz b/data/presets/ZynAddSubFX/ChoirAndVoice/0071-Vocal Morph 7.xiz new file mode 100644 index 000000000..c48fa19ba Binary files /dev/null and b/data/presets/ZynAddSubFX/ChoirAndVoice/0071-Vocal Morph 7.xiz differ diff --git a/data/presets/ZynAddSubFX/Drums/0001-Drums Kit1.xiz b/data/presets/ZynAddSubFX/Drums/0001-Drums Kit1.xiz new file mode 100644 index 000000000..eac3faa45 Binary files /dev/null and b/data/presets/ZynAddSubFX/Drums/0001-Drums Kit1.xiz differ diff --git a/data/presets/ZynAddSubFX/Dual/0001-Layered1.xiz b/data/presets/ZynAddSubFX/Dual/0001-Layered1.xiz new file mode 100644 index 000000000..b87c7a3d1 Binary files /dev/null and b/data/presets/ZynAddSubFX/Dual/0001-Layered1.xiz differ diff --git a/data/presets/ZynAddSubFX/Dual/0002-Layered2.xiz b/data/presets/ZynAddSubFX/Dual/0002-Layered2.xiz new file mode 100644 index 000000000..ae06071a1 Binary files /dev/null and b/data/presets/ZynAddSubFX/Dual/0002-Layered2.xiz differ diff --git a/data/presets/ZynAddSubFX/Dual/0005-Organ and Saw.xiz b/data/presets/ZynAddSubFX/Dual/0005-Organ and Saw.xiz new file mode 100644 index 000000000..d9f419aba Binary files /dev/null and b/data/presets/ZynAddSubFX/Dual/0005-Organ and Saw.xiz differ diff --git a/data/presets/ZynAddSubFX/Dual/0007-Organ Choir Pad1.xiz b/data/presets/ZynAddSubFX/Dual/0007-Organ Choir Pad1.xiz new file mode 100644 index 000000000..38c44fca0 Binary files /dev/null and b/data/presets/ZynAddSubFX/Dual/0007-Organ Choir Pad1.xiz differ diff --git a/data/presets/ZynAddSubFX/Dual/0008-Organ Choir Pad2.xiz b/data/presets/ZynAddSubFX/Dual/0008-Organ Choir Pad2.xiz new file mode 100644 index 000000000..88e99146a Binary files /dev/null and b/data/presets/ZynAddSubFX/Dual/0008-Organ Choir Pad2.xiz differ diff --git a/data/presets/ZynAddSubFX/Dual/0033-Rhodes Strings1.xiz b/data/presets/ZynAddSubFX/Dual/0033-Rhodes Strings1.xiz new file mode 100644 index 000000000..9c1f7804f Binary files /dev/null and b/data/presets/ZynAddSubFX/Dual/0033-Rhodes Strings1.xiz differ diff --git a/data/presets/ZynAddSubFX/Dual/0034-Rhodes Strings2.xiz b/data/presets/ZynAddSubFX/Dual/0034-Rhodes Strings2.xiz new file mode 100644 index 000000000..b932a312d Binary files /dev/null and b/data/presets/ZynAddSubFX/Dual/0034-Rhodes Strings2.xiz differ diff --git a/data/presets/ZynAddSubFX/Dual/0035-Rhodes Strings3.xiz b/data/presets/ZynAddSubFX/Dual/0035-Rhodes Strings3.xiz new file mode 100644 index 000000000..3e2d6ebe2 Binary files /dev/null and b/data/presets/ZynAddSubFX/Dual/0035-Rhodes Strings3.xiz differ diff --git a/data/presets/ZynAddSubFX/Dual/0036-Rhodes Strings4.xiz b/data/presets/ZynAddSubFX/Dual/0036-Rhodes Strings4.xiz new file mode 100644 index 000000000..0a7725fc5 Binary files /dev/null and b/data/presets/ZynAddSubFX/Dual/0036-Rhodes Strings4.xiz differ diff --git a/data/presets/ZynAddSubFX/Dual/0065-Dream of the Saw.xiz b/data/presets/ZynAddSubFX/Dual/0065-Dream of the Saw.xiz new file mode 100644 index 000000000..ef7efae3d Binary files /dev/null and b/data/presets/ZynAddSubFX/Dual/0065-Dream of the Saw.xiz differ diff --git a/data/presets/ZynAddSubFX/Fantasy/0001-Emptyness1.xiz b/data/presets/ZynAddSubFX/Fantasy/0001-Emptyness1.xiz new file mode 100644 index 000000000..ce78b60ea Binary files /dev/null and b/data/presets/ZynAddSubFX/Fantasy/0001-Emptyness1.xiz differ diff --git a/data/presets/ZynAddSubFX/Fantasy/0002-Emptyness2.xiz b/data/presets/ZynAddSubFX/Fantasy/0002-Emptyness2.xiz new file mode 100644 index 000000000..fa071c450 Binary files /dev/null and b/data/presets/ZynAddSubFX/Fantasy/0002-Emptyness2.xiz differ diff --git a/data/presets/ZynAddSubFX/Fantasy/0003-Space Synth.xiz b/data/presets/ZynAddSubFX/Fantasy/0003-Space Synth.xiz new file mode 100644 index 000000000..b5dcfefdf Binary files /dev/null and b/data/presets/ZynAddSubFX/Fantasy/0003-Space Synth.xiz differ diff --git a/data/presets/ZynAddSubFX/Fantasy/0004-Weird Pad.xiz b/data/presets/ZynAddSubFX/Fantasy/0004-Weird Pad.xiz new file mode 100644 index 000000000..f66db7c4f Binary files /dev/null and b/data/presets/ZynAddSubFX/Fantasy/0004-Weird Pad.xiz differ diff --git a/data/presets/ZynAddSubFX/Fantasy/0006-Space SynthBrass.xiz b/data/presets/ZynAddSubFX/Fantasy/0006-Space SynthBrass.xiz new file mode 100644 index 000000000..f235cc962 Binary files /dev/null and b/data/presets/ZynAddSubFX/Fantasy/0006-Space SynthBrass.xiz differ diff --git a/data/presets/ZynAddSubFX/Fantasy/0008-Space Voice1.xiz b/data/presets/ZynAddSubFX/Fantasy/0008-Space Voice1.xiz new file mode 100644 index 000000000..09b13e677 Binary files /dev/null and b/data/presets/ZynAddSubFX/Fantasy/0008-Space Voice1.xiz differ diff --git a/data/presets/ZynAddSubFX/Fantasy/0009-Space Voice2.xiz b/data/presets/ZynAddSubFX/Fantasy/0009-Space Voice2.xiz new file mode 100644 index 000000000..7c83d8fd3 Binary files /dev/null and b/data/presets/ZynAddSubFX/Fantasy/0009-Space Voice2.xiz differ diff --git a/data/presets/ZynAddSubFX/Fantasy/0010-Space Voice3.xiz b/data/presets/ZynAddSubFX/Fantasy/0010-Space Voice3.xiz new file mode 100644 index 000000000..60e79340f Binary files /dev/null and b/data/presets/ZynAddSubFX/Fantasy/0010-Space Voice3.xiz differ diff --git a/data/presets/ZynAddSubFX/Fantasy/0011-Space Choir1.xiz b/data/presets/ZynAddSubFX/Fantasy/0011-Space Choir1.xiz new file mode 100644 index 000000000..1d5bb6b49 Binary files /dev/null and b/data/presets/ZynAddSubFX/Fantasy/0011-Space Choir1.xiz differ diff --git a/data/presets/ZynAddSubFX/Fantasy/0012-Space Choir2.xiz b/data/presets/ZynAddSubFX/Fantasy/0012-Space Choir2.xiz new file mode 100644 index 000000000..06cea9405 Binary files /dev/null and b/data/presets/ZynAddSubFX/Fantasy/0012-Space Choir2.xiz differ diff --git a/data/presets/ZynAddSubFX/Fantasy/0014-Glass Voices.xiz b/data/presets/ZynAddSubFX/Fantasy/0014-Glass Voices.xiz new file mode 100644 index 000000000..cd2f28340 Binary files /dev/null and b/data/presets/ZynAddSubFX/Fantasy/0014-Glass Voices.xiz differ diff --git a/data/presets/ZynAddSubFX/Fantasy/0015-Strange Voice.xiz b/data/presets/ZynAddSubFX/Fantasy/0015-Strange Voice.xiz new file mode 100644 index 000000000..8863577c7 Binary files /dev/null and b/data/presets/ZynAddSubFX/Fantasy/0015-Strange Voice.xiz differ diff --git a/data/presets/ZynAddSubFX/Fantasy/0033-ImpossibleDream1.xiz b/data/presets/ZynAddSubFX/Fantasy/0033-ImpossibleDream1.xiz new file mode 100644 index 000000000..90a4c838f Binary files /dev/null and b/data/presets/ZynAddSubFX/Fantasy/0033-ImpossibleDream1.xiz differ diff --git a/data/presets/ZynAddSubFX/Fantasy/0034-ImpossibleDream2.xiz b/data/presets/ZynAddSubFX/Fantasy/0034-ImpossibleDream2.xiz new file mode 100644 index 000000000..60d320f29 Binary files /dev/null and b/data/presets/ZynAddSubFX/Fantasy/0034-ImpossibleDream2.xiz differ diff --git a/data/presets/ZynAddSubFX/Fantasy/0035-ImpossibleDream3.xiz b/data/presets/ZynAddSubFX/Fantasy/0035-ImpossibleDream3.xiz new file mode 100644 index 000000000..91d2e4fa1 Binary files /dev/null and b/data/presets/ZynAddSubFX/Fantasy/0035-ImpossibleDream3.xiz differ diff --git a/data/presets/ZynAddSubFX/Fantasy/0036-ImpossibleDream4.xiz b/data/presets/ZynAddSubFX/Fantasy/0036-ImpossibleDream4.xiz new file mode 100644 index 000000000..5ceff9263 Binary files /dev/null and b/data/presets/ZynAddSubFX/Fantasy/0036-ImpossibleDream4.xiz differ diff --git a/data/presets/ZynAddSubFX/Fantasy/0037-ImpossibleDream5.xiz b/data/presets/ZynAddSubFX/Fantasy/0037-ImpossibleDream5.xiz new file mode 100644 index 000000000..85baaa75a Binary files /dev/null and b/data/presets/ZynAddSubFX/Fantasy/0037-ImpossibleDream5.xiz differ diff --git a/data/presets/ZynAddSubFX/Fantasy/0040-Delayed Echo.xiz b/data/presets/ZynAddSubFX/Fantasy/0040-Delayed Echo.xiz new file mode 100644 index 000000000..89120de06 Binary files /dev/null and b/data/presets/ZynAddSubFX/Fantasy/0040-Delayed Echo.xiz differ diff --git a/data/presets/ZynAddSubFX/Fantasy/0041-Fade Down Echo.xiz b/data/presets/ZynAddSubFX/Fantasy/0041-Fade Down Echo.xiz new file mode 100644 index 000000000..8e8141a77 Binary files /dev/null and b/data/presets/ZynAddSubFX/Fantasy/0041-Fade Down Echo.xiz differ diff --git a/data/presets/ZynAddSubFX/Fantasy/0042-Rhodes Space1.xiz b/data/presets/ZynAddSubFX/Fantasy/0042-Rhodes Space1.xiz new file mode 100644 index 000000000..fd4073196 Binary files /dev/null and b/data/presets/ZynAddSubFX/Fantasy/0042-Rhodes Space1.xiz differ diff --git a/data/presets/ZynAddSubFX/Fantasy/0043-Rhodes Space2.xiz b/data/presets/ZynAddSubFX/Fantasy/0043-Rhodes Space2.xiz new file mode 100644 index 000000000..33bdd7d46 Binary files /dev/null and b/data/presets/ZynAddSubFX/Fantasy/0043-Rhodes Space2.xiz differ diff --git a/data/presets/ZynAddSubFX/Fantasy/0065-Long SpaceChoir1.xiz b/data/presets/ZynAddSubFX/Fantasy/0065-Long SpaceChoir1.xiz new file mode 100644 index 000000000..c476227ee Binary files /dev/null and b/data/presets/ZynAddSubFX/Fantasy/0065-Long SpaceChoir1.xiz differ diff --git a/data/presets/ZynAddSubFX/Fantasy/0066-Long SpaceChoir2.xiz b/data/presets/ZynAddSubFX/Fantasy/0066-Long SpaceChoir2.xiz new file mode 100644 index 000000000..ac2e0fa40 Binary files /dev/null and b/data/presets/ZynAddSubFX/Fantasy/0066-Long SpaceChoir2.xiz differ diff --git a/data/presets/ZynAddSubFX/Guitar/0001-Dist Guitar 1.xiz b/data/presets/ZynAddSubFX/Guitar/0001-Dist Guitar 1.xiz new file mode 100644 index 000000000..6525b52b6 Binary files /dev/null and b/data/presets/ZynAddSubFX/Guitar/0001-Dist Guitar 1.xiz differ diff --git a/data/presets/ZynAddSubFX/Guitar/0002-Dist Guitar 2.xiz b/data/presets/ZynAddSubFX/Guitar/0002-Dist Guitar 2.xiz new file mode 100644 index 000000000..0df346e15 Binary files /dev/null and b/data/presets/ZynAddSubFX/Guitar/0002-Dist Guitar 2.xiz differ diff --git a/data/presets/ZynAddSubFX/Guitar/0003-Dist Guitar 3.xiz b/data/presets/ZynAddSubFX/Guitar/0003-Dist Guitar 3.xiz new file mode 100644 index 000000000..8c81e442f Binary files /dev/null and b/data/presets/ZynAddSubFX/Guitar/0003-Dist Guitar 3.xiz differ diff --git a/data/presets/ZynAddSubFX/Guitar/0004-Dist Guitar 4.xiz b/data/presets/ZynAddSubFX/Guitar/0004-Dist Guitar 4.xiz new file mode 100644 index 000000000..80f126db6 Binary files /dev/null and b/data/presets/ZynAddSubFX/Guitar/0004-Dist Guitar 4.xiz differ diff --git a/data/presets/ZynAddSubFX/Guitar/0005-Dist Guitar 5.xiz b/data/presets/ZynAddSubFX/Guitar/0005-Dist Guitar 5.xiz new file mode 100644 index 000000000..d33123f89 Binary files /dev/null and b/data/presets/ZynAddSubFX/Guitar/0005-Dist Guitar 5.xiz differ diff --git a/data/presets/ZynAddSubFX/Guitar/0033-Trash Guitar 1.xiz b/data/presets/ZynAddSubFX/Guitar/0033-Trash Guitar 1.xiz new file mode 100644 index 000000000..f63dc3e50 Binary files /dev/null and b/data/presets/ZynAddSubFX/Guitar/0033-Trash Guitar 1.xiz differ diff --git a/data/presets/ZynAddSubFX/Guitar/0034-Trash Guitar 2.xiz b/data/presets/ZynAddSubFX/Guitar/0034-Trash Guitar 2.xiz new file mode 100644 index 000000000..5237e0665 Binary files /dev/null and b/data/presets/ZynAddSubFX/Guitar/0034-Trash Guitar 2.xiz differ diff --git a/data/presets/ZynAddSubFX/Guitar/0035-Short.xiz b/data/presets/ZynAddSubFX/Guitar/0035-Short.xiz new file mode 100644 index 000000000..48570caa7 Binary files /dev/null and b/data/presets/ZynAddSubFX/Guitar/0035-Short.xiz differ diff --git a/data/presets/ZynAddSubFX/Guitar/0065-Clean Guitar1.xiz b/data/presets/ZynAddSubFX/Guitar/0065-Clean Guitar1.xiz new file mode 100644 index 000000000..98f1c2b3f Binary files /dev/null and b/data/presets/ZynAddSubFX/Guitar/0065-Clean Guitar1.xiz differ diff --git a/data/presets/ZynAddSubFX/Misc/0001-Memories.xiz b/data/presets/ZynAddSubFX/Misc/0001-Memories.xiz new file mode 100644 index 000000000..d35109dfa Binary files /dev/null and b/data/presets/ZynAddSubFX/Misc/0001-Memories.xiz differ diff --git a/data/presets/ZynAddSubFX/Misc/0002-Bells 1.xiz b/data/presets/ZynAddSubFX/Misc/0002-Bells 1.xiz new file mode 100644 index 000000000..49a25c0ab Binary files /dev/null and b/data/presets/ZynAddSubFX/Misc/0002-Bells 1.xiz differ diff --git a/data/presets/ZynAddSubFX/Misc/0003-Bells 2.xiz b/data/presets/ZynAddSubFX/Misc/0003-Bells 2.xiz new file mode 100644 index 000000000..448f74fa0 Binary files /dev/null and b/data/presets/ZynAddSubFX/Misc/0003-Bells 2.xiz differ diff --git a/data/presets/ZynAddSubFX/Misc/0004-Bells 3.xiz b/data/presets/ZynAddSubFX/Misc/0004-Bells 3.xiz new file mode 100644 index 000000000..ca788f313 Binary files /dev/null and b/data/presets/ZynAddSubFX/Misc/0004-Bells 3.xiz differ diff --git a/data/presets/ZynAddSubFX/Misc/0006-SuperSaw 1.xiz b/data/presets/ZynAddSubFX/Misc/0006-SuperSaw 1.xiz new file mode 100644 index 000000000..c90f61565 Binary files /dev/null and b/data/presets/ZynAddSubFX/Misc/0006-SuperSaw 1.xiz differ diff --git a/data/presets/ZynAddSubFX/Misc/0007-SuperSaw 2.xiz b/data/presets/ZynAddSubFX/Misc/0007-SuperSaw 2.xiz new file mode 100644 index 000000000..d4a8cc7ec Binary files /dev/null and b/data/presets/ZynAddSubFX/Misc/0007-SuperSaw 2.xiz differ diff --git a/data/presets/ZynAddSubFX/Misc/0008-SuperSaw 3.xiz b/data/presets/ZynAddSubFX/Misc/0008-SuperSaw 3.xiz new file mode 100644 index 000000000..871e711cc Binary files /dev/null and b/data/presets/ZynAddSubFX/Misc/0008-SuperSaw 3.xiz differ diff --git a/data/presets/ZynAddSubFX/Misc/0009-SuperSaw 4.xiz b/data/presets/ZynAddSubFX/Misc/0009-SuperSaw 4.xiz new file mode 100644 index 000000000..117d41d61 Binary files /dev/null and b/data/presets/ZynAddSubFX/Misc/0009-SuperSaw 4.xiz differ diff --git a/data/presets/ZynAddSubFX/Misc/0010-SuperSaw 5.xiz b/data/presets/ZynAddSubFX/Misc/0010-SuperSaw 5.xiz new file mode 100644 index 000000000..ba3202d9a Binary files /dev/null and b/data/presets/ZynAddSubFX/Misc/0010-SuperSaw 5.xiz differ diff --git a/data/presets/ZynAddSubFX/Misc/0033-Trash Synth 1.xiz b/data/presets/ZynAddSubFX/Misc/0033-Trash Synth 1.xiz new file mode 100644 index 000000000..ba3d01b7c Binary files /dev/null and b/data/presets/ZynAddSubFX/Misc/0033-Trash Synth 1.xiz differ diff --git a/data/presets/ZynAddSubFX/Misc/0034-Trash Synth 2.xiz b/data/presets/ZynAddSubFX/Misc/0034-Trash Synth 2.xiz new file mode 100644 index 000000000..b78456bd7 Binary files /dev/null and b/data/presets/ZynAddSubFX/Misc/0034-Trash Synth 2.xiz differ diff --git a/data/presets/ZynAddSubFX/Misc/0035-Trash Synth 3.xiz b/data/presets/ZynAddSubFX/Misc/0035-Trash Synth 3.xiz new file mode 100644 index 000000000..a9f373ea4 Binary files /dev/null and b/data/presets/ZynAddSubFX/Misc/0035-Trash Synth 3.xiz differ diff --git a/data/presets/ZynAddSubFX/Noises/0001-Synth Effect.xiz b/data/presets/ZynAddSubFX/Noises/0001-Synth Effect.xiz new file mode 100644 index 000000000..ac7a2fc03 Binary files /dev/null and b/data/presets/ZynAddSubFX/Noises/0001-Synth Effect.xiz differ diff --git a/data/presets/ZynAddSubFX/Noises/0002-Ioioioioioi.xiz b/data/presets/ZynAddSubFX/Noises/0002-Ioioioioioi.xiz new file mode 100644 index 000000000..0bd7eaebe Binary files /dev/null and b/data/presets/ZynAddSubFX/Noises/0002-Ioioioioioi.xiz differ diff --git a/data/presets/ZynAddSubFX/Noises/0003-Noise1.xiz b/data/presets/ZynAddSubFX/Noises/0003-Noise1.xiz new file mode 100644 index 000000000..b092dbe2b Binary files /dev/null and b/data/presets/ZynAddSubFX/Noises/0003-Noise1.xiz differ diff --git a/data/presets/ZynAddSubFX/Noises/0004-Noise2.xiz b/data/presets/ZynAddSubFX/Noises/0004-Noise2.xiz new file mode 100644 index 000000000..f0c219672 Binary files /dev/null and b/data/presets/ZynAddSubFX/Noises/0004-Noise2.xiz differ diff --git a/data/presets/ZynAddSubFX/Noises/0006-Wind.xiz b/data/presets/ZynAddSubFX/Noises/0006-Wind.xiz new file mode 100644 index 000000000..bb8b03874 Binary files /dev/null and b/data/presets/ZynAddSubFX/Noises/0006-Wind.xiz differ diff --git a/data/presets/ZynAddSubFX/Noises/0033-Metal Sound 1.xiz b/data/presets/ZynAddSubFX/Noises/0033-Metal Sound 1.xiz new file mode 100644 index 000000000..63db7b9cd Binary files /dev/null and b/data/presets/ZynAddSubFX/Noises/0033-Metal Sound 1.xiz differ diff --git a/data/presets/ZynAddSubFX/Noises/0034-Metal Sound 2.xiz b/data/presets/ZynAddSubFX/Noises/0034-Metal Sound 2.xiz new file mode 100644 index 000000000..a092c6624 Binary files /dev/null and b/data/presets/ZynAddSubFX/Noises/0034-Metal Sound 2.xiz differ diff --git a/data/presets/ZynAddSubFX/Noises/0035-Metal Sound 3.xiz b/data/presets/ZynAddSubFX/Noises/0035-Metal Sound 3.xiz new file mode 100644 index 000000000..abdbc3ed7 Binary files /dev/null and b/data/presets/ZynAddSubFX/Noises/0035-Metal Sound 3.xiz differ diff --git a/data/presets/ZynAddSubFX/Noises/0037-Metal Sound 4.xiz b/data/presets/ZynAddSubFX/Noises/0037-Metal Sound 4.xiz new file mode 100644 index 000000000..ff184baf0 Binary files /dev/null and b/data/presets/ZynAddSubFX/Noises/0037-Metal Sound 4.xiz differ diff --git a/data/presets/ZynAddSubFX/Noises/0038-Metal Sound 5.xiz b/data/presets/ZynAddSubFX/Noises/0038-Metal Sound 5.xiz new file mode 100644 index 000000000..8c3dd4880 Binary files /dev/null and b/data/presets/ZynAddSubFX/Noises/0038-Metal Sound 5.xiz differ diff --git a/data/presets/ZynAddSubFX/Noises/0065-Short noise.xiz b/data/presets/ZynAddSubFX/Noises/0065-Short noise.xiz new file mode 100644 index 000000000..b3631800f Binary files /dev/null and b/data/presets/ZynAddSubFX/Noises/0065-Short noise.xiz differ diff --git a/data/presets/ZynAddSubFX/Organ/0001-Organ 1.xiz b/data/presets/ZynAddSubFX/Organ/0001-Organ 1.xiz new file mode 100644 index 000000000..a049d330a Binary files /dev/null and b/data/presets/ZynAddSubFX/Organ/0001-Organ 1.xiz differ diff --git a/data/presets/ZynAddSubFX/Organ/0002-Organ 2.xiz b/data/presets/ZynAddSubFX/Organ/0002-Organ 2.xiz new file mode 100644 index 000000000..1fc08695a Binary files /dev/null and b/data/presets/ZynAddSubFX/Organ/0002-Organ 2.xiz differ diff --git a/data/presets/ZynAddSubFX/Organ/0003-Organ 3.xiz b/data/presets/ZynAddSubFX/Organ/0003-Organ 3.xiz new file mode 100644 index 000000000..38e2ff4ec Binary files /dev/null and b/data/presets/ZynAddSubFX/Organ/0003-Organ 3.xiz differ diff --git a/data/presets/ZynAddSubFX/Organ/0004-Organ 4.xiz b/data/presets/ZynAddSubFX/Organ/0004-Organ 4.xiz new file mode 100644 index 000000000..66372af97 Binary files /dev/null and b/data/presets/ZynAddSubFX/Organ/0004-Organ 4.xiz differ diff --git a/data/presets/ZynAddSubFX/Organ/0005-Organ 5.xiz b/data/presets/ZynAddSubFX/Organ/0005-Organ 5.xiz new file mode 100644 index 000000000..ee4191d80 Binary files /dev/null and b/data/presets/ZynAddSubFX/Organ/0005-Organ 5.xiz differ diff --git a/data/presets/ZynAddSubFX/Organ/0006-Organ 6.xiz b/data/presets/ZynAddSubFX/Organ/0006-Organ 6.xiz new file mode 100644 index 000000000..4613ec444 Binary files /dev/null and b/data/presets/ZynAddSubFX/Organ/0006-Organ 6.xiz differ diff --git a/data/presets/ZynAddSubFX/Organ/0007-Organ 7.xiz b/data/presets/ZynAddSubFX/Organ/0007-Organ 7.xiz new file mode 100644 index 000000000..42e62dc22 Binary files /dev/null and b/data/presets/ZynAddSubFX/Organ/0007-Organ 7.xiz differ diff --git a/data/presets/ZynAddSubFX/Organ/0008-Organ 8.xiz b/data/presets/ZynAddSubFX/Organ/0008-Organ 8.xiz new file mode 100644 index 000000000..77121146b Binary files /dev/null and b/data/presets/ZynAddSubFX/Organ/0008-Organ 8.xiz differ diff --git a/data/presets/ZynAddSubFX/Organ/0009-Organ 9.xiz b/data/presets/ZynAddSubFX/Organ/0009-Organ 9.xiz new file mode 100644 index 000000000..bd980f6ae Binary files /dev/null and b/data/presets/ZynAddSubFX/Organ/0009-Organ 9.xiz differ diff --git a/data/presets/ZynAddSubFX/Organ/0010-Organ 10.xiz b/data/presets/ZynAddSubFX/Organ/0010-Organ 10.xiz new file mode 100644 index 000000000..eb86fde93 Binary files /dev/null and b/data/presets/ZynAddSubFX/Organ/0010-Organ 10.xiz differ diff --git a/data/presets/ZynAddSubFX/Organ/0011-Organ 11.xiz b/data/presets/ZynAddSubFX/Organ/0011-Organ 11.xiz new file mode 100644 index 000000000..c07450e72 Binary files /dev/null and b/data/presets/ZynAddSubFX/Organ/0011-Organ 11.xiz differ diff --git a/data/presets/ZynAddSubFX/Organ/0033-Cathedral Organ1.xiz b/data/presets/ZynAddSubFX/Organ/0033-Cathedral Organ1.xiz new file mode 100644 index 000000000..0b7847260 Binary files /dev/null and b/data/presets/ZynAddSubFX/Organ/0033-Cathedral Organ1.xiz differ diff --git a/data/presets/ZynAddSubFX/Organ/0034-Cathedral Organ2.xiz b/data/presets/ZynAddSubFX/Organ/0034-Cathedral Organ2.xiz new file mode 100644 index 000000000..0de7b5a23 Binary files /dev/null and b/data/presets/ZynAddSubFX/Organ/0034-Cathedral Organ2.xiz differ diff --git a/data/presets/ZynAddSubFX/Organ/0035-Cathedral Organ3.xiz b/data/presets/ZynAddSubFX/Organ/0035-Cathedral Organ3.xiz new file mode 100644 index 000000000..1a61ce26e Binary files /dev/null and b/data/presets/ZynAddSubFX/Organ/0035-Cathedral Organ3.xiz differ diff --git a/data/presets/ZynAddSubFX/Organ/0037-Church Organ 1.xiz b/data/presets/ZynAddSubFX/Organ/0037-Church Organ 1.xiz new file mode 100644 index 000000000..855f6a1e4 Binary files /dev/null and b/data/presets/ZynAddSubFX/Organ/0037-Church Organ 1.xiz differ diff --git a/data/presets/ZynAddSubFX/Organ/0038-Church Organ 2.xiz b/data/presets/ZynAddSubFX/Organ/0038-Church Organ 2.xiz new file mode 100644 index 000000000..0fa0cda52 Binary files /dev/null and b/data/presets/ZynAddSubFX/Organ/0038-Church Organ 2.xiz differ diff --git a/data/presets/ZynAddSubFX/Organ/0039-Church Organ 3.xiz b/data/presets/ZynAddSubFX/Organ/0039-Church Organ 3.xiz new file mode 100644 index 000000000..3f067dd33 Binary files /dev/null and b/data/presets/ZynAddSubFX/Organ/0039-Church Organ 3.xiz differ diff --git a/data/presets/ZynAddSubFX/Organ/0041-Church Organ Soft.xiz b/data/presets/ZynAddSubFX/Organ/0041-Church Organ Soft.xiz new file mode 100644 index 000000000..9c5eeb2bc Binary files /dev/null and b/data/presets/ZynAddSubFX/Organ/0041-Church Organ Soft.xiz differ diff --git a/data/presets/ZynAddSubFX/Organ/0065-Nice Organ 1.xiz b/data/presets/ZynAddSubFX/Organ/0065-Nice Organ 1.xiz new file mode 100644 index 000000000..4715e04b7 Binary files /dev/null and b/data/presets/ZynAddSubFX/Organ/0065-Nice Organ 1.xiz differ diff --git a/data/presets/ZynAddSubFX/Organ/0066-Nice Organ 2.xiz b/data/presets/ZynAddSubFX/Organ/0066-Nice Organ 2.xiz new file mode 100644 index 000000000..f69926d5d Binary files /dev/null and b/data/presets/ZynAddSubFX/Organ/0066-Nice Organ 2.xiz differ diff --git a/data/presets/ZynAddSubFX/Organ/0067-Sub_Organ.xiz b/data/presets/ZynAddSubFX/Organ/0067-Sub_Organ.xiz new file mode 100644 index 000000000..c108ca050 Binary files /dev/null and b/data/presets/ZynAddSubFX/Organ/0067-Sub_Organ.xiz differ diff --git a/data/presets/ZynAddSubFX/Organ/0068-Square Organ.xiz b/data/presets/ZynAddSubFX/Organ/0068-Square Organ.xiz new file mode 100644 index 000000000..68b75e669 Binary files /dev/null and b/data/presets/ZynAddSubFX/Organ/0068-Square Organ.xiz differ diff --git a/data/presets/ZynAddSubFX/Organ/0069-Soft Organ 1.xiz b/data/presets/ZynAddSubFX/Organ/0069-Soft Organ 1.xiz new file mode 100644 index 000000000..6008ac747 Binary files /dev/null and b/data/presets/ZynAddSubFX/Organ/0069-Soft Organ 1.xiz differ diff --git a/data/presets/ZynAddSubFX/Organ/0070-Soft Organ 2.xiz b/data/presets/ZynAddSubFX/Organ/0070-Soft Organ 2.xiz new file mode 100644 index 000000000..9ce98004b Binary files /dev/null and b/data/presets/ZynAddSubFX/Organ/0070-Soft Organ 2.xiz differ diff --git a/data/presets/ZynAddSubFX/Organ/0071-Synth Organ.xiz b/data/presets/ZynAddSubFX/Organ/0071-Synth Organ.xiz new file mode 100644 index 000000000..c70ae4b99 Binary files /dev/null and b/data/presets/ZynAddSubFX/Organ/0071-Synth Organ.xiz differ diff --git a/data/presets/ZynAddSubFX/Organ/0072-Fantasy Organ.xiz b/data/presets/ZynAddSubFX/Organ/0072-Fantasy Organ.xiz new file mode 100644 index 000000000..0a71c909d Binary files /dev/null and b/data/presets/ZynAddSubFX/Organ/0072-Fantasy Organ.xiz differ diff --git a/data/presets/ZynAddSubFX/Organ/0097-Accordion Pad 1.xiz b/data/presets/ZynAddSubFX/Organ/0097-Accordion Pad 1.xiz new file mode 100644 index 000000000..8fed1336f Binary files /dev/null and b/data/presets/ZynAddSubFX/Organ/0097-Accordion Pad 1.xiz differ diff --git a/data/presets/ZynAddSubFX/Organ/0098-Accordion Pad 2.xiz b/data/presets/ZynAddSubFX/Organ/0098-Accordion Pad 2.xiz new file mode 100644 index 000000000..5b09f7b1b Binary files /dev/null and b/data/presets/ZynAddSubFX/Organ/0098-Accordion Pad 2.xiz differ diff --git a/data/presets/ZynAddSubFX/Organ/0099-Synth Accordion1.xiz b/data/presets/ZynAddSubFX/Organ/0099-Synth Accordion1.xiz new file mode 100644 index 000000000..6cc192896 Binary files /dev/null and b/data/presets/ZynAddSubFX/Organ/0099-Synth Accordion1.xiz differ diff --git a/data/presets/ZynAddSubFX/Organ/0100-Synth Accordion2.xiz b/data/presets/ZynAddSubFX/Organ/0100-Synth Accordion2.xiz new file mode 100644 index 000000000..7b9dafad5 Binary files /dev/null and b/data/presets/ZynAddSubFX/Organ/0100-Synth Accordion2.xiz differ diff --git a/data/presets/ZynAddSubFX/Organ/0101-Accordion 1.xiz b/data/presets/ZynAddSubFX/Organ/0101-Accordion 1.xiz new file mode 100644 index 000000000..c963a2eb5 Binary files /dev/null and b/data/presets/ZynAddSubFX/Organ/0101-Accordion 1.xiz differ diff --git a/data/presets/ZynAddSubFX/Pads/0001-Sine Pad.xiz b/data/presets/ZynAddSubFX/Pads/0001-Sine Pad.xiz new file mode 100644 index 000000000..183443187 Binary files /dev/null and b/data/presets/ZynAddSubFX/Pads/0001-Sine Pad.xiz differ diff --git a/data/presets/ZynAddSubFX/Pads/0002-sin2x pad.xiz b/data/presets/ZynAddSubFX/Pads/0002-sin2x pad.xiz new file mode 100644 index 000000000..efa197d72 Binary files /dev/null and b/data/presets/ZynAddSubFX/Pads/0002-sin2x pad.xiz differ diff --git a/data/presets/ZynAddSubFX/Pads/0003-Analog Pad 1.xiz b/data/presets/ZynAddSubFX/Pads/0003-Analog Pad 1.xiz new file mode 100644 index 000000000..fae1c73bd Binary files /dev/null and b/data/presets/ZynAddSubFX/Pads/0003-Analog Pad 1.xiz differ diff --git a/data/presets/ZynAddSubFX/Pads/0004-Analog Pad 2.xiz b/data/presets/ZynAddSubFX/Pads/0004-Analog Pad 2.xiz new file mode 100644 index 000000000..b01fa97f0 Binary files /dev/null and b/data/presets/ZynAddSubFX/Pads/0004-Analog Pad 2.xiz differ diff --git a/data/presets/ZynAddSubFX/Pads/0005-Square Pad 1.xiz b/data/presets/ZynAddSubFX/Pads/0005-Square Pad 1.xiz new file mode 100644 index 000000000..9f3210f7c Binary files /dev/null and b/data/presets/ZynAddSubFX/Pads/0005-Square Pad 1.xiz differ diff --git a/data/presets/ZynAddSubFX/Pads/0006-Square Pad 2.xiz b/data/presets/ZynAddSubFX/Pads/0006-Square Pad 2.xiz new file mode 100644 index 000000000..ac9335503 Binary files /dev/null and b/data/presets/ZynAddSubFX/Pads/0006-Square Pad 2.xiz differ diff --git a/data/presets/ZynAddSubFX/Pads/0008-Resonance Pad1.xiz b/data/presets/ZynAddSubFX/Pads/0008-Resonance Pad1.xiz new file mode 100644 index 000000000..9e8760d12 Binary files /dev/null and b/data/presets/ZynAddSubFX/Pads/0008-Resonance Pad1.xiz differ diff --git a/data/presets/ZynAddSubFX/Pads/0009-Resonance Pad2.xiz b/data/presets/ZynAddSubFX/Pads/0009-Resonance Pad2.xiz new file mode 100644 index 000000000..6e4f696a1 Binary files /dev/null and b/data/presets/ZynAddSubFX/Pads/0009-Resonance Pad2.xiz differ diff --git a/data/presets/ZynAddSubFX/Pads/0033-Synth Pad 1.xiz b/data/presets/ZynAddSubFX/Pads/0033-Synth Pad 1.xiz new file mode 100644 index 000000000..0731979c6 Binary files /dev/null and b/data/presets/ZynAddSubFX/Pads/0033-Synth Pad 1.xiz differ diff --git a/data/presets/ZynAddSubFX/Pads/0034-Synth Pad 2.xiz b/data/presets/ZynAddSubFX/Pads/0034-Synth Pad 2.xiz new file mode 100644 index 000000000..60258b464 Binary files /dev/null and b/data/presets/ZynAddSubFX/Pads/0034-Synth Pad 2.xiz differ diff --git a/data/presets/ZynAddSubFX/Pads/0035-Synth Pad 3.xiz b/data/presets/ZynAddSubFX/Pads/0035-Synth Pad 3.xiz new file mode 100644 index 000000000..3db3b68ce Binary files /dev/null and b/data/presets/ZynAddSubFX/Pads/0035-Synth Pad 3.xiz differ diff --git a/data/presets/ZynAddSubFX/Pads/0036-Synth Pad 4.xiz b/data/presets/ZynAddSubFX/Pads/0036-Synth Pad 4.xiz new file mode 100644 index 000000000..ab1450c03 Binary files /dev/null and b/data/presets/ZynAddSubFX/Pads/0036-Synth Pad 4.xiz differ diff --git a/data/presets/ZynAddSubFX/Pads/0065-Soft Pad.xiz b/data/presets/ZynAddSubFX/Pads/0065-Soft Pad.xiz new file mode 100644 index 000000000..2b36fbe19 Binary files /dev/null and b/data/presets/ZynAddSubFX/Pads/0065-Soft Pad.xiz differ diff --git a/data/presets/ZynAddSubFX/Pads/0066-Flanged Pad 1.xiz b/data/presets/ZynAddSubFX/Pads/0066-Flanged Pad 1.xiz new file mode 100644 index 000000000..e20e317e2 Binary files /dev/null and b/data/presets/ZynAddSubFX/Pads/0066-Flanged Pad 1.xiz differ diff --git a/data/presets/ZynAddSubFX/Plucked/0001-Plucked 1.xiz b/data/presets/ZynAddSubFX/Plucked/0001-Plucked 1.xiz new file mode 100644 index 000000000..437ff874c Binary files /dev/null and b/data/presets/ZynAddSubFX/Plucked/0001-Plucked 1.xiz differ diff --git a/data/presets/ZynAddSubFX/Plucked/0002-Plucked 2.xiz b/data/presets/ZynAddSubFX/Plucked/0002-Plucked 2.xiz new file mode 100644 index 000000000..d0c468b78 Binary files /dev/null and b/data/presets/ZynAddSubFX/Plucked/0002-Plucked 2.xiz differ diff --git a/data/presets/ZynAddSubFX/Plucked/0003-Plucked 3.xiz b/data/presets/ZynAddSubFX/Plucked/0003-Plucked 3.xiz new file mode 100644 index 000000000..fe6367c95 Binary files /dev/null and b/data/presets/ZynAddSubFX/Plucked/0003-Plucked 3.xiz differ diff --git a/data/presets/ZynAddSubFX/Plucked/0004-Plucked 4.xiz b/data/presets/ZynAddSubFX/Plucked/0004-Plucked 4.xiz new file mode 100644 index 000000000..efe4abe44 Binary files /dev/null and b/data/presets/ZynAddSubFX/Plucked/0004-Plucked 4.xiz differ diff --git a/data/presets/ZynAddSubFX/Plucked/0005-Plucked 5.xiz b/data/presets/ZynAddSubFX/Plucked/0005-Plucked 5.xiz new file mode 100644 index 000000000..6d57a4c8b Binary files /dev/null and b/data/presets/ZynAddSubFX/Plucked/0005-Plucked 5.xiz differ diff --git a/data/presets/ZynAddSubFX/Plucked/0006-Plucked 6.xiz b/data/presets/ZynAddSubFX/Plucked/0006-Plucked 6.xiz new file mode 100644 index 000000000..bd3cf9b88 Binary files /dev/null and b/data/presets/ZynAddSubFX/Plucked/0006-Plucked 6.xiz differ diff --git a/data/presets/ZynAddSubFX/Plucked/0033-Plucked String1.xiz b/data/presets/ZynAddSubFX/Plucked/0033-Plucked String1.xiz new file mode 100644 index 000000000..1b996fea0 Binary files /dev/null and b/data/presets/ZynAddSubFX/Plucked/0033-Plucked String1.xiz differ diff --git a/data/presets/ZynAddSubFX/Plucked/0034-Plucked String2.xiz b/data/presets/ZynAddSubFX/Plucked/0034-Plucked String2.xiz new file mode 100644 index 000000000..271e688b7 Binary files /dev/null and b/data/presets/ZynAddSubFX/Plucked/0034-Plucked String2.xiz differ diff --git a/data/presets/ZynAddSubFX/Plucked/0036-Plucked Wah.xiz b/data/presets/ZynAddSubFX/Plucked/0036-Plucked Wah.xiz new file mode 100644 index 000000000..3a651d175 Binary files /dev/null and b/data/presets/ZynAddSubFX/Plucked/0036-Plucked Wah.xiz differ diff --git a/data/presets/ZynAddSubFX/ReedAndWind/0001-Flute 1.xiz b/data/presets/ZynAddSubFX/ReedAndWind/0001-Flute 1.xiz new file mode 100644 index 000000000..6e9569b0a Binary files /dev/null and b/data/presets/ZynAddSubFX/ReedAndWind/0001-Flute 1.xiz differ diff --git a/data/presets/ZynAddSubFX/ReedAndWind/0002-Flute 2.xiz b/data/presets/ZynAddSubFX/ReedAndWind/0002-Flute 2.xiz new file mode 100644 index 000000000..793c4166b Binary files /dev/null and b/data/presets/ZynAddSubFX/ReedAndWind/0002-Flute 2.xiz differ diff --git a/data/presets/ZynAddSubFX/ReedAndWind/0003-Flute 3.xiz b/data/presets/ZynAddSubFX/ReedAndWind/0003-Flute 3.xiz new file mode 100644 index 000000000..c50030214 Binary files /dev/null and b/data/presets/ZynAddSubFX/ReedAndWind/0003-Flute 3.xiz differ diff --git a/data/presets/ZynAddSubFX/ReedAndWind/0005-FM Reed.xiz b/data/presets/ZynAddSubFX/ReedAndWind/0005-FM Reed.xiz new file mode 100644 index 000000000..e538f35ee Binary files /dev/null and b/data/presets/ZynAddSubFX/ReedAndWind/0005-FM Reed.xiz differ diff --git a/data/presets/ZynAddSubFX/ReedAndWind/0006-Clarinet.xiz b/data/presets/ZynAddSubFX/ReedAndWind/0006-Clarinet.xiz new file mode 100644 index 000000000..f321a1c88 Binary files /dev/null and b/data/presets/ZynAddSubFX/ReedAndWind/0006-Clarinet.xiz differ diff --git a/data/presets/ZynAddSubFX/ReedAndWind/0007-Breathy1.xiz b/data/presets/ZynAddSubFX/ReedAndWind/0007-Breathy1.xiz new file mode 100644 index 000000000..ea3c33f22 Binary files /dev/null and b/data/presets/ZynAddSubFX/ReedAndWind/0007-Breathy1.xiz differ diff --git a/data/presets/ZynAddSubFX/ReedAndWind/0033-Reed 1.xiz b/data/presets/ZynAddSubFX/ReedAndWind/0033-Reed 1.xiz new file mode 100644 index 000000000..e6165c464 Binary files /dev/null and b/data/presets/ZynAddSubFX/ReedAndWind/0033-Reed 1.xiz differ diff --git a/data/presets/ZynAddSubFX/ReedAndWind/0034-Reed 2.xiz b/data/presets/ZynAddSubFX/ReedAndWind/0034-Reed 2.xiz new file mode 100644 index 000000000..d2c1c3e5f Binary files /dev/null and b/data/presets/ZynAddSubFX/ReedAndWind/0034-Reed 2.xiz differ diff --git a/data/presets/ZynAddSubFX/ReedAndWind/0035-Reed 3.xiz b/data/presets/ZynAddSubFX/ReedAndWind/0035-Reed 3.xiz new file mode 100644 index 000000000..40ef3ddba Binary files /dev/null and b/data/presets/ZynAddSubFX/ReedAndWind/0035-Reed 3.xiz differ diff --git a/data/presets/ZynAddSubFX/ReedAndWind/0036-Reed 4.xiz b/data/presets/ZynAddSubFX/ReedAndWind/0036-Reed 4.xiz new file mode 100644 index 000000000..34ff460d1 Binary files /dev/null and b/data/presets/ZynAddSubFX/ReedAndWind/0036-Reed 4.xiz differ diff --git a/data/presets/ZynAddSubFX/ReedAndWind/0037-Reed 5.xiz b/data/presets/ZynAddSubFX/ReedAndWind/0037-Reed 5.xiz new file mode 100644 index 000000000..258c570f5 Binary files /dev/null and b/data/presets/ZynAddSubFX/ReedAndWind/0037-Reed 5.xiz differ diff --git a/data/presets/ZynAddSubFX/ReedAndWind/0038-Reed 6.xiz b/data/presets/ZynAddSubFX/ReedAndWind/0038-Reed 6.xiz new file mode 100644 index 000000000..e0e0cbb5a Binary files /dev/null and b/data/presets/ZynAddSubFX/ReedAndWind/0038-Reed 6.xiz differ diff --git a/data/presets/ZynAddSubFX/ReedAndWind/0039-Reed 7.xiz b/data/presets/ZynAddSubFX/ReedAndWind/0039-Reed 7.xiz new file mode 100644 index 000000000..9c8fa4489 Binary files /dev/null and b/data/presets/ZynAddSubFX/ReedAndWind/0039-Reed 7.xiz differ diff --git a/data/presets/ZynAddSubFX/ReedAndWind/0065-Fat Reed1.xiz b/data/presets/ZynAddSubFX/ReedAndWind/0065-Fat Reed1.xiz new file mode 100644 index 000000000..ef1647d8d Binary files /dev/null and b/data/presets/ZynAddSubFX/ReedAndWind/0065-Fat Reed1.xiz differ diff --git a/data/presets/ZynAddSubFX/ReedAndWind/0066-Fat Reed2.xiz b/data/presets/ZynAddSubFX/ReedAndWind/0066-Fat Reed2.xiz new file mode 100644 index 000000000..f850b7518 Binary files /dev/null and b/data/presets/ZynAddSubFX/ReedAndWind/0066-Fat Reed2.xiz differ diff --git a/data/presets/ZynAddSubFX/ReedAndWind/0067-Fat Reed3 square.xiz b/data/presets/ZynAddSubFX/ReedAndWind/0067-Fat Reed3 square.xiz new file mode 100644 index 000000000..1ed39b0c1 Binary files /dev/null and b/data/presets/ZynAddSubFX/ReedAndWind/0067-Fat Reed3 square.xiz differ diff --git a/data/presets/ZynAddSubFX/Rhodes/0001-DX Rhodes 1.xiz b/data/presets/ZynAddSubFX/Rhodes/0001-DX Rhodes 1.xiz new file mode 100644 index 000000000..6cc5a7c72 Binary files /dev/null and b/data/presets/ZynAddSubFX/Rhodes/0001-DX Rhodes 1.xiz differ diff --git a/data/presets/ZynAddSubFX/Rhodes/0002-DX Rhodes 2.xiz b/data/presets/ZynAddSubFX/Rhodes/0002-DX Rhodes 2.xiz new file mode 100644 index 000000000..c75812593 Binary files /dev/null and b/data/presets/ZynAddSubFX/Rhodes/0002-DX Rhodes 2.xiz differ diff --git a/data/presets/ZynAddSubFX/Rhodes/0003-DX Rhodes 3.xiz b/data/presets/ZynAddSubFX/Rhodes/0003-DX Rhodes 3.xiz new file mode 100644 index 000000000..0a6f38f0e Binary files /dev/null and b/data/presets/ZynAddSubFX/Rhodes/0003-DX Rhodes 3.xiz differ diff --git a/data/presets/ZynAddSubFX/Rhodes/0004-DX Rhodes 4.xiz b/data/presets/ZynAddSubFX/Rhodes/0004-DX Rhodes 4.xiz new file mode 100644 index 000000000..c8478096a Binary files /dev/null and b/data/presets/ZynAddSubFX/Rhodes/0004-DX Rhodes 4.xiz differ diff --git a/data/presets/ZynAddSubFX/Rhodes/0005-DX Rhodes 5.xiz b/data/presets/ZynAddSubFX/Rhodes/0005-DX Rhodes 5.xiz new file mode 100644 index 000000000..ef7d15f0c Binary files /dev/null and b/data/presets/ZynAddSubFX/Rhodes/0005-DX Rhodes 5.xiz differ diff --git a/data/presets/ZynAddSubFX/Rhodes/0007-Dig Rhodes.xiz b/data/presets/ZynAddSubFX/Rhodes/0007-Dig Rhodes.xiz new file mode 100644 index 000000000..90b70caa0 Binary files /dev/null and b/data/presets/ZynAddSubFX/Rhodes/0007-Dig Rhodes.xiz differ diff --git a/data/presets/ZynAddSubFX/Rhodes/0008-Synth Rhodes1.xiz b/data/presets/ZynAddSubFX/Rhodes/0008-Synth Rhodes1.xiz new file mode 100644 index 000000000..721a6eac3 Binary files /dev/null and b/data/presets/ZynAddSubFX/Rhodes/0008-Synth Rhodes1.xiz differ diff --git a/data/presets/ZynAddSubFX/Rhodes/0009-Synth Rhodes2.xiz b/data/presets/ZynAddSubFX/Rhodes/0009-Synth Rhodes2.xiz new file mode 100644 index 000000000..478d91e62 Binary files /dev/null and b/data/presets/ZynAddSubFX/Rhodes/0009-Synth Rhodes2.xiz differ diff --git a/data/presets/ZynAddSubFX/Rhodes/0010-Synth Rhodes3.xiz b/data/presets/ZynAddSubFX/Rhodes/0010-Synth Rhodes3.xiz new file mode 100644 index 000000000..d29f90c0d Binary files /dev/null and b/data/presets/ZynAddSubFX/Rhodes/0010-Synth Rhodes3.xiz differ diff --git a/data/presets/ZynAddSubFX/Rhodes/0012-Ice Rhodes1.xiz b/data/presets/ZynAddSubFX/Rhodes/0012-Ice Rhodes1.xiz new file mode 100644 index 000000000..71c4eab9d Binary files /dev/null and b/data/presets/ZynAddSubFX/Rhodes/0012-Ice Rhodes1.xiz differ diff --git a/data/presets/ZynAddSubFX/Rhodes/0013-Ice Rhodes2.xiz b/data/presets/ZynAddSubFX/Rhodes/0013-Ice Rhodes2.xiz new file mode 100644 index 000000000..960257992 Binary files /dev/null and b/data/presets/ZynAddSubFX/Rhodes/0013-Ice Rhodes2.xiz differ diff --git a/data/presets/ZynAddSubFX/Rhodes/0014-Ice Rhodes3.xiz b/data/presets/ZynAddSubFX/Rhodes/0014-Ice Rhodes3.xiz new file mode 100644 index 000000000..c4576d227 Binary files /dev/null and b/data/presets/ZynAddSubFX/Rhodes/0014-Ice Rhodes3.xiz differ diff --git a/data/presets/ZynAddSubFX/Rhodes/0033-FM Rhodes 1.xiz b/data/presets/ZynAddSubFX/Rhodes/0033-FM Rhodes 1.xiz new file mode 100644 index 000000000..cb1b13457 Binary files /dev/null and b/data/presets/ZynAddSubFX/Rhodes/0033-FM Rhodes 1.xiz differ diff --git a/data/presets/ZynAddSubFX/Rhodes/0034-FM Rhodes 2.xiz b/data/presets/ZynAddSubFX/Rhodes/0034-FM Rhodes 2.xiz new file mode 100644 index 000000000..37d914ef8 Binary files /dev/null and b/data/presets/ZynAddSubFX/Rhodes/0034-FM Rhodes 2.xiz differ diff --git a/data/presets/ZynAddSubFX/Rhodes/0035-FM Rhodes 3.xiz b/data/presets/ZynAddSubFX/Rhodes/0035-FM Rhodes 3.xiz new file mode 100644 index 000000000..49f557b83 Binary files /dev/null and b/data/presets/ZynAddSubFX/Rhodes/0035-FM Rhodes 3.xiz differ diff --git a/data/presets/ZynAddSubFX/Rhodes/0036-FM Rhodes 4.xiz b/data/presets/ZynAddSubFX/Rhodes/0036-FM Rhodes 4.xiz new file mode 100644 index 000000000..6b65b53f7 Binary files /dev/null and b/data/presets/ZynAddSubFX/Rhodes/0036-FM Rhodes 4.xiz differ diff --git a/data/presets/ZynAddSubFX/Rhodes/0037-FM Rhodes 5.xiz b/data/presets/ZynAddSubFX/Rhodes/0037-FM Rhodes 5.xiz new file mode 100644 index 000000000..5a53a290e Binary files /dev/null and b/data/presets/ZynAddSubFX/Rhodes/0037-FM Rhodes 5.xiz differ diff --git a/data/presets/ZynAddSubFX/Rhodes/0038-FM Rhodes 6.xiz b/data/presets/ZynAddSubFX/Rhodes/0038-FM Rhodes 6.xiz new file mode 100644 index 000000000..a4603fe68 Binary files /dev/null and b/data/presets/ZynAddSubFX/Rhodes/0038-FM Rhodes 6.xiz differ diff --git a/data/presets/ZynAddSubFX/Rhodes/0041-Soft Rhodes.xiz b/data/presets/ZynAddSubFX/Rhodes/0041-Soft Rhodes.xiz new file mode 100644 index 000000000..4e01a3431 Binary files /dev/null and b/data/presets/ZynAddSubFX/Rhodes/0041-Soft Rhodes.xiz differ diff --git a/data/presets/ZynAddSubFX/Rhodes/0042-Hard Rhodes1.xiz b/data/presets/ZynAddSubFX/Rhodes/0042-Hard Rhodes1.xiz new file mode 100644 index 000000000..eac61cd6c Binary files /dev/null and b/data/presets/ZynAddSubFX/Rhodes/0042-Hard Rhodes1.xiz differ diff --git a/data/presets/ZynAddSubFX/Rhodes/0043-Hard Rhodes2.xiz b/data/presets/ZynAddSubFX/Rhodes/0043-Hard Rhodes2.xiz new file mode 100644 index 000000000..b63449ac5 Binary files /dev/null and b/data/presets/ZynAddSubFX/Rhodes/0043-Hard Rhodes2.xiz differ diff --git a/data/presets/ZynAddSubFX/Rhodes/0044-Echo Rhodes.xiz b/data/presets/ZynAddSubFX/Rhodes/0044-Echo Rhodes.xiz new file mode 100644 index 000000000..45280de55 Binary files /dev/null and b/data/presets/ZynAddSubFX/Rhodes/0044-Echo Rhodes.xiz differ diff --git a/data/presets/ZynAddSubFX/Rhodes/0045-A long time ago.xiz b/data/presets/ZynAddSubFX/Rhodes/0045-A long time ago.xiz new file mode 100644 index 000000000..633ac686b Binary files /dev/null and b/data/presets/ZynAddSubFX/Rhodes/0045-A long time ago.xiz differ diff --git a/data/presets/ZynAddSubFX/Rhodes/0065-Steel Rhodes.xiz b/data/presets/ZynAddSubFX/Rhodes/0065-Steel Rhodes.xiz new file mode 100644 index 000000000..56c119f1f Binary files /dev/null and b/data/presets/ZynAddSubFX/Rhodes/0065-Steel Rhodes.xiz differ diff --git a/data/presets/ZynAddSubFX/Splited/0001-Strings and Reed1.xiz b/data/presets/ZynAddSubFX/Splited/0001-Strings and Reed1.xiz new file mode 100644 index 000000000..82f7d2ea5 Binary files /dev/null and b/data/presets/ZynAddSubFX/Splited/0001-Strings and Reed1.xiz differ diff --git a/data/presets/ZynAddSubFX/Splited/0002-Strings and Reed2.xiz b/data/presets/ZynAddSubFX/Splited/0002-Strings and Reed2.xiz new file mode 100644 index 000000000..24dcd3be6 Binary files /dev/null and b/data/presets/ZynAddSubFX/Splited/0002-Strings and Reed2.xiz differ diff --git a/data/presets/ZynAddSubFX/Splited/0003-Strings and Flute.xiz b/data/presets/ZynAddSubFX/Splited/0003-Strings and Flute.xiz new file mode 100644 index 000000000..82d2b5451 Binary files /dev/null and b/data/presets/ZynAddSubFX/Splited/0003-Strings and Flute.xiz differ diff --git a/data/presets/ZynAddSubFX/Splited/0033-Choir and Reed.xiz b/data/presets/ZynAddSubFX/Splited/0033-Choir and Reed.xiz new file mode 100644 index 000000000..acd226fb3 Binary files /dev/null and b/data/presets/ZynAddSubFX/Splited/0033-Choir and Reed.xiz differ diff --git a/data/presets/ZynAddSubFX/Strings/0001-Saw Strings 1.xiz b/data/presets/ZynAddSubFX/Strings/0001-Saw Strings 1.xiz new file mode 100644 index 000000000..97766327e Binary files /dev/null and b/data/presets/ZynAddSubFX/Strings/0001-Saw Strings 1.xiz differ diff --git a/data/presets/ZynAddSubFX/Strings/0002-Saw Strings 2.xiz b/data/presets/ZynAddSubFX/Strings/0002-Saw Strings 2.xiz new file mode 100644 index 000000000..62d3ddb55 Binary files /dev/null and b/data/presets/ZynAddSubFX/Strings/0002-Saw Strings 2.xiz differ diff --git a/data/presets/ZynAddSubFX/Strings/0003-Saw Strings 3.xiz b/data/presets/ZynAddSubFX/Strings/0003-Saw Strings 3.xiz new file mode 100644 index 000000000..81ed541db Binary files /dev/null and b/data/presets/ZynAddSubFX/Strings/0003-Saw Strings 3.xiz differ diff --git a/data/presets/ZynAddSubFX/Strings/0004-Saw Strings 4.xiz b/data/presets/ZynAddSubFX/Strings/0004-Saw Strings 4.xiz new file mode 100644 index 000000000..a2dc7f376 Binary files /dev/null and b/data/presets/ZynAddSubFX/Strings/0004-Saw Strings 4.xiz differ diff --git a/data/presets/ZynAddSubFX/Strings/0005-Saw Strings 5.xiz b/data/presets/ZynAddSubFX/Strings/0005-Saw Strings 5.xiz new file mode 100644 index 000000000..2a8b94ee3 Binary files /dev/null and b/data/presets/ZynAddSubFX/Strings/0005-Saw Strings 5.xiz differ diff --git a/data/presets/ZynAddSubFX/Strings/0006-Saw Strings 6.xiz b/data/presets/ZynAddSubFX/Strings/0006-Saw Strings 6.xiz new file mode 100644 index 000000000..dcef5c218 Binary files /dev/null and b/data/presets/ZynAddSubFX/Strings/0006-Saw Strings 6.xiz differ diff --git a/data/presets/ZynAddSubFX/Strings/0007-Saw Strings 7.xiz b/data/presets/ZynAddSubFX/Strings/0007-Saw Strings 7.xiz new file mode 100644 index 000000000..dfcc8d89d Binary files /dev/null and b/data/presets/ZynAddSubFX/Strings/0007-Saw Strings 7.xiz differ diff --git a/data/presets/ZynAddSubFX/Strings/0008-Saw Strings 8.xiz b/data/presets/ZynAddSubFX/Strings/0008-Saw Strings 8.xiz new file mode 100644 index 000000000..56d3e2a03 Binary files /dev/null and b/data/presets/ZynAddSubFX/Strings/0008-Saw Strings 8.xiz differ diff --git a/data/presets/ZynAddSubFX/Strings/0011-Strings Pad1.xiz b/data/presets/ZynAddSubFX/Strings/0011-Strings Pad1.xiz new file mode 100644 index 000000000..37b5aa546 Binary files /dev/null and b/data/presets/ZynAddSubFX/Strings/0011-Strings Pad1.xiz differ diff --git a/data/presets/ZynAddSubFX/Strings/0012-Strings Pad2.xiz b/data/presets/ZynAddSubFX/Strings/0012-Strings Pad2.xiz new file mode 100644 index 000000000..fef8a751e Binary files /dev/null and b/data/presets/ZynAddSubFX/Strings/0012-Strings Pad2.xiz differ diff --git a/data/presets/ZynAddSubFX/Strings/0013-Strings Pad3.xiz b/data/presets/ZynAddSubFX/Strings/0013-Strings Pad3.xiz new file mode 100644 index 000000000..1a2d9d091 Binary files /dev/null and b/data/presets/ZynAddSubFX/Strings/0013-Strings Pad3.xiz differ diff --git a/data/presets/ZynAddSubFX/Strings/0016-Sweep Pad 1.xiz b/data/presets/ZynAddSubFX/Strings/0016-Sweep Pad 1.xiz new file mode 100644 index 000000000..1a6eaa642 Binary files /dev/null and b/data/presets/ZynAddSubFX/Strings/0016-Sweep Pad 1.xiz differ diff --git a/data/presets/ZynAddSubFX/Strings/0017-Sweep Pad 1 Fat.xiz b/data/presets/ZynAddSubFX/Strings/0017-Sweep Pad 1 Fat.xiz new file mode 100644 index 000000000..f760886c6 Binary files /dev/null and b/data/presets/ZynAddSubFX/Strings/0017-Sweep Pad 1 Fat.xiz differ diff --git a/data/presets/ZynAddSubFX/Strings/0018-Sweep Pad 2.xiz b/data/presets/ZynAddSubFX/Strings/0018-Sweep Pad 2.xiz new file mode 100644 index 000000000..805e69fff Binary files /dev/null and b/data/presets/ZynAddSubFX/Strings/0018-Sweep Pad 2.xiz differ diff --git a/data/presets/ZynAddSubFX/Strings/0019-Sweep Pad 3Wah.xiz b/data/presets/ZynAddSubFX/Strings/0019-Sweep Pad 3Wah.xiz new file mode 100644 index 000000000..c08b6a740 Binary files /dev/null and b/data/presets/ZynAddSubFX/Strings/0019-Sweep Pad 3Wah.xiz differ diff --git a/data/presets/ZynAddSubFX/Strings/0020-Sweep Pad 4.xiz b/data/presets/ZynAddSubFX/Strings/0020-Sweep Pad 4.xiz new file mode 100644 index 000000000..ec4bd7cfb Binary files /dev/null and b/data/presets/ZynAddSubFX/Strings/0020-Sweep Pad 4.xiz differ diff --git a/data/presets/ZynAddSubFX/Strings/0033-Strings1.xiz b/data/presets/ZynAddSubFX/Strings/0033-Strings1.xiz new file mode 100644 index 000000000..15e4551c6 Binary files /dev/null and b/data/presets/ZynAddSubFX/Strings/0033-Strings1.xiz differ diff --git a/data/presets/ZynAddSubFX/Strings/0034-Dark Strings.xiz b/data/presets/ZynAddSubFX/Strings/0034-Dark Strings.xiz new file mode 100644 index 000000000..b079450a9 Binary files /dev/null and b/data/presets/ZynAddSubFX/Strings/0034-Dark Strings.xiz differ diff --git a/data/presets/ZynAddSubFX/Strings/0035-Octave Pad.xiz b/data/presets/ZynAddSubFX/Strings/0035-Octave Pad.xiz new file mode 100644 index 000000000..9ccf0f98f Binary files /dev/null and b/data/presets/ZynAddSubFX/Strings/0035-Octave Pad.xiz differ diff --git a/data/presets/ZynAddSubFX/Strings/0036-Fast Attack.xiz b/data/presets/ZynAddSubFX/Strings/0036-Fast Attack.xiz new file mode 100644 index 000000000..5fb63dcbb Binary files /dev/null and b/data/presets/ZynAddSubFX/Strings/0036-Fast Attack.xiz differ diff --git a/data/presets/ZynAddSubFX/Strings/0038-Fat Saw.xiz b/data/presets/ZynAddSubFX/Strings/0038-Fat Saw.xiz new file mode 100644 index 000000000..562f5bd20 Binary files /dev/null and b/data/presets/ZynAddSubFX/Strings/0038-Fat Saw.xiz differ diff --git a/data/presets/ZynAddSubFX/Strings/0041-Saw 1.xiz b/data/presets/ZynAddSubFX/Strings/0041-Saw 1.xiz new file mode 100644 index 000000000..d45a3c20f Binary files /dev/null and b/data/presets/ZynAddSubFX/Strings/0041-Saw 1.xiz differ diff --git a/data/presets/ZynAddSubFX/Strings/0042-Saw 2.xiz b/data/presets/ZynAddSubFX/Strings/0042-Saw 2.xiz new file mode 100644 index 000000000..0ab80ea28 Binary files /dev/null and b/data/presets/ZynAddSubFX/Strings/0042-Saw 2.xiz differ diff --git a/data/presets/ZynAddSubFX/Strings/0043-Saw 3.xiz b/data/presets/ZynAddSubFX/Strings/0043-Saw 3.xiz new file mode 100644 index 000000000..b0e06b27f Binary files /dev/null and b/data/presets/ZynAddSubFX/Strings/0043-Saw 3.xiz differ diff --git a/data/presets/ZynAddSubFX/Strings/0044-Saw Pad.xiz b/data/presets/ZynAddSubFX/Strings/0044-Saw Pad.xiz new file mode 100644 index 000000000..6974b651c Binary files /dev/null and b/data/presets/ZynAddSubFX/Strings/0044-Saw Pad.xiz differ diff --git a/data/presets/ZynAddSubFX/Strings/0045-Soft Saw Pad.xiz b/data/presets/ZynAddSubFX/Strings/0045-Soft Saw Pad.xiz new file mode 100644 index 000000000..45e85d263 Binary files /dev/null and b/data/presets/ZynAddSubFX/Strings/0045-Soft Saw Pad.xiz differ diff --git a/data/presets/ZynAddSubFX/Strings/0046-Echoed Saw.xiz b/data/presets/ZynAddSubFX/Strings/0046-Echoed Saw.xiz new file mode 100644 index 000000000..991d6ca65 Binary files /dev/null and b/data/presets/ZynAddSubFX/Strings/0046-Echoed Saw.xiz differ diff --git a/data/presets/ZynAddSubFX/Strings/0047-Vibratto Saw1.xiz b/data/presets/ZynAddSubFX/Strings/0047-Vibratto Saw1.xiz new file mode 100644 index 000000000..cf62f6d97 Binary files /dev/null and b/data/presets/ZynAddSubFX/Strings/0047-Vibratto Saw1.xiz differ diff --git a/data/presets/ZynAddSubFX/Strings/0048-Wah1.xiz b/data/presets/ZynAddSubFX/Strings/0048-Wah1.xiz new file mode 100644 index 000000000..c26c7702c Binary files /dev/null and b/data/presets/ZynAddSubFX/Strings/0048-Wah1.xiz differ diff --git a/data/presets/ZynAddSubFX/Strings/0050-Synth Violin 1.xiz b/data/presets/ZynAddSubFX/Strings/0050-Synth Violin 1.xiz new file mode 100644 index 000000000..b9c79b6fb Binary files /dev/null and b/data/presets/ZynAddSubFX/Strings/0050-Synth Violin 1.xiz differ diff --git a/data/presets/ZynAddSubFX/Strings/0051-Synth Violin 2 Fat.xiz b/data/presets/ZynAddSubFX/Strings/0051-Synth Violin 2 Fat.xiz new file mode 100644 index 000000000..154182c28 Binary files /dev/null and b/data/presets/ZynAddSubFX/Strings/0051-Synth Violin 2 Fat.xiz differ diff --git a/data/presets/ZynAddSubFX/Strings/0065-Simple Strings.xiz b/data/presets/ZynAddSubFX/Strings/0065-Simple Strings.xiz new file mode 100644 index 000000000..32381895e Binary files /dev/null and b/data/presets/ZynAddSubFX/Strings/0065-Simple Strings.xiz differ diff --git a/data/presets/ZynAddSubFX/Strings/0066-Dual Strings.xiz b/data/presets/ZynAddSubFX/Strings/0066-Dual Strings.xiz new file mode 100644 index 000000000..4e236ba94 Binary files /dev/null and b/data/presets/ZynAddSubFX/Strings/0066-Dual Strings.xiz differ diff --git a/data/presets/ZynAddSubFX/Strings/0067-Dual StringsOct.xiz b/data/presets/ZynAddSubFX/Strings/0067-Dual StringsOct.xiz new file mode 100644 index 000000000..e36b55776 Binary files /dev/null and b/data/presets/ZynAddSubFX/Strings/0067-Dual StringsOct.xiz differ diff --git a/data/presets/ZynAddSubFX/Synth/0001-Soft Synth 1.xiz b/data/presets/ZynAddSubFX/Synth/0001-Soft Synth 1.xiz new file mode 100644 index 000000000..7aa87d1f3 Binary files /dev/null and b/data/presets/ZynAddSubFX/Synth/0001-Soft Synth 1.xiz differ diff --git a/data/presets/ZynAddSubFX/Synth/0002-Soft Synth 2.xiz b/data/presets/ZynAddSubFX/Synth/0002-Soft Synth 2.xiz new file mode 100644 index 000000000..8f88ad5eb Binary files /dev/null and b/data/presets/ZynAddSubFX/Synth/0002-Soft Synth 2.xiz differ diff --git a/data/presets/ZynAddSubFX/Synth/0004-Pulse Pad 1.xiz b/data/presets/ZynAddSubFX/Synth/0004-Pulse Pad 1.xiz new file mode 100644 index 000000000..cdc504d57 Binary files /dev/null and b/data/presets/ZynAddSubFX/Synth/0004-Pulse Pad 1.xiz differ diff --git a/data/presets/ZynAddSubFX/Synth/0005-Pulse Pad 2.xiz b/data/presets/ZynAddSubFX/Synth/0005-Pulse Pad 2.xiz new file mode 100644 index 000000000..ebb8206e3 Binary files /dev/null and b/data/presets/ZynAddSubFX/Synth/0005-Pulse Pad 2.xiz differ diff --git a/data/presets/ZynAddSubFX/Synth/0007-Analog Filter 1.xiz b/data/presets/ZynAddSubFX/Synth/0007-Analog Filter 1.xiz new file mode 100644 index 000000000..aefd1eccb Binary files /dev/null and b/data/presets/ZynAddSubFX/Synth/0007-Analog Filter 1.xiz differ diff --git a/data/presets/ZynAddSubFX/Synth/0008-Analog Filter 2.xiz b/data/presets/ZynAddSubFX/Synth/0008-Analog Filter 2.xiz new file mode 100644 index 000000000..8d749f9b9 Binary files /dev/null and b/data/presets/ZynAddSubFX/Synth/0008-Analog Filter 2.xiz differ diff --git a/data/presets/ZynAddSubFX/Synth/0033-Phased Pad 1.xiz b/data/presets/ZynAddSubFX/Synth/0033-Phased Pad 1.xiz new file mode 100644 index 000000000..fa856b64d Binary files /dev/null and b/data/presets/ZynAddSubFX/Synth/0033-Phased Pad 1.xiz differ diff --git a/data/presets/ZynAddSubFX/Synth/0034-Phased Pad 2.xiz b/data/presets/ZynAddSubFX/Synth/0034-Phased Pad 2.xiz new file mode 100644 index 000000000..fa9b2275b Binary files /dev/null and b/data/presets/ZynAddSubFX/Synth/0034-Phased Pad 2.xiz differ diff --git a/data/presets/ZynAddSubFX/Synth/0035-Phased Pad 3.xiz b/data/presets/ZynAddSubFX/Synth/0035-Phased Pad 3.xiz new file mode 100644 index 000000000..6efd18e11 Binary files /dev/null and b/data/presets/ZynAddSubFX/Synth/0035-Phased Pad 3.xiz differ diff --git a/data/presets/ZynAddSubFX/Synth/0037-Resonance Synth.xiz b/data/presets/ZynAddSubFX/Synth/0037-Resonance Synth.xiz new file mode 100644 index 000000000..619588209 Binary files /dev/null and b/data/presets/ZynAddSubFX/Synth/0037-Resonance Synth.xiz differ diff --git a/data/presets/ZynAddSubFX/Synth/0039-Multi-phase synth.xiz b/data/presets/ZynAddSubFX/Synth/0039-Multi-phase synth.xiz new file mode 100644 index 000000000..5943e843f Binary files /dev/null and b/data/presets/ZynAddSubFX/Synth/0039-Multi-phase synth.xiz differ diff --git a/data/presets/ZynAddSubFX/Synth/0065-Computer Lead.xiz b/data/presets/ZynAddSubFX/Synth/0065-Computer Lead.xiz new file mode 100644 index 000000000..d11e7bf40 Binary files /dev/null and b/data/presets/ZynAddSubFX/Synth/0065-Computer Lead.xiz differ diff --git a/data/presets/ZynAddSubFX/Synth/0067-Detuned Harmonic.xiz b/data/presets/ZynAddSubFX/Synth/0067-Detuned Harmonic.xiz new file mode 100644 index 000000000..5cf9725d2 Binary files /dev/null and b/data/presets/ZynAddSubFX/Synth/0067-Detuned Harmonic.xiz differ diff --git a/data/presets/ZynAddSubFX/Synth/0097-FM Synth.xiz b/data/presets/ZynAddSubFX/Synth/0097-FM Synth.xiz new file mode 100644 index 000000000..7219c5e61 Binary files /dev/null and b/data/presets/ZynAddSubFX/Synth/0097-FM Synth.xiz differ diff --git a/data/presets/ZynAddSubFX/SynthPiano/0001-Soft Piano 1.xiz b/data/presets/ZynAddSubFX/SynthPiano/0001-Soft Piano 1.xiz new file mode 100644 index 000000000..f44c7434c Binary files /dev/null and b/data/presets/ZynAddSubFX/SynthPiano/0001-Soft Piano 1.xiz differ diff --git a/data/presets/ZynAddSubFX/SynthPiano/0002-Soft Piano 2.xiz b/data/presets/ZynAddSubFX/SynthPiano/0002-Soft Piano 2.xiz new file mode 100644 index 000000000..9ffd7ffbf Binary files /dev/null and b/data/presets/ZynAddSubFX/SynthPiano/0002-Soft Piano 2.xiz differ diff --git a/data/presets/ZynAddSubFX/SynthPiano/0004-Fantasy Bell.xiz b/data/presets/ZynAddSubFX/SynthPiano/0004-Fantasy Bell.xiz new file mode 100644 index 000000000..0f7e50749 Binary files /dev/null and b/data/presets/ZynAddSubFX/SynthPiano/0004-Fantasy Bell.xiz differ diff --git a/data/presets/ZynAddSubFX/SynthPiano/0005-Synth Piano1.xiz b/data/presets/ZynAddSubFX/SynthPiano/0005-Synth Piano1.xiz new file mode 100644 index 000000000..9452b7ced Binary files /dev/null and b/data/presets/ZynAddSubFX/SynthPiano/0005-Synth Piano1.xiz differ diff --git a/data/presets/ZynAddSubFX/SynthPiano/0006-Synth Piano2.xiz b/data/presets/ZynAddSubFX/SynthPiano/0006-Synth Piano2.xiz new file mode 100644 index 000000000..b1f6c5b21 Binary files /dev/null and b/data/presets/ZynAddSubFX/SynthPiano/0006-Synth Piano2.xiz differ diff --git a/data/presets/ZynAddSubFX/SynthPiano/0007-Termollo1.xiz b/data/presets/ZynAddSubFX/SynthPiano/0007-Termollo1.xiz new file mode 100644 index 000000000..52e94905b Binary files /dev/null and b/data/presets/ZynAddSubFX/SynthPiano/0007-Termollo1.xiz differ diff --git a/data/presets/ZynAddSubFX/SynthPiano/0008-Termollo2.xiz b/data/presets/ZynAddSubFX/SynthPiano/0008-Termollo2.xiz new file mode 100644 index 000000000..aac661bd5 Binary files /dev/null and b/data/presets/ZynAddSubFX/SynthPiano/0008-Termollo2.xiz differ diff --git a/data/presets/ZynAddSubFX/SynthPiano/0009-Termollo3.xiz b/data/presets/ZynAddSubFX/SynthPiano/0009-Termollo3.xiz new file mode 100644 index 000000000..324f3a591 Binary files /dev/null and b/data/presets/ZynAddSubFX/SynthPiano/0009-Termollo3.xiz differ diff --git a/data/presets/ZynAddSubFX/SynthPiano/0011-Drop1.xiz b/data/presets/ZynAddSubFX/SynthPiano/0011-Drop1.xiz new file mode 100644 index 000000000..162cd9821 Binary files /dev/null and b/data/presets/ZynAddSubFX/SynthPiano/0011-Drop1.xiz differ diff --git a/data/presets/ZynAddSubFX/SynthPiano/0012-Drop2.xiz b/data/presets/ZynAddSubFX/SynthPiano/0012-Drop2.xiz new file mode 100644 index 000000000..cb6e49ed5 Binary files /dev/null and b/data/presets/ZynAddSubFX/SynthPiano/0012-Drop2.xiz differ diff --git a/data/presets/ZynAddSubFX/SynthPiano/0033-Analog Piano 1.xiz b/data/presets/ZynAddSubFX/SynthPiano/0033-Analog Piano 1.xiz new file mode 100644 index 000000000..0c405d97e Binary files /dev/null and b/data/presets/ZynAddSubFX/SynthPiano/0033-Analog Piano 1.xiz differ diff --git a/data/presets/ZynAddSubFX/SynthPiano/0034-Analog Piano 2.xiz b/data/presets/ZynAddSubFX/SynthPiano/0034-Analog Piano 2.xiz new file mode 100644 index 000000000..a950a9839 Binary files /dev/null and b/data/presets/ZynAddSubFX/SynthPiano/0034-Analog Piano 2.xiz differ diff --git a/data/presets/ZynAddSubFX/SynthPiano/0035-Analog Piano 3.xiz b/data/presets/ZynAddSubFX/SynthPiano/0035-Analog Piano 3.xiz new file mode 100644 index 000000000..71e86b495 Binary files /dev/null and b/data/presets/ZynAddSubFX/SynthPiano/0035-Analog Piano 3.xiz differ diff --git a/data/presets/ZynAddSubFX/SynthPiano/0037-FM Synth1.xiz b/data/presets/ZynAddSubFX/SynthPiano/0037-FM Synth1.xiz new file mode 100644 index 000000000..07f658906 Binary files /dev/null and b/data/presets/ZynAddSubFX/SynthPiano/0037-FM Synth1.xiz differ diff --git a/data/presets/ZynAddSubFX/SynthPiano/0039-BinaryPiano1.xiz b/data/presets/ZynAddSubFX/SynthPiano/0039-BinaryPiano1.xiz new file mode 100644 index 000000000..2430d6a46 Binary files /dev/null and b/data/presets/ZynAddSubFX/SynthPiano/0039-BinaryPiano1.xiz differ diff --git a/data/presets/ZynAddSubFX/SynthPiano/0040-BinaryPiano2.xiz b/data/presets/ZynAddSubFX/SynthPiano/0040-BinaryPiano2.xiz new file mode 100644 index 000000000..82d24d02e Binary files /dev/null and b/data/presets/ZynAddSubFX/SynthPiano/0040-BinaryPiano2.xiz differ diff --git a/data/presets/ZynAddSubFX/SynthPiano/0065-Synth Piano 1.xiz b/data/presets/ZynAddSubFX/SynthPiano/0065-Synth Piano 1.xiz new file mode 100644 index 000000000..9d03fecd9 Binary files /dev/null and b/data/presets/ZynAddSubFX/SynthPiano/0065-Synth Piano 1.xiz differ diff --git a/data/presets/ZynAddSubFX/SynthPiano/0066-Synth Piano 2.xiz b/data/presets/ZynAddSubFX/SynthPiano/0066-Synth Piano 2.xiz new file mode 100644 index 000000000..e85a5ea2f Binary files /dev/null and b/data/presets/ZynAddSubFX/SynthPiano/0066-Synth Piano 2.xiz differ diff --git a/data/presets/ZynAddSubFX/SynthPiano/0067-Synth Piano 3.xiz b/data/presets/ZynAddSubFX/SynthPiano/0067-Synth Piano 3.xiz new file mode 100644 index 000000000..0ddad8b9a Binary files /dev/null and b/data/presets/ZynAddSubFX/SynthPiano/0067-Synth Piano 3.xiz differ diff --git a/data/presets/ZynAddSubFX/SynthPiano/0068-Synth Piano 3 fat.xiz b/data/presets/ZynAddSubFX/SynthPiano/0068-Synth Piano 3 fat.xiz new file mode 100644 index 000000000..b72e4f63a Binary files /dev/null and b/data/presets/ZynAddSubFX/SynthPiano/0068-Synth Piano 3 fat.xiz differ diff --git a/data/presets/ZynAddSubFX/SynthPiano/0069-Synth Piano 3 det.xiz b/data/presets/ZynAddSubFX/SynthPiano/0069-Synth Piano 3 det.xiz new file mode 100644 index 000000000..7f7d321fa Binary files /dev/null and b/data/presets/ZynAddSubFX/SynthPiano/0069-Synth Piano 3 det.xiz differ diff --git a/data/presets/ZynAddSubFX/SynthPiano/0070-Synth Piano 4.xiz b/data/presets/ZynAddSubFX/SynthPiano/0070-Synth Piano 4.xiz new file mode 100644 index 000000000..4c8f77171 Binary files /dev/null and b/data/presets/ZynAddSubFX/SynthPiano/0070-Synth Piano 4.xiz differ diff --git a/data/presets/ZynAddSubFX/SynthPiano/0071-Synth Piano 5.xiz b/data/presets/ZynAddSubFX/SynthPiano/0071-Synth Piano 5.xiz new file mode 100644 index 000000000..ec60fb935 Binary files /dev/null and b/data/presets/ZynAddSubFX/SynthPiano/0071-Synth Piano 5.xiz differ diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 11f038c24..132524acf 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -23,3 +23,4 @@ ADD_SUBDIRECTORY(vestige) ADD_SUBDIRECTORY(vst_base) ADD_SUBDIRECTORY(vst_effect) ADD_SUBDIRECTORY(vibed) +ADD_SUBDIRECTORY(zynaddsubfx) diff --git a/plugins/zynaddsubfx/CMakeLists.txt b/plugins/zynaddsubfx/CMakeLists.txt new file mode 100644 index 000000000..88cb8a082 --- /dev/null +++ b/plugins/zynaddsubfx/CMakeLists.txt @@ -0,0 +1,138 @@ +IF(LMMS_HAVE_FFTW3F) + +INCLUDE(BuildPlugin) + +BUILD_PLUGIN(zynaddsubfx zynaddsubfx.cpp zynaddsubfx.h MOCFILES zynaddsubfx.h EMBEDDED_RESOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.png) + +SET(ZYN_SRC + ${CMAKE_CURRENT_SOURCE_DIR}/src/DSP/AnalogFilter.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/DSP/Filter.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/DSP/SVFilter.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/DSP/FFTwrapper.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/DSP/FormantFilter.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Input/NULLMidiIn.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Input/MidiIn.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Output/Recorder.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Output/WAVaudiooutput.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Effects/EffectMgr.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Effects/Effect.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Effects/Phaser.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Effects/Echo.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Effects/EffectLFO.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Effects/Chorus.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Effects/DynamicFilter.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Effects/Reverb.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Effects/EQ.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Effects/Distorsion.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Effects/Alienwah.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Params/LFOParams.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Params/EnvelopeParams.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Params/SUBnoteParameters.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Params/ADnoteParameters.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Params/Presets.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Params/FilterParams.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Params/PADnoteParameters.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Params/Controller.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Params/PresetsStore.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Seq/MIDIFile.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Seq/MIDIEvents.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Seq/Sequencer.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Synth/PADnote.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Synth/SUBnote.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Synth/LFO.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Synth/Resonance.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Synth/ADnote.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Synth/Envelope.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Synth/OscilGen.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Misc/Dump.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Misc/Bank.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Misc/Config.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Misc/XMLwrapper.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Misc/Util.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Misc/Master.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Misc/Microtonal.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/Misc/Part.C + ${CMAKE_CURRENT_SOURCE_DIR}/src/UI/MasterUI.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/UI/VirKeyboard.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/UI/ConfigUI.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/UI/OscilGenUI.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/UI/WidgetPDial.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/UI/ResonanceUI.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/UI/MicrotonalUI.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/UI/ADnoteUI.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/UI/PresetsUI.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/UI/EffUI.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/UI/FilterUI.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/UI/PartUI.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/UI/EnvelopeUI.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/UI/LFOUI.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/UI/SeqUI.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/UI/PADnoteUI.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/UI/SUBnoteUI.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/UI/BankUI.cc +) + +SET(MXML_SRC + ${CMAKE_CURRENT_SOURCE_DIR}/mxml/mxml-attr.c + ${CMAKE_CURRENT_SOURCE_DIR}/mxml/mxml-entity.c + ${CMAKE_CURRENT_SOURCE_DIR}/mxml/mxml-file.c + ${CMAKE_CURRENT_SOURCE_DIR}/mxml/mxml-index.c + ${CMAKE_CURRENT_SOURCE_DIR}/mxml/mxml-node.c + ${CMAKE_CURRENT_SOURCE_DIR}/mxml/mxml-private.c + ${CMAKE_CURRENT_SOURCE_DIR}/mxml/mxml-search.c + ${CMAKE_CURRENT_SOURCE_DIR}/mxml/mxml-set.c + ${CMAKE_CURRENT_SOURCE_DIR}/mxml/mxml-string.c +) + + +# definitions for ZynAddSubFX +IF(LMMS_BUILD_LINUX OR LMMS_BUILD_APPLE) +ADD_DEFINITIONS(-DOS_LINUX) +ELSE(LMMS_BUILD_LINUX OR LMMS_BUILD_APPLE) +ADD_DEFINITIONS(-DOS_WINDOWS) +ENDIF(LMMS_BUILD_LINUX OR LMMS_BUILD_APPLE) + +# use asm optimizations when on x86 or x86_64 +IF(LMMS_HOST_X86 OR LMMS_HOST_X86_64) +ADD_DEFINITIONS(-DASM_F2I_YES) +ENDIF(LMMS_HOST_X86 OR LMMS_HOST_X86_64) + +# build ZynAddSubFX with full optimizations +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -Wno-write-strings -Wno-deprecated-declarations") + +# link default libraries +LINK_LIBRARIES(${FFTW3F_LIBRARIES} -lz -lpthread ${CMAKE_CURRENT_BINARY_DIR}/fltk/bin/libfltk.a) + +# FLTK needs X +IF(LMMS_BUILD_LINUX) +FIND_PACKAGE(X11) +FIND_PACKAGE(Freetype) +LINK_LIBRARIES(${X11_LIBRARIES} ${X11_Xft_LIB} ${FREETYPE_LIBRARY}) +ENDIF(LMMS_BUILD_LINUX) + +# link system-libraries when on win32 +IF(LMMS_BUILD_WIN32) +ADD_DEFINITIONS(-DPTW32_STATIC_LIB) +LINK_LIBRARIES(${QT_LIBRARIES} -lole32 -luuid -lcomctl32 -lgdi32) +ENDIF(LMMS_BUILD_WIN32) + +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/fltk/ ${CMAKE_CURRENT_SOURCE_DIR}) + +ADD_EXECUTABLE(remote_zynaddsubfx remote_zynaddsubfx.cpp ${ZYN_SRC} ${MXML_SRC}) +INSTALL(TARGETS remote_zynaddsubfx RUNTIME DESTINATION ${PLUGIN_DIR}) + +IF(LMMS_BUILD_WIN32) + ADD_CUSTOM_COMMAND(TARGET remote_zynaddsubfx POST_BUILD COMMAND ${STRIP} ${CMAKE_CURRENT_BINARY_DIR}/remote_zynaddsubfx.exe) +ENDIF(LMMS_BUILD_WIN32) + +# build FLTK +IF(LMMS_BUILD_WIN64) +SET(FLTK_EXTRA_FLAGS "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_SOURCE_DIR}/cmake/modules/Win64Toolchain.cmake") +ELSEIF(LMMS_BUILD_WIN32) +SET(FLTK_EXTRA_FLAGS "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_SOURCE_DIR}/cmake/modules/Win32Toolchain.cmake") +ENDIF(LMMS_BUILD_WIN64) +ADD_CUSTOM_TARGET(libfltk COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/fltk && cd ${CMAKE_CURRENT_BINARY_DIR}/fltk && ${CMAKE_COMMAND} ${CMAKE_CURRENT_SOURCE_DIR}/fltk ${FLTK_EXTRA_FLAGS} -DFLTK_USE_SYSTEM_ZLIB:BOOL=ON -DFLTK_USE_SYSTEM_JPEG:BOOL=ON -DFLTK_USE_SYSTEM_PNG:BOOL=ON -DUSE_OPENGL:BOOL=OFF -DBUILD_TESTING:BOOL=OFF -DCMAKE_BUILD_TYPE=release && ${CMAKE_BUILD_TOOL}) + +ADD_DEPENDENCIES(remote_zynaddsubfx libfltk) +ENDIF(LMMS_HAVE_FFTW3F) + diff --git a/plugins/zynaddsubfx/artwork.png b/plugins/zynaddsubfx/artwork.png new file mode 100644 index 000000000..d661fc62f Binary files /dev/null and b/plugins/zynaddsubfx/artwork.png differ diff --git a/plugins/zynaddsubfx/fltk/CHANGES b/plugins/zynaddsubfx/fltk/CHANGES new file mode 100644 index 000000000..08c0407a2 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/CHANGES @@ -0,0 +1,3397 @@ +CHANGES IN FLTK 1.1.9 + + - Improved color contrast in secondary selection blocks + of Fl_Text_Display (STR #1917) + - Fixed regression in callback handling (STR #1918) + - Fixed wrong relative path when absolute path has a + trailing slash in fl_filename_relative (STR #1920) + - Fixed multiple selction of files and directories in + Fl_File_Chooser (STR #1913) + - Fixed MSWindows crash when selecting umlauts + in Fl_Help_View (STR #1912) + +CHANGES IN FLTK 1.1.8 + + - Documentation fixes (STR #1454, STR #1455, STR #1456, + STR #1457, STR #1458, STR #1460, STR #1481, STR #1578, + STR #1639, STR #1645, STR #1644, STR #1792, STR #1793, + STR #1742, STR #1777, STR #1794, STR #1827, STR #1843, + STR #1796, STR #1815, STR #1726, STR #1753, STR #1855, + STR #1862, STR #1867, STR #1874, STR #1888) + - Fixed library path in Makefile (STR #1885) + - Fixed image read for partial regions on X11 + (STR #1716) + - Fixed KDE/Gnome icon paths (STR #1795) + - Fixed Tab key to wrap around menu bars (STR #1877) + - Fixed possible timer leak in Scrollbar (STR #1880) + - Added documentation about the potential limitations + of Fl::grab on newer operating systems (STR #1747) + - Fixed lockout when mixing popups and alerts + (STR # 1869) + - Fixed recursion crash in event handling (STR #1873) + - Fixed missing return code in 'fltk-config' (STR #1875) + - Fixed inconsistencies with CHANGED flags (STR #1719) + - Fixed message sent to hidden widgets (STR #1849) + - Fixed width calculation in Fl_Help_View (STR #1868) + - Fixed offset bug in OS X pixmap code (STR #1856) + - Fixed potential buffer overrun + in Fl_Preferences (STR #1853) + - Fixed method attributes in consecutive class + declarations in FLUID (STR #1741) + - FLUID checks for seperately declared callbacks to + avoid a bogus "extern" declaration (STR #1776) + - Added "protected" class memebrs in FLUID + - Double-clicking a widget in a FLUID layout will show + the item in the widget browser + - Fixed color highlighting in Text_Display + - Fixed 16 bit PNM image support (STR #1847) + - Fixed exposure event on zero size windows (STR #1824) + - Fixed overlay offset for OS X Quartz (STR #1729) + - gl_font() support for Xft+X11 (STR #1809) + - Fl_Gl_Window::mode() needed to hide and show the window + when toggling stereo mode (STR #1846) + - Fl_Gl_Window::show() did not work reliably on Mac OS X + (STR #1707) + - Added Fl_Group::clip_children() methods to support + automatic clipping of child widget drawing (STR #1844) + - Fl_Browser_ and friends now support FL_WHEN_ENTER_KEY + for both Enter/Return and double-clicks (STR #1818) + - Fl_Help_View did not release the images it used (STR + #1817) + - Shared libraries would not build on 64-bit Linux + systems with an existing non-PIC FLTK installation + (STR #1791) + - Fl_Browser::hide() and Fl_Browser::show() did not + correctly update the scrollbar (STR #1724) + - The configure script now shows a summry of the + configuration results (STR #1810) + - "fltk-config --use-* --libs" did not list all of the + dependent libraries (STR #1799) + - Hiding a nested window on WIN32 caused 100% CPU (STR #1748) + - Changing the window size in FLUID would not mark the + project as modified (STR #1751) + - Fixed fl_filename_isdir for "/"-path (STR #1761) + - Fixed Fl_Chart drawing (STR #1756) + - Fixed mapping of subwindows with unmapped parent + windows (STR #1706) + - Fixed rendering of grayscale images with alpha + channel (STR #1703) + - Fixed occasional incomplete refresh (STR #1681) + - Improved fl_down, fl_frame, added fl_box (STR #1678) + - Fixed selection of submenu items in + input_choice (STR #1676) + - Fixed calculation of stride for image scaling and + color manipulation (STR #1673) + - Made -O3 the default optimization on Cygwin/Mingw since + -Os currently creates bad code (STR #1656) + - OSF/Tru64 now uses 'install-sh' instead of 'install' to + accomodate for a missing '-d' option (STR #1632) + - New option in Fluid project settings to translate all + shortcut modifiers from FL_META or FL_CTRL to FL_COMMAND + - Made icon size fixed (50x50) in fl_message etc. (STR #1626) + - Fixed selection of first word in Fl_Help_View + - Fixed endless loop in Fl_Text_Display (STR #1655) + - Allowing shortcuts in Tabs (STR #1652) + - Fixed Makefile "make clean" (STR #1642, + STR #1643, STR #1641) + - The sample RPM spec file now enables large file support + and threading support (STR #1603) + - Changed minimum contrast between background and text to + 99 and added more weight to the blue component to improve + readability for certain color combinations (STR #1625) + - Fixed VCNet OpenGL project file (STR #1617) + - Fixed scrolling of clipped areas in MSWindows (STR + #1601) + - Fixed clipping in OS X Quartz offscreen buffers (STR + #1595) + - Now flush file chooser preferences after every change to + avoid data loss (STR #1609) + - The Fl_File_Chooser constructor now saves and restores the + current group (STR #1611) + - Added Fl::awake(fn*,void*) to set a handler for thread + messages (STR #1536) + - Added "mute sound" option to Sudoku game. + - Updated the bundled zlib to v1.2.3. + - Updated the bundled libpng to v1.2.16. + - "make install" now uses the install command (or the + included install-sh script) to copy files to the + install directories, to ensure that permissions are + correct. + - Fixed DLL generation via MingW/Cygwin (STR #1546) + - FLUID incorrectly opened the display when generating + source code for Fl_Help_View widgets (STR #1318) + - Fl_Double_Window did not always show the scheme + background image. + - Fixed first window behavior in OS X (STR #1548) + - Fixed calculation of character widths for OS X + Quartz rendering (no STR) + - Fixed OS X mouse click handling (STR #1504) + - Added missing GLUT functions so that FLTK can be used + as a fairly complete C++ replacement for the original + GLUT library (STR #1522) + - Fl::awake() could block on X11 and OSX (STR #1537) + - Updated recursive mutex code to run on platforms other + than Linux and to do a run-time check to determine + whether they are supported by the kernel (STR #1575) + - WIN32 did check callbacks after the event processing instead of + before as documented (STR #1535) + - Fl_File_Chooser now hides the window before doing a callback + when the user clicks on the OK button (STR #1565) + - Fixed indentation of nested HTML elements (STR #1549) + - Made layout of Fl_Help_Dialog consistent with other + help windows and web browsers. + - Improved GTK+ schemed round box (STR #1531) + - Fluid avoids writing unsupported combinations of the + "when()" flags (STR #1501) + - Fl_Browser_ would allow keyboard callbacks even though + "when()" was set to "never" (STR #1501) + - Added automated little helpers to Sudoku + - Added example code for Wizard with the + Tabs demo (STR #1564) + - Optimized Fl_Tabs drawing for speed (STR #1520) + - OS X resource fork now obsolete (STR #1453) + - Added chapter 10 about multithreading (STR #1532, + 1533) + - OS X system menu bar top level attribute support + improved (STR #1505) + - Fixed Quartz image drawing bug (STR #1438) + - Fixed Quartz fl_read_image + - Overlay drawing is now avoiding XOR mode (STR #1438) + - Fixed Scroll crash in Fluid Live Mode (STR #1524) + - Fixed mousewheel event propagation (STR #1521) + - Fixed drawing issues of a tile in a scroll (STR #1507) + - Fixed dismissing buttons in menu bars (STR #1494) + - Making a child group visible in a Fl_Tabs or Fl_Wizard + group now shows that tab or pane. + - Added fl_open_uri() function as proposed on + fltk.development. + - Added Fl::has_check() which previously was prototyped + and documented, but not implemented (STR #1542) + - Enabled Fl::add_check() on OS X (STR #1534) + - Documented tooltip inheritance (STR #1467) + - Better event mouse handling fixing detached menus and + sticky tooltips (STR #1463, STR #449) + - Added Fl::scrollbar_size() methods that are used by all + of the scrollbar-using widgets (STR #1500) + - fl_read_image() was broken on Intel-based Macs (STR + #1490) + - Fl_Progress was using the wrong width to calculate + progress (STR #1492) + - Fl::x(), Fl::y(), Fl::w(), and Fl::h() did not report + the desktop work area on X11 (STR #1482) + - Shortcut events could be sent to the wrong window (STR + #1451) + - Fl_Spinner did not handle the arrow keys properly (STR + #1476) + - Fl_File_Browser did not calculate the width of + directory items correctly (STR #1469, STR #1470) + - Fl_Pack incorrectly started widgets at an offset of 1/2 + the spacing value. + - FLUID did not generate correct window class code if + the class name was not a standard FLTK window class. + - FLUID incorrectly included for + widget classes that were not subclassed from a standard + FLTK widget class. + - The demo master test program now supports scheme + selection and all demos use it (STR #1459) + - fl_arc() and fl_pie() did not draw properly on WIN32 + when the start and end points were identical (STR + #1461) + - Fl_Input and Fl_Text_Editor now hide the mouse pointer + when typing into them (STR #1466) + - Implemented alpha blending for Quartz, WIN32, and X11 + - Check buttons did not redraw properly with box() set to + FL_NO_BOX (STR #1440) + - Added the Bluecurve-inspired scheme "gtk+". + - Updated documentation (STR #1420, STR #1421) + - Fixed font caching issue (STR #1415) + - Fixed crash in fl_file_chooser (STR #1410) + - Fixed Fluid hotspot bug (STR #1416) + - Fixed image copy code (STR #1412) + - Fixed latin-to-roman text conversion (STR #1411) + - Fixed Cygwin timeout for "select" calls (STR #1151) + - Improved Mac OS X subwindow handling (STR #1402) + - Fixed more inconsistencies between fl_draw and + fl_measure (STR #1408) + - Fixed fl_measure which mistook a trailing '@@' for a + symbol (STR #1406) + - Fixed GLUT behavior on window creation (STR #1403) + - Fixed OS X bug that would hide tooltips before they + were shown (STR #1392) + - Fixed Fl_Tabs tooltip reappearing (STR #1324) + - Added a new demo game called "Block Attack!" + - Updated the Sudoku game to show a notice about Hard and + Impossible puzzles having multiple solutions which are + not a bug or error (STR #1361) + - Fixed filechooser to behave as documented when file + pattern changes (STR #1359) + - Completed the global function index and added an + alphabetical list of all methods (STR #1319) + - Avoiding problems with some platforms that don't + implement hypot() (STR #1366) + - Fixed floating point value formatting for Fl_Spinner + (STR #1331) + - Fixed Fl_Positioner callback when released (STR #1387) + - Fixed WIN32 zero size window issue (STR #1387) + - Fixed Sudoku window positioning (STR #1398) + - Fluid Code Declarations can now handle C++ style + comments (STR #1383) + - Fixed uninitialized data in OS X and WIN32 timeout + functions (STR #1374). + - Fixed speed issues when measuring text on OS X with + Quartz (STR #1386). + - Fixed focus issues on OS X (STR #1377) + - Optional precision argument when storing floats or + doubles in a Preferences file (STR #1381) + - Fixed callback not called when using arrow keys in + Fl_Slider (STR #1333) + - Changing the shortcut of a widget in fluid now marks the + document as dirty (STR #1382) + - Fl_Text_Editor now correctly handles middle mouse + clicks (STR #1384) + - Added some GLUT4 functions (STR #1370) + - Added "context_changed()" function for OpenGL windows + which allows efficient texture loading (STR #1372) + - Added missing "const" to GLUT call (STR #1371) + - Fixed stray FL_RELEASE events after clicking system + areas on OS X (STR #1376) + - FLUID now only writes definitions of "o" and "w" + variables as needed, reducing the number of "variable + is shadowed" warnings from GCC. + - Added access to Xft font pointer (STR #1328) + - Fixed endianness in OS X mouse cursor graphics (STR + #1348) + - Fixed crash on mixed use of keyboard and mouse for + Fl_Menu_Button (STR #1356) + - Fixed Fl_Window::visible() and shown() for OS X + (STR #1341) + - Fixed Fl_Window::copy_label() losing copy (STR #1332) + - Documentation fixes (STR #1336, STR #1329, STR #1339, + STR #1340) + - Added support for floating point Fl_Spinner in the + API, documentation, and Fluid (STR #1331) + - Repeat button now cancels timeout if it should get + deactivated during a callback (STR #1330) + - Added support for assigning Fl_Menu_Items to array + variables in Fluid (STR #1280) + - Added --with-archflags configure option to allow + passing of specific architecture-selection options to + the compiler and linker. + - Fixed WIN32 window stacking bug (STR #1296) + - Fixed wrong code generated by FLUID for Scrollbars (STR + #1287) + - Loading a file would not update the Widget Properties + dialog in FLUID (STR #1326) + - Fixed key compose sequences for shifted keys (STR + #1194) + - Added text selection and copy to Fl_Help_View. + - Fixed position of popup menu titles (STR #1322) + - Showing any window will disable the current tooltip + so it won't pop over menus (STR #1321) + - Updated documentation to reflect limitation of + Fl::delete_widget() (STR #1306) + - Fixed line wrapping in Fl_Text_Display (STR #1227) + - New function Fl::event_original_key() returns key code + before NumLock handling. + - Many OS X Quartz fixes (STR #1310, etc.) + - Fixed shortcut and default focus for message dialogs + (STR #1298) + - Fixed focus issues (STR #1286, STR #1289, STR #1296) + - Fixed window resizing in OS X (STR #1297) + - In FLUID, declarations starting with the keyword + 'typedef', 'class', or 'struct' are now treated + correctly if inside a class (STR #1283) + - Tabs now show the correct tooltip (STR #1282) + - Included fltk.spec in configure.in (STR #1274) + - Fixed insufficiently invalidated cache + in Fl_Browser (STR #1265) + - Attempt to fix multi monitor issues (STR #1153) + - Fixed warnings when compiling w/Cygwin (STR #1152) + - Fixed missing reset of flag in FLUID (STR #1187) + - Fixed maximizing in OS X (STR #1221) + - Fixed 'make distclean' to remove binaries inside + MacOS app packages (STR #1169) + - FLUID Code Viewer is now truly a viewer, not a text + editor because edited text can not be saved. + - Fl_Spinner is now fully supported by FLUID (STR #1158) + - Fixed usage of deleted object after menu pulldown + (STR #1162) + - Calling fl_font(0, 0) under Xft would access a NULL + pointer (STR #1205) + - Setting a new value in Fl_Input_ wil now actually move + cursor to the end of the input field as documented + (STR #1161) + - FLUID crashed on WIN32 with international characters + (STR #1176) + - Fl_Check_Browser did not allow the user to toggle the + check boxes (STR #1232) + - Fl_Help_View crashed on WIN32 with international + characters (STR #1228) + - Fl::run() no longer clears resources on WIN32 (STR + #1231) + - Fl::add_timeout() leaked resources on OSX (STR #1233) + - Accented characters could not be entered on OSX (STR + #1195) + - The caret key lookup was missing for OS X + - FLUID didn't handle loading .fl files with + international characters properly with all compilers + (STR #1150) + - Fl_Spinner's minimum() and maximum() "get" methods were + misspelled (STR #1146) + - The largefile support changes in 1.1.7 broke binary + compability for fl_filename_list(); you must now use + "--enable-largefile" when configuring to get large file + support, and the large file support definitions are + added to the output of "fltk-config --cflags" (STR + #1159) + + +CHANGES IN FLTK 1.1.7 + + - Documentation fixes (STR #571, STR #648, STR #692, STR + #730, STR #744, STR #745, STR #931, STR #942, STR #960, + STR #969) + - Various menu widget fixes (STR #1140, STR #1143, STR + #1144) + - The threads demo would display negative prime numbers + on MacOS X; this appears to be a MacOS X bug, but we + added a workaround to "fix" this (STR #1138) + - Fl::dnd() now sets the content type of the drag to + "text/uri-list" when it sees the dragged text is + composed of URIs. + - Fixed keyboard shortcut handling in FLUID and shortcut + labeling in FLTK (STR #1129) + - Fixed include path for CMake build (STR #1123) + - Fixed unnecessary delay in WIN32 event handling + (STR #1104) + - Fixed handling of Ctrl-C in Fl_Text_Display (STR #1122) + - OS X Quartz version now draw a nice resize control (STR + #1099) + - FLTK now enables large file support when available (STR + #1087) + - Fl_Clock_Output depended on a time value that was the + same as an unsigned long, which is incorrect for WIN64 + and VC++ 2005 (STR #1079) + - Fl_Text_Display::wrap_mode() would crash if no buffer + was associated with the widget (STR #1069) + - Updated the default label and text colors of all widgets + to use FL_FOREGROUND_COLOR instead of FL_BLACK (STR + #1052) + - Fl::set_fonts() now works with Xft (STR #1012) + - Fl_Value_Input now uses the screen-absolute position + instead of the window-relative position when dragging + the value; this avoids some jumping conditions (STR + #1037) + - Menus now pop up fully inside the screen if possible + (STR #973) + - Fixed illegal access in Preferences (STR #1025) + - Fixed x-offset problem in Help_Widget (STR #998) + - Clipboard will persist if owner window is hidden (STR + #1019) + - Fixed handling of Win32 Device Contexts (STR #1007) + - Fixed C++ style comments in C files (STR #997) + - Fixed signedness of scanf() argument (STR #996) + - Fixed cross-compiling problem (STR #995). + - FLUID now knows if a static callback is already + declared in a class and won't declare it 'extern' (STR + #776) + - Some actions in FLUID would not set the "changed" flag + (STR #984, STR #999) + - fl_filename_list now always appends a forward slash to + directory names (STR #874) + - Multiline Input will update right if a space character is + inserted in word wrap mode (STR #981) + - FLUID group labels redraw correctly (STR #959) + - FLUID now updates color of Fl_Tabs children (STR #979) + - FLUID now supports 'size_range()' (STR #851) + - FLUID selection boxes now synchronised (STR #964) + - fl_filename_list() now recognizes pathnames without + trailing slash as directions (STR #854) + - Fl_Text_Display now auto-scrolls in all + directions (STR #915) + - Borderless windows will not show in the taskbar anymore + on X11 (STR #933) + - Fixed event_text() field on FL_DND_* event on + OS X and WIN32 (STR #968) + - The fltk-config utility now supports "--cc" and "--cxx" + options to get the C and C++ compilers that were used + to compile FLTK (STR #868) + - Fl_Valuator-derived widgets could show more digits than + were necessary (STR #971) + - Fl_GIF_Image did not handle images with an incorrect + number of data bits (STR #914) + - Fixed some plastic drawing artifacts (STR #906) + - Fl_Help_View now draws the box outside the scrollbars, + like the other scrollable widgets (STR #871) + - The fltk-config script now handles invocation via a + symlink (STR #869) + - Updated WIN32 cut/paste code to consistently handle DOS + text (STR #961) + - Added shared library support for Cygwin and MingW (STR + #893) + - Fl_File_Chooser did not implement the user_data() + methods (STR #970) + - Compilation could fail if a previous installation of + FLTK was in the same (non-standard) directory as an + image library (STR #926) + - Fixed OSX compilation problems with non-HFS filesystems + (STR #972) + - Problems with CMake on MinGW have been solved, thanks + to Mr. "fltk.x0", who submitted the patch. (STR #863) + - Fixed memory leak in Fl_Check_Browser reported by + "miguel2i". (STR #967) + - Fl_File_Input could draw in the wrong window (STR #958) + - WIN32: Internal WM_PAINT message now ignored (STR #831) + - Added Windows support for Fl_Window::xclass() (STR #848) + - Floating point input field allows characters from + current locale (STR #903) + - Fixed integration of Fl_Input_Choice into FLUID (STR + #879) + - New windows touching the right screen border would be + positioned all the way to the left (STR #898) + - Made pie drawing size for WIN32 and OS X the same as + X11 (STR #905) + - Fixed OS X issue with OpenGL windows inside of Tabs + (STR #602) + - FLUID Code Editor would occasionally not draw the last + character in the buffer (STR #798) + - FLUID Declaration private flag fixed (STR #799) + - FLUID overlay now shows a seperate bounding box of + selected items with correct handles and a dotted + boundig box for all labels (STR #790) + - Fixed left overhang of large chracters in Fl_Input_ + (STR #941) + - Fixed button resizing in File Chooser (STR #884) + - Fixed FLUID redraw issue (STR #912) + - Added 32bit BMP Image file format support (STR #918) + - Value Sliders would not receive focus when clicked on + (STR #911) + - Added redraw of some widgets to show focus change (STR + #910) + - Fl::set_font would not clear 'pretty' name (STR #902) + - Fixed unescaped '@' in fonts demo (STR #867) + - FLUID should not open the Display connection anymore if + creating code only (STR #904) + - Improved hidden copy / ctor implementation (STR #860) + - Increased matrix stack depth and added over/underflow + error (STR #924) + - Reverted Mac Carbon Clipping simplification that broke + subwindow clipping (STR #908, SVN r4386) + - Fixed bitmap scaling code + - Fixed tiny memory leak (STR #878) + - Fixed hang on corrupt jpeg (STR #915) + - Fixed static allocation of font buffer in demo (STR #909) + - Added symbols 'refresh', 'reload', 'undo', and 'redo'. + - Fixed focus loss on Fl_Window:resize() + - Fl::delete_widget would hang fl_wait after deleting the + window (STR #679) + - Fl::paste would sometimes not recoginze external + changes of the clipboard (STR #722) + - Clipping fixes for OSX + - Removed attempt to find items via + Fl_Menu_::find_item() in linked submenus + - FLUID interactive window resizing fixes (STR #873, 791) + - FLUID panel resize and alignment fixes (STR #891) + - Fl_Window::show(argc, argv) now sets the scheme before + showing the window; this should eliminate any + flickering between the standard and plastic schemes on + startup (STR #886) + - Selected tabs are now drawn slightly larger than + unselected tabs so they stand out more (STR #882) + - Round Plastic boxes now draw round (STR #841) + - FL_PLASTIC_DOWN_BOX drew with artifacts (STR #852) + - Changed initializations on WIN32 (STR #862) + - Fl_Preferences::getUserdataPath() didn't work for + sub-groups (STR #872) + - Fixed some redraw issues on Windows XP. + - FLUID didn't set the initial size of widgets properly + (STR #850) + - Fl_Tabs would steal focus away from its children on a + window focus change (STR #870) + - filename_relative() now converts the current directory + to forward slashes as needed on WIN32 (STR #816) + - Fl_File_Chooser::value() and ::directory() now handle + paths with backslashes on WIN32 (STR #811) + - Added the standard rgb.txt file from X11 to the test + directory, allowing all platforms to try the colbrowser + demo (STR #843) + - Resizing of OpenGL subwindows was broken on OSX (STR #804) + - The fltk-config script now supports running from a + source directory (STR #840) + - Fl_Browser_ didn't update the position properly when an + item was deleted (STR #839) + - fl_contrast() now compares the luminosity of each color + (STR #837) + - Fl_Input_ crashed on some platforms when wrapping + international text characters (STR #836) + - Fixed some BMP images loading bugs (STR #825) + - Fl_File_Chooser now returns directory names with a + trailing slash to avoid problems with relative + filenames (STR #819) + - Fl_Help_View now supports the FONT and U elements (STR + #815) + - OpenGL windows that were completely off-screen caused + problems with some graphics cards on WIN32 (STR #831) + - Multiple screen support didn't work on Windows NT and + 95 (STR #821) + - Fl_Scrollbar didn't compute the correct knob size when + using the "nice" types (STR #845) + - fl_draw() would segfault on WIN32 if no font was set; + it now uses the default font (STR #828) + - Fl_Browser_ was calling the callback multiple times for + a single selection change with FL_WHEN_CHANGED (STR + #834) + - Added "filenew", "fileopen", "filesave", "filesaveas", + and "fileprint" symbols with standard toolbar + symbology. + - Updated Fl_Tabs to check the contrast of the label + color against the tab background, and to highlight the + top 5 lines of the tab pane with the selection color so + that selected tabs stand out more. + - The example programs can now compile separate from the + FLTK source distribution (STR #809) + - The example programs are now installed with the + documentation (STR #809) + - Fixed the drawing of the Fl_Browser_ selection box (STR + #786) + - Dropped Codewarrier project files and support. + - The FLTK string functions are now compiled in on all + systems (STR #774) + - Fixed symbol demo label bug (STR #777) + - Fixed position of menu titles (STR #795) + - Added missing Fl_Window::copy_label() method. + - Fixed wrong tooltip in FLUID (STR #784) + - Added zlib path to FLUID (STR #783) + - Menus and other pop-up windows now obey screen + boundaries on multi-screen displays (STR #781) + - Fl_Chart would draw outside its bounding box (STR #780) + - Added Fl::screen_count() and Fl::screen_xywh() APIs to + support multi-screen displays. + - FLUID now supports direct creation of widget classes. + - Fl_File_Chooser now correctly handles multiple + selections that are a mix of files and directories. + - Fl_File_Chooser no longer resets the type() when + choosing a single file, and it now works when selecting + multiple directories (STR #747) + - Fl_File_Icon::load_system_icons() now only loads 16x16 + and 32x32 icon images to improve startup performance. + - Pressing Enter in the file chooser when selecting a + directory will choose that directory if it is currently + shown (STR #746) + - Added a fl_file_chooser_ok_label() function to set the + "OK" button label for the fl_file_chooser() and + fl_dir_chooser() functions. + - Added Fl_File_Chooser::ok_label() methods to set the + "OK" button label. + - The fl_ask() function is now deprecated since it does + not conform to the FLTK Human Interface Guidelines. + - The Fl_File_Chooser window now properly resizes its + controls (STR #766) + - The Fl_Help_Dialog window now properly resizes its + controls (STR #768) + - The Fl_File_Chooser favorites window is now resizable + (STR #770) + - Now provide FL_PLASTIC_ROUND_UP/DOWN_BOX box types + which are used by the plastic scheme. + - FLUID windows that are resized through the widget panel + now remain resizable by the window manager. + - Increased the size of the background image used by + the plastic scheme to reduce the CPU load of redraws + (STR #769) + - Fixed a syntax highlighting bug in the editor demo. + - Fl_Progress now contrasts the label color with the bar + color, so labels will be readable at all times. + - fl_read_image() didn't use the right red, green, and + blue masks on XFree86. + - Fixed Quickdraw drawing of 3 and 4 sided polygons (STR + #765) + - Fixed fl_message() code so that it does not get + accidentaly addded to the current group (STR #253) + - FLUID now highlights code in the widget callback and + code editors. + - FLUID now supports printing of windows. + - Fixed inactive drawing of border, embossed, and + engraved box types. + - Added Fl_Spinner widget (another combination of + existing widgets in a header file) + - FLUID now provides support for UI templates. + - fl_not_clipped() incorrectly used the current window + dimensions for gross clipping, which interfered with + off-screen rendering. + - Fl_Window::draw() and Fl_Window::iconlabel() could leak + memory if copy_label() was used on the window. + - fl_shortcut_label() now shows letter shortcuts in + uppercase, e.g. "Ctrl+N" instead of "Ctrl+n" to be + consistent with other toolkits. + - FLUID now provides unlimited undo/redo support. + - FLUID now provides an option to choose which scheme + (default, none, plastic) to display. + - Fixed scheme background issue with windows in FLUID. + - In FLUID, new widgets are now created with the ideal + size by default, and menu bars are positioned to use + the entire width of the window. + - Added Layout/Widget Size submenu to select default + label and text size (Tiny, Small, and Normal). + - Added Edit/Duplicate command to FLUID to duplicate the + current selection. + - FLUID now tracks the current state of the widget bin + and overlays. + - Now fill the widget image paths with relative + filenames. + - Fixed frame drawing of Fl_Text_Display (STR #762) + - Fl_Clock_Output::value() did not return the previously + set value (STR #748) + - Added comment type to FLUID. This is useful for + generating copyright notices in the source and header + files. + - Fl_Valuator would not format text output with decimal + point when the step value was fractional, but above 1. + - fl_filename_relative() didn't compare drive letters in + a case-insensitive way (STR #741) + - Fixed menu item width calculations with symbols (STR + #740) + - The keyboard shortcut handling code did not handle + 8-bit characters properly (STR #731) + - Fl_JPEG_Image could still crash an app with a corrupt + JPEG file (STR #739) + - Using the layout alignment controls on a menu widget + would cause FLUID to crash (STR #742) + - Added QNX bug workaround for menu handling (STR #704) + - Added Greg Ercolano's simple Fl_Input_Choice widget + which is a combination of the Fl_Input and + Fl_Menu_Button widgets (STR #650) + - Fl_Multiline_Input now scrolls the full height of the + widget instead of 5 lines when the user presses PageUp + or PageDown (STR #727) + - CMake build fixes (STR #724) + - Fl_Browser::swap() didn't handle redraws properly when + the swapped lines had different heights (STR #729) + - FL_MOUSEWHEEL events are now sent first to the widget + under the mouse pointer and then to the first widget + which accepts them. This is similar to the way + shortcut events are handled and is consistent with the + way the mouse wheel is handled by other toolkits. + - Fl::wait() could block on WIN32 if the window was + deleted via Fl::delete_widget() (STR #679) + - Fl_Preferences::RootNode did not find the user's home + directory on some non-US versions of Windows (STR + #720) + - Fl_Window::hide() didn't delete the current clipping + region on WIN32, causing a GDI resource leak in some + situations (STR #723) + - Removed a few warnings when compiling on OS X + - Fl_Menu now draws the arrow more like other toolkits + and 2.0 (STR #651) + - Fixed a VC++ compiler error in Fl_JPEG_Image.cxx (STR + #676) + - FL_SHADOW_BOX/FRAME drew outside of the bounding box + (STR #694) + - Fl_Widget::copy_label(NULL) didn't work (STR #707) + - Fl_Choice now allows click selection like + Fl_Menu_Button and Fl_Menubar (STR #706) + - Updated cmake support (STR #645) + - Fl_Check_Browser didn't draw properly when inactive + (STR #681) + - Removed some redundant code in Fl_Group::handle() (STR + #669) + - The file chooser didn't always deactivate the OK + button when necessary (STR #653) + - Image drawing on OSX changed the current drawing + colors (STR #662) + - Fixed some compiler errors on WIN32 (STR #647, STR + #726) + - FLUID didn't update the widget panel X/Y/W/H values + when moving the selected window (STR #701) + - FLUID didn't use the label type constant names for + menu items, causing them to be drawn using the normal + label type (STR #668) + - Fl_File_Chooser was slow with large directories (STR + #654) + - FLUID didn't add xclass() calls to windows (STR #718) + - The X11 DND code did not correctly select a text + format for incoming data (STR #711) + - Fixes to Fl_JPEG_Image error handler. + - Fl_Menu::popup() and ::pulldown() would crash an + application if a callback created widgets before they + returned (STR #685) + - Fl_Double_Window would cause a full redraw, even if + only small parts of the UI were changed on Mac OS X. + - Fl_JPEG_Image did not correctly handle errors reported + by the JPEG library (STR #652) + - Fl_Menu now draws sub-menu arrows like other toolkits + and FLTK 2.0 (STR #651) + - Fixed a compiler warning in Fl_Window.H (STR #641) + - Tooltips disabled shortcut processing (STR #643) + - Fl::event_number() didn't always match the value sent + to the handle() method (STR #634) + - Fl_Shared_Image::reload() didn't set the image_ + pointer properly in all cases (STR #632) + - Fl_Help_View::topline() incorrectly set the changed() + flag (STR #631) + - Fl_Choice::value() now supports NULL or -1 to deselect + the current item (STR #637) + - More VC++ 6 project file fixes (STR #638) + - Added missing Watcom makefile in the test directory + (STR #636) + - Fl_Text_Display::word_left would hang if the cursor + was at position 0 (STR #635) + + +CHANGES IN FLTK 1.1.6 + + - Documentation updates (STR #552, STR #608) + - Added the 2.0 Fl_Widget::copy_label() method to + allow FLTK 1.x applications to have their label + strings managed by FLTK (STR #630) + - Added Fl::delete_widget() method to safely delete + widgets in callback methods (STR #629) + - Fl_Widget::damage(uchar,int,int,int,int) didn't clip + the bounding box properly (STR #626) + - Windows could appear on the wrong screen on OSX (STR + #628) + - Fl_Double_Window produced an error on resize with X11 + - FLUID didn't display menu items using images properly + (STR #564) + - Fl_Sys_Menu_Bar didn't compile on case-sensitive + file-systems (STR #622) + - FLUID didn't handle default function parameters + properly (STR #579) + - Moving or resizing widgets in FLUID didn't always + update the widget panel (STR #600) + - FLTK windows could appear off-screen on X11 (STR #586) + - The configure script did not support + --disable-localfoo to completely disable image file + support (STR #582) + - The Visual C++ 6.0 project files still listed the old + JPEG, PNG, and ZLIB library names (STR #577) + - Fixed the scandir() conditional code for HP-UX 11i + (STR #585) + - Fl_Text_Display didn't support CTRL/CMD-A/C (STR #601) + - Watcom fixes (STR #581, STR #584, STR #594, STR #595, + STR #623, STR #627) + - Fixed library include order when building DSOs on + MacOS X (STR #596) + - fl_xid() could cause a WIN32 application to crash (STR + #560, STR #576, STR #618) + - Fl_Browser::remove_() removed the item from the list + before computing the item height, which caused + problems with some programs (STR #613) + + +CHANGES IN FLTK 1.1.5 + + - Documentation updates (STR #568, STR #570) + - Shortcuts were incorrectly underlined in multi-line + labels (STR #566) + - More CMake updates (STR #499) + - The Watcom C++ compiler needed a small change (STR + #567) + - Added DESTDIR support and now remove all man pages for + the "uninstall" target (STR #545) + - Fix PNG drawing on buggy WIN32 graphics cards (STR + #548) + - The configure script didn't propagate the CPPFLAGS + environment variable (STR #549) + - The numpad keys didn't work properly on WIN32 (STR + #502) + - fl_input() and friends now set the input focus to the + text field when the dialog is shown (STR #553) + - Fixed background color mixup when drawing Fl_Choice + menus (STR #544) + - Fixed MingW makefiles (STR #550) + - More VC++ project file tweaking (STR #559) + - Fl_PNG_Image didn't use the png_set_trns_to_alpha + function when available (STR #547) + - The FL_UNFOCUS event wasn't always sent when switching + tabs (STR #558) + + +CHANGES IN FLTK 1.1.5rc3 + + - Documentation updates (STR #505, STR #513) + - Updated PNG library source to 1.2.7. + - Updated ZLIB library source to 1.2.1. + - Fixed VC++ project file problems (STR #476, STR #478, + STR #520, STR #527, STR #537) + - Now look for 8 bits of alpha when the developer has + requested FL_RGB8 (STR #541) + - The last line in an Fl_Help_View widget was not + aligned properly (STR #536) + - The "search" symbol looked like a Q (STR #536) + - Changed Fl_Help_View::get_color() to use a lookup + table to avoid serious Borland C++ 5.5 compiler bugs + (STR #533) + - Fixed Watcom compiler warnings with FL/Fl_Widget.H + (STR #540) + - The image class copy() methods did not always make a + separate copy of the image data (STR #539) + - Fixed an edge case in fl_old_shortcut() that could + cause it to read beyond then end of the shortcut + string (used for XForms named shortcuts) + - Added (unsupported) CMake files (STR #499) + - Tooltips would not reappear on the same widget, and + the initial tooltip delay was not used after a tooltip + was shown (STR #465) + - Fixed a compile problem with the Linux 2.6 threading + support (STR #483) + - Fixed problems with 2-byte Xpm files on 64-bit + platforms (STR #525) + - FLTK didn't handle the ReparentNotify event on X11 + (STR #524) + - The old source file "fl_set_gray.cxx" is not needed + (STR #516) + - Fl_Text_Display still called delete[] instead of + free() in one place (STR #503) + - The symbol test program did not handle the @+ symbol + properly (STR #490) + - Fl_File_Chooser didn't correctly call isprint() and + isspace() when checking to see if the current file was + text that can be previewed (STR #517) + - FLUID didn't compile with Borland C++ due to a + compiler bug (STR #496) + - Fl_Positioner did not handle reversed min and max + values (STR #510) + - fl_descent(), fl_height(), and fl_width() would crash + a program if you didn't call fl_font() first; they now + return -1 if no font is set (STR #500) + - Added test/unittests to verify pixel drawing and + alignment across platforms + - Fl_Menu_::find_item() didn't determine the menu path + properly (STR #481) + - The build system now installs image library header + files in FL/images/filename.h so that FLTK programs + will use the same header files as the FLTK image + libraries. + - The build system now creates image libraries named + "libfltk_name.a" instead of "libname.a" to avoid + clobbering an existing installed library (STR #480) + + +CHANGES IN FLTK 1.1.5rc2 + + - Documentation updates (STR #365, STR #399, STR #407, + STR #412, STR #414, STR #452, STR #462) + - Fl_Text_Display did not handle drawing of overlapping + text (italic next to plain, etc.) properly (STR #381) + - All of the core widgets now consistently set changed() + before calling the callback function for a change in + value; this allows programs to check the changed() + state in a callback to see why they are being called + (STR #475) + - Fl_File_Chooser did not handle some cases for filename + completion (STR #376) + - Fl_Help_View didn't properly compute the default + maximum width of the page properly, resulting in + non-wrapped text in table cells (STR #464) + - Fl_Text_Editor no longer tries to emulate the Emacs + CTRL-A shortcut to move to the first column, since + there is a key for that and the widget does not + emulate any other Emacs keys (STR #421) + - Fl_File_Chooser always disabled the OK button when the + user pressed DELETE or BACKSPACE (STR #397) + - Added Fl_Browser::swap() methods (STR #459) + - Fl_Counter didn't use a thin down box for the text + field if the box type was set to FL_THIN_UP_BOX (STR + #467) + - Fl_Help_View now resets the scrollbars if they go + outside the current view (STR #464) + - fl_dir_chooser() did not show the previous selection + as documented (STR #443) + - Fl_Text_Display used delete[] instead of free() in + some places (STR #466) + - FLTK now includes copies of the PNG, JPEG, and ZLIB + libraries for platforms that do not have them (STR + #441) + - The fltk-config script did not include the + "-mno-cygwin" option under CygWin (STR #434) + - Fl_Help_View::find() did not check for a NULL value + (STR #442) + - Added search symbol to the search field of + Fl_Help_Dialog (STR #417) + - Added two new symbols, @search and @FLTK, which can be + used in labels. + - MacOS X: fixed NumLock mixup, added support for + FL_Menu and FL_Delete keys on external (PC) keyboards + (STR #445) + - Fl_File_Icon::draw() did not support drawing of complex + polygons in icon descriptions (STR #474) + - The configure script now offers options for JPEG, PNG, + and ZLIB libraries (STR #416) + - The first menu item in a list would not go invisible + (STR #406) + - Fl_Text_Buffer::replace() now range checks its input + (STR #385) + - FLTK now builds with the current release of MinGW (STR + #325, STR #401, STR #402) + - FLTK now honors the numlock key state (STR #369) + - The Fl_Text_Display widget did not redraw selections + when focus changed (STR #390) + - The plastic background image is now less contrasty + (STR #394) + - Fl_Scroll now uses a full redraw when the scheme is + set to plastic and the box type is a frame (STR #205) + - Fl_Window::resize() did not work properly with KDE 3.2 + (STR #356) + - FLTK didn't delete font bitmaps when the last OpenGL + window was deleted, preventing future text from + displaying (STR #310) + - FLUID didn't include a full initialization record for + the trailing NULL menu items (STR #375) + - Fl_Browser::item_width() did not properly handle + format modifiers (STR #372) + - Fl_Browser::item_height() did not handle columns + properly (STR #371) + - Fl_Gl_Window's on WIN32 now prefer accelerated pixel + formats over generic formats (STR #382) + - Fl_Window::resize() did not work on some systems if + the window was not shown (STR #373) + - FLUID did not write the user_data type if the + user_data field was empty (STR #374) + - The value(const Fl_Menu_Item*) method was not + implemented for Fl_Choice (STR #366) + - Fl_Pack didn't draw child widget labels the same way + as Fl_Group, causing display problems (STR #360) + - fl_read_image() didn't work when reading from an + offscreen buffer with some X11 servers (STR #364) + + +CHANGES IN FLTK 1.1.5rc1 + + - Documentation updates (STR #186, STR #245, STR #250, + STR #277, STR #281, STR #328, STR #338) + - fl_scroll() did not handle scrolling from off-screen on + WIN32 (STR #315) + - Fl_File_Chooser did not allow manual entry of a drive + letter (STR #339) + - Fl_Menu now uses the boxtype to redraw the menu + background (STR #204) + - Fl_Scroll now shows the background image when a framed + box type is used and the Fl_Scroll is a direct + decendent of a window (STR #205) + - Added a new_directory_tooltip string pointer to allow + localization of the file chooser's new directory + button (STR #340) + - Added Fl_Menu_::find_item() method (STR #316) + - The Fl_Widget copy operator definitions were not + conditionally compiled properly (STR #329) + - FLUID's Layout functionality did not move child + widgets when laying out group widgets (STR #319) + - FLUID's Layout->Center In Group functionality did not + properly handle widgets that were children of a + Fl_Window widget (STR #318) + - The Fl_Text_Display destructor did not remove the + predelete callback associated with the current buffer + (STR #332) + - Fixed several bugs in the MacOS X Fl::add_fd() + handling (STR #333, STR #337) + - The Fl_Text_Display widget did not display selections + set by the application (STR #322) + - FLUID crashed if you did layout with a window widget + (STR #317) + - Fl_Scroll::clear() didn't remove the child widget from + the Fl_Scroll widget (STR #327) + - Fl_Value_Slider::draw_bg() didn't always apply the + clipping rectangle (STR #235) + - fl_filename_relative() returned the wrong string if + the absolute pathname was equal to the current working + directory (STR #224) + - Fl_Help_Dialog didn't correctly restore the scroll + position when going forward/back in the link history + if the file changed (STR #218) + - glutGetModifiers() did not mask off extra state bits, + confusing some GLUT-based applications (STR #213) + - Fixed mouse capture problems on MacOS X (STR #209, STR + #229) + - Fl_Sys_Menu_Bar is now built into the library for + MacOS X (STR #229) + - Fl_Menu_ now provides item_pathname() methods to get + the "pathname" of a menu item, e.g. "File/Quit" (STR + #283) + - Fl_Text_Display now provides cursor_color() methods to + get and set the cursor color (STR #271) + - Fl_Scroll didn't honor FL_NO_BOX (STR #305) + - FLUID declaration blocks didn't support public/private + definitions (STR #301) + - Fl_Preferences incorrectly created the preferences + directory before necessary (STR #247) + - The WIN32 project files still defined the (obsolete) + FL_STATIC constant (STR #279) + - Fl_Text_Display::buffer() did not support NULL values, + making it impossible to clean up text buffers from a + subclass (STR #295) + - Fl_Text_Display did not support a NULL + unfinishedStyleCB function (STR #241) + - Fl::background2() incorrectly marked the foreground + color as initialized (STR #255) + - Fixed the X11 CTRL + "-" detection code to properly + track the state of the CTRL key (STR #264) + - Fl_File_Icon::load_system_icons() didn't support KDE + 3.x (STR #299) + - WIN32's scandir() emulation did not allocate enough + memory for directory names (STR #263) + - Fl::compose() did not handle special keys like + backspace properly (STR #293) + - Fl_Choice did not clip its text when drawing using the + plastic scheme (STR #287) + - Fl_Group incorrectly mapped the emacs CTRL keys to + keyboard navigation (STR #228) + - Fl_File_Browser::load() didn't handle a NULL directory + name (STR #266) + - 64-bit library fixes (STR #261) + - The Fl_Valuator::format() function did not limit the + size of the number buffer (STR #268) + - The keypad Enter key works as the normal Enter/Return + key in common widgets (STR #191) + - Fixed some OS/2-specific build problems (STR #185, STR + #197) + - Calling Fl_Text_Display::buffer() with the same buffer + would cause an application to lockup (STR #196) + - Some of the widgets could crash an application if the + cursor was changed after a window was deleted (STR + #181) + - The Fl_Gl_Window WIN32 pixel format code did not + choose the pixel format with the largest depth buffer + (STR #175) + - The configure script didn't leave space between the + CFLAGS/CXXFLAGS and X_CFLAGS variables (STR #174) + - The Fl_JPEG_Image and Fl_PNG_Image classes did not + trap errors from the corresponding image libraries + (STR #168) + - Added "--with-links" configure option to control + whether symlinks are created for the FLTK header files + (STR #164) + - Added new hoverdelay() to Fl_Tooltip to control how + quickly recent tooltips appear (STR #126) + - FLUID now sets the size range when a window is shown. + This seems to be necessary with some window managers + (STR #166) + + +CHANGES IN FLTK 1.1.4 + + - The fl_read_image() function was not implemented on + OSX (STR #161) + - VC++ 7.1 didn't like how the copy operators were + disabled for the Fl_Widget class; now include inline + code which will never be used but makes VC++ happy + (STR #156) + - Fixed an IRIX compile problem caused by a missing + #include (STR #157) + - FLUID didn't write color/selection_color() calls using + the symbolic names when possible, nor did it cast + integer colors to Fl_Color (STR #146) + - Fl_File_Chooser was very close for multiple file + selection in large directories (STR #140) + - Fl_Text_Display/Editor did not disable the current + selection when focus was shifted to another widget + (STR #131) + - Fl_Choice didn't use the normal focus box when the + plastic scheme was in use (STR #129) + - Fl_Text_Editor didn't use selection_color() + consistently (STR #130) + - The fltk_forms, fltk_gl, and fltk_images DSO's and + HP-UX shared libraries are now linked against the fltk + shared library to provide complete dependency + resolution (STR #118) + - The configure.in file did not work with autoconf 2.57. + - FLUID didn't redraw widgets when changing the X, Y, W, + or H values in the widget panel (STR #120) + - Fl_Window::show(argc, argv) wasn't calling + Fl::get_system_colors() as documented (STR #119) + - DSO (shared library) building wasn't quite right for + some platforms (STR #118) + - OSX: some changes to make ProjectBuilder compiles + possible. + - OSX: FLTK would not know where a window was positioned + by the OS. As a result, popup menus could open at + wrong positions. + + +CHANGES IN FLTK 1.1.4rc2 + + - Fl_Window::show(argc,argv) incorrectly opened the + display prior to parsing the arguments; this prevented + the "-display foo" option from working (STR #111) + - Images were not clipped properly on MacOS X (STR #114) + - Fl::reload_scheme() and Fl::scheme("foo") incorrectly + called Fl::get_system_colors(). This prevented an + application from setting its own color preferences + (STR #115) + - The 'Enter' key event on OS X would not set + Fl::e_text. + - Changed behaviour of FLUID to always paste into + a selected group (STR #88) + - Menuitem now changes font, even if fontsize + is not set (STR #110) + - Swapped shortcut labels in OS X (STR #86) + - Non-square Fl_Dial would calculate angle from user + input wrong (STR #101) + - Updated documentatiopn of fl_draw (STR #94) + and Fl_Menu_::add() (STR #99) + - FLUID collapse triangle events were not offset by + horizontal scroll (STR #106) + - QuitAppleEvent now correctly returns from Fl::run() + instead of just exiting (STR #87) + - Hiding the first created OpenGL context was not + possible. FLTK now manages a list of contexts (STR #77) + - FLUID didn't keep the double/single buffer type for + windows. + - FLTK didn't work with Xft2. + - OSX window resizing didn't work (STR #64) + - Fixed MacOS X shared library generation (STR #51) + - Several widgets defined their own size() method but + didn't provide an inline method that mapped to the + Fl_Widget::size() method (STR #62) + - Fl_Scroll didn't provide its own clear() method, so + calling clear() on a Fl_Scroll widget would also + destroy the scrollbars (STR #75) + - Fl::event_text() was sometimes initialized to NULL + instead of an empty string (STR #70) + - fl_draw() didn't properly handle a trailing escaped + "@" character (STR #84) + - Added documentation for all forms of + Fl_Widget::damage() (STR #61) + - Fl_Double_Window now has a type() value of + FL_DOUBLE_WINDOW, to allow double-buffered windows to + process redraws properly on WIN32 (STR #46) + - Added FL_DAMAGE_USER1 and FL_DAMAGE_USER2 damage bits + for use by widget developers (STR #57) + - Fl_Help_View didn't support numeric character entities + (STR #66) + - Menu shortcuts didn't use the Mac key names under + MacOS X (STR #71) + - CodeWarrior Mac OS X updated to work with current + CW8.3 (STR #34) + - Apple-C/X/V/Z didn't work in the Fl_Input widget due + to a bad mapping to control keys (STR #79) + - Added the OSX-specific fl_open_callback() function to + handle Open Documents messages from the Finder (STR + #80) + - The configure script contained erroneous whitespace in + various tests which caused errors on some platforms + (STR #60) + - The fltk-config script still supported the deprecated + --prefix and --exec-prefix options; dropped them since + they serve no useful purpose and would never have + worked for the intended purpose anyways... (STR #56) + - fl_filename_list returned 0 on Win32 if no directory + existed (STR #54) + - Pressing 'home' after the last letter in a Text_Editor + would move the cursor to pos 0 (STR #39) + - Fl::get_key(x) would mix up Ctrl and Meta on OS X (STR + #55) + - The configure script used the wrong dynamic library + linking command for OSX (STR #51) + - The Fl_Text_Editor widget did not set changed() nor + did it call the widget's callback function for + FL_WHEN_CHANGED when processing characters that + Fl::compose() handles (STR #52) + + +CHANGES IN FLTK 1.1.4rc1 + + - The file chooser did not reset the click count when + changing directories; if you clicked on a file in the + same position after changing directories with a + double-click, the chooser treated it as a triple + click (STR #27) + - Symbols with outlines did not get drawn inactive. + - The Fl_Help_View widget now provides a find() method + to search for text within the page. + - The Fl_Help_Dialog widget now provides a search box + for entering text to search for. + - The default font encoding on OSX did not match the + default on WIN32 or X11. + - Menu items were not drawn using the font specified in + the Fl_Menu_Item structure (STR #30) + - Long menus that were aligned such that the top of an + item was exactly at the top of the screen would not + scroll (STR #33) + - The OS issues appendix incorrectly stated that MacOS + 8.6 and 9 were supported; they are not (STR #28) + - Fixed handling of nested double-buffered windows (STR + #1) + - Showing a subwindow inside a hidden window would crash + the application (STR #23) + - OSX users couldn't enter some special chars when using + some foreign key layouts (STR #32) + - Hiding subwindows on OSX would hide the parent window + (STR #22) + - Added thin plastic box types. + - Fl_Pack ignored the box() setting and cleared any + unused areas to the widget color; it now only does so + if the box() is set to something other than FL_NO_BOX. + - Updated the Fl_Tabs widget to offset the first tab by + the box dx value to avoid visual errors. + - Updated the plastic up box to draw only a single + border frame instead of the old double one for + improved appearance. + - Updated the default background color on OSX to provide + better contrast. + - Fl_Text_Display and friends now look for the next + non-punctuation/space character for word boundaries + (STR #26) + - gl_font() didn't work properly for X11 when Xft was + used (STR #12) + - Fl_File_Browser incorrectly included "." on WIN32 (STR + #9) + - Include shellapi.h instead of ShellAPI.h in the WIN32 + drag-n-drop code in order to work with the MingW cross + compiler (STR #6) + - The cursor was not properly restored when doing + drag-n-drop on X11 (STR #4) + - Fl::remove_fd() didn't recalculate the highest file + descriptor properly (STR #20) + - Fl_Preferences::deleteGroup() didn't work properly + (STR #13) + - Fixed the fl_show_file_selector() function - it was + copying using the wrong string size (STR #14) + - fl_font() and fl_size() were not implemented on MacOS + X. + - Sorted the icon menu bar in FLUID. + - Fixed minor memory access complaints from Valgrind + - Compiling src/flstring.h on OS X with BSD header would + fail. + - Fl_Text_Editor didn't scroll the buffer when the user + pressed Ctrl+End or Ctrl+Home. + - Fl_Text_Editor didn't show its cursor when the mouse + was moved inside the window. + - FLUID now uses an Fl_Text_Display widget for command + output, which allows you to copy and paste text from + command output into other windows. + - Fl_Gl_Window could cause a bus error on MacOS X if the + parent window was not yet shown. + - FLUID could crash after displaying a syntax error + dialog for the callback code. + - FLUID would reset the callback code if you opened the + widget panel for multiple widgets. + - Added a NULL check to Fl_Text_Display (SF Bug #706921). + - The fltk-config script placed the LDFLAGS at the wrong + place in the linker options. + - Fl_Text_Display didn't draw the outer box in the right + dimensions, so it was invisible. + - Fl_Help_Dialog used the same color for links as for + the background, causing links to be invisible on pages + without a background color set. + + +CHANGES IN FLTK 1.1.3 + + - Documentation updates. + - FLTK now ignores KeyRelease events when X11 sends them + for repeating keys. + - FLUID now supports up to two additional qualifiers + before a class name (FL_EXPORT, etc.) to aide in + developing DLL interfaces for WIN32. + - Additional NULL checks in Fl_Button, + fl_draw_boxtype(), Fl_File_Chooser, and + Fl_Window::hotspot(). + - The Fl_Preferences header file needed to FL_EXPORT all + of the nested classes for WIN32. + - Fl_Double_Window couldn't be nested on WIN32. [SF Bug + #658219] + - Fl_Slider didn't call the callback function when the + user changed the value using the keyboard and the + "when" condition was FL_WHEN_RELEASE. [SF Bug #647072] + - Lines with less than 2 unique vertices and polygons + with less the 3 unique vertices were not drawn + properly. [SF Bug #647067] + - The size_range() values were not honored under MacOS + X. [SF Bug #647074] + - OpenGL windows didn't resize correctly on MacOS X. + [SF Bug #667855] + - The menus incorrectly used the overlay visual when one + or more menu items contained an image. [SF Bug #653846] + - Changed some error messages to use Fl::error() instead + of fprintf()... + - Fl_Text_Buffer and Fl_Text_Display used free to free + memory that was allocated using the new operator. + - Tweeked the plastic scheme under MacOSX to better + match the colors. + - The Fl_Image.H always included the x.H header file, + which included many system headers that could + interfere with normal GUI applications. It now uses + the corresponding based types for the image id and + mask to avoid this. + - The FLUID widget panel wasn't sorted, so keyboard + navigation was strange. [SF Bug #647069] + - Fl_Scroll didn't compute the location of labels to the + right or below when determining the area to erase. + - Added backward-compatibility macro for + filename_setext(). + - Fl_Bitmap::copy(), Fl_Pixmap::copy(), and + Fl_RGB_Image::copy() all could overflow the source + image when scaling the image. + - Double/triple clicks in Fl_Input fields didn't copy + the expanded selection to the clipboard. + - Fl_Glut_Window and Fl_Gl_Window didn't always initialize + the OpenGL context on MacOS. + + +CHANGES IN FLTK 1.1.2 + + - Fl_Menu_Bar now supports drawing vertical dividers + between menu items and submenus in the menu bar. + - Fl_File_Chooser::value() didn't return NULL when the + user clicked Cancel while selecting a directory. This + bug also affected fl_dir_chooser(). + - Fl_Menu_::add(const char *) used too small a menu item + label buffer and didn't do bounds checking. + - Eliminate some compiler warnings with CodeWarrier + under WIN32 (Paul Chambers) + - Fl_Gl_Window widgets did not resize properly under + MacOS X. + - The cursor could be set for the wrong window in the + text widgets. + - Fl_Check_Browser didn't provide const char * add + methods as documented. + - Fl_Check_Browser didn't draw the same style of check + marks at the other widgets. + - Fl_Button, Fl_Choice, and Fl_Menu_Button incorrectly + activated the button/menu when the spacebar was + pressed in conjunction with shift, control, alt, or + meta. + - FLTK should now compile with Xft 2.0. + - Some versions of Tru64 4.0 have snprintf and + vnsprintf, but don't have the prototypes for those + functions. + - FLTK had trouble doing character composition with some + keyboard layouts under X11 (in particular, Belgian). + - Fl_Text_Editor would cause a segfault if the user + pressed CTRL-V (paste) without having any data in the + clipboard... + - The tab key moved backwards in menus instead of + forwards. Shift-tab still moves backwards. + - The redraw_label() method didn't damage the parent + window when the label was outside the widget's + bounding box. + - Added a "draw_children()" method to Fl_Group to make + subclassing Fl_Group with a custom draw() function + easier. + - Fl_Text_Editor now supports basic undo functionality. + - FLUID now uses Fl_Text_Editor widgets for all + multi-line code fields. + - Added new widget bin and icons to FLUID. + - FLUID would try running multiple commands in parallel, + even though it wasn't capable of handling it. + - FLUID didn't generate code for some attributes when + using custom/named widget classes. + - Added a new FL_COMMAND state bit which maps to FL_CTRL + on X11 and WIN32 and FL_META on MacOS. + - MacOS keyboard modifiers mapping corrections. Cmd and + Control are no longer swapped, event_key and event_text + return (mostly) the same values as on other platforms. + - The Fl_Tabs widget should no longer be a focus hog; + previously it would take focus from child widgets. + - The file chooser now activates the OK button when + opening a directory in directory selection mode. + - Fixed a bug in the file chooser when entering an + absolute path. + - Back-ported some FLTK 2.0 tooltip changes to eliminate + erroneous tooltip display. + - MacOS windows were resizable, even when size_range + would not allow for resizing. + - Fl_Text_Editor now supports Shift+Delete, Ctrl+Insert, + and Shift+Insert for cut, copy, and paste, + respectively. + - Fl_Text_Display didn't restore the mouse pointer when + hidden. + - Fl::arg() now ignores the MacOS X -psn_N_NNNNN option. + - Added another change to the WIN32 redraw handling for + the MingW compilers. + - Fl_File_Chooser didn't handle WIN32 home directories + that used backslashes instead of forward slashes. + - Fl_Text_Display didn't limit the resize height to 1 + line. + - Fl_Scrollbar widgets incorrectly took keyboard focus + when clicked on. This caused widgets such as + Fl_Text_Display to hide the cursor when you scrolled + the text. + + +CHANGES IN FLTK 1.1.1 + + - Fl_Text_Display didn't always show the cursor. + - Fl_Tabs now only redraws the tabs themselves when + making focus changes. This reduces flicker in tabbed + interfaces. + - The WIN32 redraw handler now correctly merges the FLTK + and Windows redraw regions. + - The Fl_Text_* widgets use the C++ bool type, which is + not supported by older C++ compilers. Added a + configure check and workaround code for this. + - Fl_X::set_xid() didn't initialize the backbuffer_bad + element that was used with XDBE. + - Fl_Shared_Image::uncache() was not implemented. + - Fl::set_font() didn't 0-initialize all font descriptor + data. + - Some OpenGL implementations don't support single- + buffered visuals. The Fl_Gl_Window class now emulates + single-buffered windows using double-buffered + windows. + - Added a workaround for a compiler bug in Borland C++ + that prevented Fl_Help_View.cxx from compiling. + - Checkmarks didn't scale properly; copied the 2.0 check + mark code over. + - Replaced several memcpy's with memmove's for + portability (memmove allows for overlapping copies, + memcpy does not) + - Bug #621737: Fl_Bitmap::copy(), Fl_Pixmap::copy(), and + Fl_RGB_Image::copy() now range-check the new width and + height to make sure they are positive integers. + - Bug #621740: the WIN32 port needed to handle WM_MOUSELEAVE events + in order to avoid problems with tooltips. + - Fl_PNM_Image didn't set the "alloc" flag for the data, + which could lead to a memory leak. + - fl_filename_match() was inconsistently doing case- + insensitive matching. + - Fl_Button redraw fix for bug #620979 (focus boxes and + check buttons). + - Fl_Text_Display fix for bug #620633 (crash on + redisplay). + - Fl_Output now calls its callback when the user clicks + or drags in the widget. + - Shortcuts now cause buttons to take focus when visible + focus is enabled. + - fl_filename_relative() didn't check that the path was + absolute under WIN32. + - fl_filename_relative() didn't check that the path was + on the current drive under WIN32. + - The Fl_BMP_Image class now handles 16-bit BMP files + and BMP files with a transparency mask. + - The fltk-config script didn't add the required include + path, if any, when compiling a program. + - Added a license clarification that the FLTK manual is + covered by the same license as FLTK itself. + - Fl_Check_Browser wasn't documented. + - Fl_Preferences::Node::addChild(), deleteEntry(), and + remove() didn't set the "dirty" flag. + - The "no change" button didn't work in the FLUID widget + panel. + - Vertical scrollbars did not draw the arrows inactive + when the scrollbar was inactive. + + +CHANGES IN FLTK 1.1.0 + + - Documentation updates. + - Added a Fl_Widget::redraw_label() method which flags a + redraw of the appropriate area. This helps to + eliminate flicker when updating the value of a widget. + - Fl_Wizard::value() now resets the mouse cursor to the + window's default cursor. + - Fl_File_Chooser::type() didn't enable/disable the new + directory button correctly. + - Fl_Preferences::entryExists() did not work properly. + - FLUID's image file chooser pattern was incorrect. + - Fl_File_Icon::load_system_icons() now detects KDE + icons in /opt/kde, /usr/local, and /usr automatically, + and supports the KDEDIR environment variable as well. + - Submenus now display to the left of the parent menu if + they won't fit to the right. Previously they would + display right on top of the parent menu... + - Fl_Menu_:add() didn't handle a trailing "\" character + gracefully. + - Clicking/dragging the middle mouse button in a + scrollbar now moves directly to that scroll position, + matching the behavior of other toolkits. + - Added some more range checking to the Fl_Text_Display + widget. + - The editor demo did not correctly update the style + (syntax highlighting) information. + + +CHANGES IN FLTK 1.1.0rc7 + + - Updated the Fl_Text_Buffer and Fl_Text_Display classes + to be based on NEdit 5.3 (patch from George Garvey). + - Fixed a problem with Fl::wait(0.0) on MacOS X 10.2; + this affected the fractals demo and other OpenGL + applications. + - Fl_Glut_Window now takes keyboard focus and handles + shortcut events. + - The MacOS X implementation of fl_ready() now checks + the event queue for events. + - Fl_PNM_Image now supports the XV/GIMP thumbnail format + (P7). + - Fl_Preferences would not find groups inside the root + group. + - Small bug fixes for Fl_Chart, Fl_Scrollbar, Fl_Tabs, + and FLUID from Matthew Morrise. + - Fl_Chart didn't have its own destructor, so data in + the chart wasn't freed. + - Fl_Menu_Button no longer responds to focus or keyboard + events when box() is FL_NO_BOX. + - FLTK convenience dialogs put the buttons in the wrong + order. + - Fl_BMP_Image didn't load 4-bit BMP files properly. + - Minor tweeks to the WIN32 DLL support. + - Fl_Text_Display::resize() could go into an infinite + loop if the buffer is emptied. + - Fl::handle() didn't pass FL_RELEASE events to the + grab() widget if pushed() was set (for proper menu + handling...) + - DND events were being sent to the target window + instead of the target widget under WIN32. + - The newest Cygwin needs the same scandir() handling as + HP-UX. + - FLUID didn't register the image formats in the + fltk_images library, and had some other image + management problems. + - Fixed one more redraw bug in Fl_Browser_ where we + weren't using the box function to erase empty space in + the list. + - Fl_Text_Display::buffer() now calls resize() to show + the buffer. + - Fl_Help_View didn't support HTML comments. + - Fl_Help_View didn't include the extra cellpadding when + handling colspan attributes in cells. + - Fl_Help_View didn't support table alignment. + + +CHANGES IN FLTK 1.1.0rc6 + + - Documentation updates. + - Fl::handle() didn't apply the modal tests for + FL_RELEASE events, which caused Fl_Tabs to allow users + to change tabs even when a modal window was open. + - Fl_Browser_, Fl_Input_, Fl_Slider now use the box + function to erase the background. This fixes some + long-standing redraw problems. + - More snprintf/strlcpy/strlcat changes where needed. + - Fl::get_font_name() would leak 128 bytes. + - Eliminated most of the "shadowed" variables to avoid + potential problems with using the wrong copy of "foo" + in a class method. + - Moved Fl_BMP_Image, Fl_GIF_Image, and Fl_PNM_Image to + the fltk_images library, so the only image formats + that are supported by the core library are XBM and XPM + files. This reduces the size of the FLTK core library + by about 16k... + - The Fl_Text_Display::resize() method was incorrectly + flagged as protected. + - Fixed some memory/initialization bugs in + Fl_File_Chooser that valgrind caught. + - The PNG library png_read_destroy() is deprecated and + does not free all of the memory allocated by + png_create_read_struct(). This caused a memory leak in + FLTK apps that loaded PNG images. + - Added uncache() method to Fl_Image and friends. + - Added image() methods to Fl_Menu_Item. + - Added default_cursor() method and data to Fl_Window. + - Fl_Group would send FL_ENTER events before FL_LEAVE + events, causing problems with adjacent widgets. + - Fixed filename problems with Fl_File_Chooser - + changing the filename field directly or choosing files + from the root directory could yield interesting + filenames. + - Fl_Input_ could crash if it received an empty paste + event. + - The mouse pointer now changes to the I beam + (FL_CURSOR_INSERT) when moved over an input field or + text widget. + - "make install" didn't automatically (re)compile the + FLUID executable. + - Added an Fl::get_boxtype() method to get the current + drawing function for a specific box type. + - Fl_Output and Fl_Multiline_Output didn't prevent + middle-mouse pastes. + - Fl_JPEG_Image didn't compile out-of-the-box with Cygwin + due to a bug in the Cygwin JPEG library headers. + - Fl_BMP_Image still didn't work with some old BMP files. + - "make distclean" didn't really clean out everything. + - Tweeked the look of the check button with a patch from + Albrecht Schlosser. + + +CHANGES IN FLTK 1.1.0rc5 + + - Added "wrap" type bit to Fl_Input_, so you can now + have a multiline text field that wraps text. + - Setting the value() of an output text field no longer + selects the text in it. + - Output text fields now show a caret for the cursor + instead of the vertical bar. + - The newButton and previewButton widgets are now public + members of the Fl_File_Chooser class. This allows + developers to disable or hide the "new directory" and + "preview" buttons as desired. + - Added new visible focus flag bit and methods to + Fl_Widget, so it is now possible to do both global and + per-widget keyboard focus control. + - Removed extra 3 pixel border around input fields. + - No longer quote characters from 0x80 to 0x9f in input + fields. + - Improved speed of Fl_Browser_::display() method with + large lists (patch from Stephen Davies.) + - Fl_Help_View didn't properly handle NULL from the link + callback (the original filename/directory name were + not preserved...) + - Fl_Help_View didn't use the boxtype border values when + clipping the page that was displayed. + - Added first steps to CodeWarrior/OS_X support (see + fltk-1.1.x/CodeWarrior/OS_X.sit) + - Cleaned up the WIN32 export definitions for some of + the widget classes. + - Fixed a filename completion bug when changing + directories. + - Fl_File_Chooser::value() would return directories with + a trailing slash, but would not accept a directory + without a trailing slash. + - When installing shared libraries, FLUID is now linked + against the shared libraries. + - MacOS: missing compile rule for .dylib files. + - Fl_Group::current(), Fl_Group::begin(), and + Fl_Group::end() are no longer inlined so that they are + properly exported in DLLs under WIN32. Similar + changes for all static inline methods in other + classes. + - MacOS: support for Mac system menu (Fl_Sys_Menu_Bar) + - MacOS: wait(0) would not handle all pending events + - Added new makeinclude file for MingW using GCC 3.1.x. + - Fl_Choice::value(n) didn't range check "n". + - The MingW and OS/2 makeinclude files didn't have the + new fltk_images library definitions. + - Fl_Text_Editor didn't scroll the text in the widget + when dragging text. + - Config header file changes for Borland C++. + - FLTK didn't provide a Fl::remove_handler() method. + + +CHANGES IN FLTK 1.1.0rc4 + + - Added new filter_value() methods to Fl_File_Chooser to + get and set the current file filters. + - Added support for custom filters to Fl_File_Chooser. + - Added Borland C++ Builder IDE project files from + Alexey Parshin. + - Resource leak fixes under WIN32 from Ori Berger. + - Now register a WIN32 message for thread messages. + - Fl_Window didn't initialize the min and max window + size fields. + - The JPEG and PNG image classes have been moved to the + fltk_images library, a la FLTK 2.0. You can register + all image file formats provided in fltk_images using + the new fl_register_images() function. + - Fl_XBM_Image didn't correctly load XBM files. + - MacOS: Added Greg Ercolano's file descriptor support. + - MacOS: Fixed text width bug. + - A change in fl_fix_focus() broken click-focus in FLWM. + - Cygwin with -mnocygwin didn't like the FL/math.h + header file. + - Fl_Browser_ cleared the click count unnecessarily. + - MacOS: Pixmap draw fix, gl_font implemented + FL_FOCUS fix, window type fix for modal and nonmodal + windows, glut uninitialised 'display' proc fix + - Now support FLTK_1_0_COMPAT symbol to define + compatibility macros for the old FLTK 1.0.x function + names to the 1.1.x names. + - Now translate the window coordinates when a window is + shown, moved, or resized. This should fix the "menus + showing up at the wrong position" bug under XFree86. + - Fixed some more problems with the Fl_BMP_Image file + loader. + - BC++ fixes. + - The pixmap_browser demo didn't check for a NULL image + pointer. + - Fl_File_Icon::find() now uses fl_filename_isdir() + under WIN32 to check for directories. + - Fl_File_Chooser's preview code called refcount() + on the deleted image's object. + - Fixed another problem with the Fl_BMP_Image loader. + - The fl_file_chooser() callback was being called with a + NULL filename. + - Documented that fl_push_clip() is preferred over + fl_clip(), with a corresponding source change. + - Minor changes to the MacOS X event handling code. + - Added syntax highlighting example code to the editor + test program. + - Fl_Text_Display didn't range check style buffer + values. + - Added "dark" color constants (FL_DARK_RED, etc.) + - The MacOS font code was missing definitions for + fl_font_ and fl_size_. + + +CHANGES IN FLTK 1.1.0rc3 + + - Documentation updates. + - New file chooser from design contest. + - Did some testing with Valgrind and fixed some memory + problems in Fl_Help_View::Fl_HelpView, + Fl_Menu_::remove(), Fl_Text_Display::draw_vline(), and + resizeform() (convenience dialogs). + - Fixed some redraw() bugs, and now redraw portions of + the parent widget when the label appears outside the + widget. + - The boolean (char) value methods in Fl_Preferences + have been removed since some C++ compilers can't + handle char and int value methods with the same name. + - Added fl_read_image() function. + - Fixed Fl_Valuator::format() so that the correct format + type is used when step == 1.0. + - Fl_Help_View didn't support the TT markup. + - Fl_Shared_Image used a double-pointer to the image + handler functions, which was unnecessary and + unintuitive. + - Fl_PNM_Image didn't load the height of the image + properly. + - Fl_BMP_Image, Fl_JPEG_Image, Fl_PNG_Image, and + Fl_Shared_Image didn't delete image data that was + allocated. + - Enabled the OpenGL and threads demos when compiling + for MingW. + - Fl_File_Input didn't update the directory buttons if a + callback was registered with the widget. + - The file chooser would return the last selected + file(s) when cancel was pressed. + - The file chooser limited the resizing of the chooser + window unnecessarily. + - Fixed WM_PAINT handling under WIN32. + - Minor tweeks to MingW and OS/2 config headers. + - Fl_Value_Input now correctly determines if step() + specifies an integer value. + - Fl_Help_View didn't add links inside PRE elements. + - OS/2 build fixes from Alexander Mai. + - Now use strlcat() instead of strncat() which could + cause buffer overflows. + - Now use of strlcpy() instead of strncpy() to simplify + the code. + - Drag-n-drop under WIN32 now shows a [+] cursor instead + of the link cursor. + - Fixed widget width tooltip and default argument + handling code in FLUID. + - Fixed colors used when drawing antialiased text using + Xft. + - Fl_Preferences::makePath() now uses access() instead + of stat() when checking to see if the destination + directory already exists. + - Fl_BMP_Image now supports older BMP files with the 12 + byte header. + - Optimized the redrawing of tabs and radio/check + buttons when the keyboard focus changes. + - More tooltip fixes. + - DND text operations would loop under X11. + + +CHANGES IN FLTK 1.1.0rc2 + + - Portability fixes. + - Backported 2.0 tooltip changes. + - Several of the valuators did not support tooltips. + - The last menu item in a menu didn't pick up on font + changes. + - FLUID now properly handles default argument parameters + properly. + - Fixed WM_PAINT handling under WIN32 - didn't validate + the correct region that was drawn. + - Fl_Multiline_Output would insert the enter key. + - Fl_File_Browser didn't clip items to the column width. + - Fl_Window::draw() cleared the window label but didn't + restore it, so windows could lose their titles. + - Eliminated multiple definitions of dirent structure + when compiling under WIN32. + - Adjusted the size of the circle that is drawn inside + radio buttons to scale better for larger labels. + - FLUID was opening the display when it shouldn't have. + - Fl_File_Chooser.cxx defined the file chooser functions + again; they should only be defined in the header file. + - Wide arcs would draw with "teeth". + - The preferences demo included Fl/Fl_Preferences.H + instead of FL/Fl_Preferences.H. + + +CHANGES IN FLTK 1.1.0rc1 + + - The fl_file_chooser() and fl_dir_chooser() functions + now support an optional "relative" argument to get + relative pathnames; the default is to return absolute + pathnames. + - The backspace and delete keys now work as expected in + the file chooser when doing filename completion. + - FLUID now supports running shell commands. + - New Fl_File_Input widget that shows directory + separators with filename in input field. + - The Fl_File_Chooser dialog now shows the absolute path + in the filename field using the Fl_File_Input widget. + - FLUID now keeps track of grid, tooltip, and other + GUI options, along with the last 10 files opened. + - Tooltip windows would show up in the task bar under + WIN32. + - Now append trailing slash to directory names in names + in WIN32 version of scandir(). This takes care of a + file chooser performance problem with large + directories. + - Added Fl_Preferences class from Matthias Melcher, + including binary data support. + - FLUID now recognizes the "using" keyword in + declarations. + - fl_file_chooser() didn't highlight the requested file + the second time the file chooser dialog was shown. + - Fixed rendering of Fl_Light_Button with the plastic + scheme. + - Fixed a bug in the MacOS font enumeration code. + - Now show a "locked" icon next to static/private + elements in FLUID, and "unlocked" icon next to + global/public elements. + - Implemented Fl_Menu_Item image labels using older + 1.0.x labeltype method. + - Updated the PNG library check to support both png.h + and libpng/png.h. + - Fixed a recursion bug in tooltips that was causing + random crashes. + - fl_file_chooser() could cause a segfault when passed a + NULL filename parameter in some situations. + - Added a "-g" option to fltk-config to support quick + compiling with debugging enabled. + - Fixed redraw problem with Fl_Input and anti-aliased + text. + - Added threading support for MacOS X and Darwin. + - The filesystem list in the file chooser now works under + MacOS X and Darwin. + - The fl_msg structure now contains all data passed to + the WndProc function under WIN32. + - Fixed some window focus/positioning problems under + MacOS X. + - Added fl_create_alphamask() function to create an alpha + mask from 8-bit data; currently this always generates a + 1-bit screen-door bitmask, however in the future it will + allow us to generate N-bit masks as needed by various + OS's. + - Fl_File_Browser::load() didn't properly show drives + when compiled in Cygwin mode. + - Now pass correctly pass keyboard and mouse events to + widget under tooltip as needed... + - Added new Fl::dnd_text_ops() methods to enable/disable + drag-and-drop text operations. + - Fl_Input now supports clicking inside a selection to + set the new text position when drag-and-drop is + enabled. + - Added support of X resources for scheme, dnd_text_ops, + tooltips, and visible_focus... + - Fixed some case problems in includes for the MacOS X + code. + - Fl_Widget::handle() returned 1 for FL_ENTER and + FL_LEAVE events, which caused some compatibility + problems with 1.0 code. + - Fl_Box::handle() now returns 1 for FL_ENTER and + FL_LEAVE events so that tooltips will work with Fl_Box + widgets. + - Some source files still defined strcasecmp and + strncasecmp under WIN32. + - Some source files still used the "false" and "true" + C++ keywords, even though several of our "supported" + C++ compilers don't support them. Using 0 and 1 until + FLTK 2.0 (which uses the bool type instead of int for + any boolean values...) + - Minor Fl_Color revamping, so that color constants map + to the color cube and FL_FOREGROUND_COLOR, + FL_BACKGROUND_COLOR, FL_BACKGROUND2_COLOR, + FL_INACTIVE_COLOR, and FL_SELECTION_COLOR map to the + user-defined colors. + + +CHANGES IN FLTK 1.1.0b13 + + - Fixed a bug in the Xft support in Fl_Window::hide() + (the config header wasn't included, so the Xft code + wasn't getting called) + - Xdbe support must now be enabled explicitly using + --enable-xdbe due to inconsistent bugs in XFree86 and + others. + - Windows resized by a program would revert to their + original size when moved under WIN32. + - Cygwin can only compile the new WIN32 drag-n-drop code + using GCC 3.x. + - Tooltips now appear for inactive and output widgets. + - Tooltips no longer steal keyboard events other than + ESCape. + - Tooltips are no longer delayed when moving between + adjacent widgets. + - fl_beep(FL_BEEP_DEFAULT) now uses the PC speaker under + Windows (0xFFFFFFFF) rather than an event sound. + - The configure script didn't include the -mwindows or + -DWIN32 compiler options in the output of fltk-config + when using the Cygwin tools. + - Fl_Output didn't take input focus when needed, so it + was unable to support CTRL-C for copying text in the + field and did not unhighlight selections when the + widget lost focus. + - The fl_filename_name() function didn't handle a NULL + input string. + - The input field used by the fl_input() and + fl_password() functions was resized too small in + 1.1.0b12. + - Added casts in fl_set_fonts_win32.cxx for VC++ 5.0. + - Fl_File_Icon::find() did not check the basename of a + filename for a match; this caused matches for a + specific filename (e.g. "fluid") to fail. + - The Fl_Shared_Image class now supports additional + image handling functions - this allows you to support + additional image file formats transparently. + + +CHANGES IN FLTK 1.1.0b12 + + - Documentation updates. + - Fl_Choice didn't clip the current value properly - it + wasn't accounting for the box border width. + - The forms compatibility functions are now placed in a + "fltk_forms" library to match FLTK 2.0. + - Renamed down() and frame() to fl_down() and + fl_frame(), filename_xyz() to fl_filename_xyz(), and + all of the define_FL_FOO() functions for the custom + boxtypes to fl_define_FL_FOO() to avoid namespace + clashes. + - Stereo OpenGL support (patch from Stuart Levy) + - All of the convenience functions defined in fl_ask.H + now resize the widgets and dialog window as needed for + the labels and prompt. + - Backported FLTK 2.0 dual cut/paste buffer code. + - Added support for Xft library to provide anti-aliased + text on X11. + - Fl_Help_View didn't keep track of the background color + of cells properly. + - Fl_Browser::item_width() didn't compute the width of + the item properly when column_widths() was set. + - Fl_Button didn't check to see if the widget could + accept focus before taking input focus. + - Fl_Help_View didn't preserve target names (e.g. + "filename.html#target") when following links. + - Drag-and-drop support for MacOS. + - Updated MacOS issues documentation. + + +CHANGES IN FLTK 1.1.0b11 + + - Now conditionally use the WIN32 TrackMouseEvent API + (default is no...) + - Fixed a table rendering bug in the Fl_Help_View + widget. + - The fltk-config script now recognizes all common C++ + extensions. + - The menu code was using overlay visuals when the + scheme was set to "plastic". + - Fixed some drawing problems with Fl_Light_Button and + its subclasses. + - Fixed a minor event propagation bug in Fl_Group that + caused mousewheel events to be passed to scrollbars + that were not visible. + - The fl_file_chooser() function did not preserve the + old file/directory like the old file chooser did. + - The prototypes for fl_input() and fl_password() did + not default the "default value" to NULL. + - Fl_Tabs now draws tabs using the selection_color() of + the child groups; this allows the tabs to be colored + separately from the body. Selected tabs are a mix of + the Fl_Tabs selection_color() and the child group's + selection_color(). + - Fl_Tabs didn't include images in the measurement of + the tabs if no label text was defined. + - The WIN32 code didn't return 0 from the window + procedure after handling WM_PAINT messages. + - fl_draw() would incorrectly test the clipping of + labels the lay outside the bounding box. + - filename_relative() didn't always return the correct + relative path. + - Updated the test makefile to work with more versions + of "make". + - Added new "--with-optim" configure option to set the + optimization flags to use when compiling FLTK. + - The fltk-config script no longer reports the + optimization flags that were used to compile FLTK. + - Initial port of FLTK 2.0 drag-and-drop support. + + +CHANGES IN FLTK 1.1.0b10 + + - Fixed the new WIN32 TrackMouseEvent code. + - Fixed the VC++ project files to link against + comctl32.lib. + + +CHANGES IN FLTK 1.1.0b9 + + - Better FL_LEAVE event handling for WIN32. + - The alpha mask was bit-reversed. + - Fl::scheme() applied the scheme tile image to overlay + and menu windows, which caused problems when the + overlay planes were in use. + - Fixed Fl::event_button() value when hiding tooltip on + some systems. + - Added Fl_BMP_Image class to support loading of Windows + bitmap (BMP) files. + - The shiny demo didn't work on some systems (no + single-buffered OpenGL visual), and the new box types + were reset when show(argc, argv) was called. + - Fl::scheme() didn't update windows that were not + shown. + - The fractals demo would get far ahead of the UI with + some Linux OpenGL drivers. Now use glFinish() instead + of glFlush() so we are at most 1 frame ahead. + - The fractals demo Y axis controls were backwards for + the "flying" mode. + - MacOS: cleaned up src/Fl_mac.cxx + - MacOS: fixed Fl::wait(0.0), fixed Cmd-Q handling + - Update CygWin support for Fl::add_fd(). + - Update the plastic scheme to not override the default + colors - move the color code to the MacOS-specific + code. Also updates the tile image colormap to match + the current background color. + - Add fl_parse_color() to X11 as well, removing a bunch + of conditional code and providing a common interface + for looking up color values. + - Fixed the make problems in the test directory - some + make programs had trouble handling the recursive + dependencies on the FLUID files... + - Now use rint() to round floating-point coordinates. + - Demo cleanup - made sure they all worked with schemes. + - Fl_Tabs no longer clears the unused area of the tab + bar. + - Added show(argc, argv) method to Fl_Help_Dialog. + - MacOS: implemented cut/copy/paste. + - MacOS: improved keyboard handling, fixed keyboard + focus handling, fixed get_key, modified 'keyboard' + demo to show second mouse wheel and additional keys + 'help' and FL_NK+'=' + + +CHANGES IN FLTK 1.1.0b8 + + - OS/2 build fixes. + - fl_draw() didn't ignore symbol escapes properly for + the browsers... + - New Fl::scheme() methods from FLTK 2.0; currently only + the standard ("") and plastic ("plastic") methods are + supported. Schemes can be set on the command-line + ("-scheme plastic") or using the FLTK_SCHEME + environment variable. + - MacOS: fixed iBook keyboard handling, moved + remaining message handling to Carbon, added mouse + capture support, added timer support, added overlay + support, fixed double-buffering side effects. + - The configure script wasn't using the -fpermissive or + -fno-exceptions options with GCC. + - Fl_JPEG_Image and friends didn't set the depth if the + image file couldn't be loaded; since Fl_RGB_Image + didn't check for this, it could fail when displaying + or copying these images. + - filename_absolute() did not always free its temporary + buffer. + - filename_relative() did not do a case-insensitive + comparison under MacOS, OS/2, and Windows. + - filename_isdir() didn't properly handle "D:L" under + WIN32. + - Fl_Shared_Image::get() did not check to see if the + image could not be loaded. + - Fl_Help_View didn't clear the line array in the + Fl_Help_Block structure; this causes erratic + formatting for some pages. + - The font and size members of Fl_Help_Block were never + used. + - The threading functions (Fl::lock() and friends) were + not exported under WIN32. + - The Fl_Text_Display destructor deleted the scrollbars + twice... + - Fl_Help_View didn't reset the horizontal scroll + position when showing a new page. + - Fl_Pack now allows any child widget to be the + resizable() widget, not just the last one. + - MacOS: opaque window resizing, all events except + Mac menus are now handled using Carbon, window + activation fixed, GL_SWAP_TYPE default changed to + make gl_overlay work. + - Fl_Help_View::resize() didn't resize the horizontal + scrollbar. + - MacOS: list all fonts, fixed clipping and mouse + pointer bugs. + - The Fl_File_Chooser widget now uses hotspot() to + position the dialog under the mouse pointer prior to + showing it. + - Added a configure check for *BSD - use -pthread option + instead of -lpthread. + - Fl_Text_Display could get in an infinite loop when + redrawing a portion of the screen. Added a check for + the return value from fl_clip_box() so that the + correct bounding box is used. + - Removed the Fl_Mutex and Fl_Signal_Mutex classes from + the threads example, since they weren't being used + and apparently are not very portable. + - Fl_Help_View now ignores links when the link callback + returns NULL, and displays a sensible error message + when an unhandled URI scheme is used (e.g. http:, + ftp:) + - Fl_File_Icon::load_system_icons() no longer complains + about missing icon files, just files that exist but + can't be loaded. + - FLUID didn't list the plastic box and frame types. + - Now hide the tooltip window whenever a window is + hidden. Otherwise a tooltip window could keep an + application running. + - Updated FLUID to only append a trailing semicolon to + code lines in a callback (so "#include" and friends + will work...) + - The Fl_Color_Chooser widget now supports keyboard + navigation. + - Fixed button and valuator widgets to call Fl::focus() + instead of take_focus(). + - Tweeked the radio button drawing code for better + circles with different boxtypes. + - The Fl_File_Chooser widget did not provide a shown() + method, and fl_file_chooser() and fl_dir_chooser() did + not wait on shown(); this would cause them to return + prematurely if you switched desktops/workspaces. + - Cosmetic changes to plastic boxtypes. Now look much + better for large areas and the buttons now have a much + greater "3D" feeling to them. + - Added new Fl::draw_box_active() method so that + boxtypes can find out if the widget they are drawing + for is active or not. + - Fl_Button and its subclasses did not redraw the parent + when the boxtype was FL_NO_BOX and they lost keyboard + focus (the parent redraw clears the focus box.) + - Fixed the example program makefile - wasn't building + the mandelbrot and shiny demos right. + - Fl::set_font(Fl_Font, Fl_Font) was not implemented. + - Fixed the documentation Makefile commands; was not + using the fltk.book file for some reason... + + +CHANGES IN FLTK 1.1.0b7 + + - More documentation updates... + - Mac OS X support works 95% + - The Fl_Window::hotspot() off-screen avoidance code was + commented out. + - Mac OS X uses mostly Carbon event handling to support + Mousewheel, three buttons, all modifier keys, etc. + - Updated paragraph 4 of the FLTK license exceptions; + there was some question about the requirement to show + that a program uses FLTK, which is required by section + 6 of the LGPL. The new exemption specifies that + inclusion of the FLTK license is not required, just a + statement that the program uses FLTK. + - Fl_Button::handle() was calling take_focus() for both + FL_PUSH and FL_DRAG. + - File and memory fixes for Fl_GIF_Image, Fl_PNG_Image, + Fl_PNM_Image, Fl_Shared_Image, Fl_Tiled_Image, and + Fl_XBM_Image. + - filename_match() didn't handle backslashes properly + under WIN32, and didn't use a case-insensitive + comparison under MacOS X. + - The Fl class was missing access methods for the + FL_MOUSEWHEEL event values - Fl::event_dx() and + Fl::event_dy(). + - The default help string didn't include the -nokbd + option. + - "make uninstall" didn't uninstall the static OpenGL + widget library. + - Mac cursor shapes added... + - Fl_Text_Display would lockup when all text was + deleted; for example, when running the editor + demo, you couldn't load a second file. + - Added Fl::lock() and friends from FLTK 2.0 to + support multi-threaded applications; see the + "threads" demo for an example of this. + - Fl_Check_Button and Fl_Round_Button now use the + FL_NO_BOX box type to show the background of the + parent widget. + - Tweeked the plastic boxtype code to draw with the + right shading for narrow, but horizontal buttons. + - Fl_Progress now shades the bounding box instead of + drawing a polygon inside it. + - Fl::warning() under WIN32 defaults to no action. This + avoids warning dialogs when an image file cannot be + loaded. + - Some Win32 drivers would draw into wrong buffers + after OpenGL mode change + - The file chooser would cause a segfault if you + clicked in an empty area of the file list. + - Fl_File_Icon::labeltype() would cause a segfault + if the value pointer was NULL. + - Fl_File_Icon::load_image() could cause segfaults + (NULL data and incrementing the data pointer too + often.) + - Fl_File_Icon::load_image() now handles 2-byte + per color XPM files. + - Some Win32 drivers would draw into wrong buffers + after OpenGL mode change. + - Message handling and Resources for MacOS port. + - Fl_Help_View could get in an infinitely loop when + determining the maximum width of the page; this + was due to a bug in the get_length() method with + percentages (100% width would cause the bug.) + - Don't need -lgdi32 for CygWin, since -mwindows + does this for us. + - The WIN32 event handler did not properly handle + WM_SYNCPAINT messages. + - Fl_Tabs now uses the boxtype exclusively to draw + both the tabs and surrounding box, so alternate + box types actually work and the look is a little + nicer. + - Fixed the drawing of large areas with the new + plastic boxtypes. + - Updated the Visual C++ demo projects to use FLUID + to generate the GUI files as needed. + - The demo program didn't load the right menu file + when compiled for debugging under WIN32. + - Added plastic box types to forms demo. + - Added mousewheel to keyboard demo. + - The Fl_Text_Editor widget caused an infinite loop + when it received keyboard focus. + - filename_isdir() didn't properly handle drive letters + properly; WIN32 needs a trailing slash for drive + letters by themselves, but cannot have a trailing + slash for directory names, go figure... + - The Fl_Text_Buffer and Fl_Text_Display classes did not + initialize all of their members. + - fl_normal_label() had a totally redundant set of + if/else tests, which the new code handles all from + fl_draw(). + - The Fl_File_Chooser dialog contained two hotspots. + - The fl_draw_pixmap() function didn't free the 2-byte + color lookup table properly (delete instead of + delete[]). + - fl_draw() reset the text color under WIN32, causing + bitmaps to draw incorrectly. + - Fl::get_font_sizes() is now implemented under WIN32. + - Fl_Text_Display now uses the same default colors for + selection and text as Fl_Input_ and friends. + - Changed the default line scrolling in Fl_Text_Display + to 3 lines for the mouse wheel and scrollbar arrows. + + +CHANGES IN FLTK 1.1.0b6 + + - Documentation updates... + - The configure script now works within the CygWin + environment. + - Tooltips are now enabled by default, but are not + re-enabled when calling the Fl_Widget::tooltip() + method. + - Added new Fl::version() method to get the current + FLTK library version (for shared libraries/DLLs) + - Added new Fl::event() method to get the current + event that is being processed. + - Added new fl_beep() function to do audible + notifications of various types. + - Added new Fl_GIF_Image, Fl_JPEG_Image, Fl_PNG_Image, + Fl_PNM_Image, Fl_XBM_Image, and Fl_XPM_Image classes. + - Added new Fl_Shared_Image class, a la FLTK 2.0. + - Added new Fl_Tiled_Image class for tiled backgrounds. + - Added new copy(), desaturate(), inactive(), and + color_average() methods to the Fl_Image classes. + - Added a horizontal scrollbar to the Fl_Help_View + widget. + - Added new FL_PLASTIC_{UP/DOWN}_{BOX/FRAME} boxtypes + for a more "modern" look (sort of a cross between KDE + 2.2 and Aqua.) + - Fl_Float_Input and Fl_Int_Input no longer accept + pasted text that is not a floating point or integer + value. Pasted numbers now replace text in these + widgets. + - Implemented the Fl_File_Icon::load_png() method. + - The Fl_File_Icon::load_system_icons() method now + supports KDE 2.x icons. + - Fixed PNG support in Fl_Help_View. + - Removed the "Microsoft" mode button from the menubar + demo. + - The browser demo now makes sure that the input field + contains a number. + - The Fl_Browser::make_visible() method now range checks + the input. + - Updated the fl_draw() and fl_measure() methods to + accept an optional draw_symbols argument, which + controls whether symbols are drawn in the text. + - Added new Fl::visible_focus() methods to control + whether the focus box is drawn. + - The focus box is now drawn using the contrast color. + - Fl_Repeat_Button didn't accept keyboard focus. + - Added new Fl::visible_focus() method and standard + "-kbd" and "-nokbd" options in Fl::args() processing + to control whether keyboard focus is shown and handled + by non-text widgets. + - The wrong tooltip could be shown if the user moved the + mouse over adjacent widgets with tooltips. + - The drop-down button on Fl_Choice widgets was not + limited in width. + - Tooltips could appear off the screen. + - Mouse wheel events are now sent to the focus widget + first, then to any other interested widget. + - The Fl_RGB_Image class now supports images with an + alpha channel. Images are currently drawn using + "screen door" transparency... See the "image" demo + for an example. + - Added new fl_create_bitmask() and fl_delete_bitmask() + functions that create bitmap objects for masking and + bitmap drawing. + - Was sending FL_RELEASE events for buttons 4 and 5 + under X11, which are only for FL_MOUSEWHEEL. + - Fl_Help_View now supports the EM and STRONG elements. + - Didn't do callbacks when changing tabs via keyboard. + - FLUID didn't write tooltip strings to the message + catalog file. + - Fl_File_Icon now uses Fl_Shared_Image to load icon + images; the load_png() and load_xpm() methods have + been replaced by a single load_image() method. + - Fl_File_Icon::load_system_icons() now does a better + job of finding KDE icons. + - Now use Fl::warning() and Fl::error() in place of + printf's in some of the newer widgets. + - The default behavior of Fl::error() is now to display + an error but not to exit; Fl::fatal() still exits. + - FLUID now uses the Fl_Shared_Image class, so FLUID- + generated GUIs can embed any of the supported image + file formats. + - New filename_relative() function to convert an + absolute filename to a relative one. + - Updated the filename_absolute(), filename_expand(), + and filename_setext() functions to take the + destination string size, with inline functions for the + old FL_PATH_MAX size. + - fl_file_chooser() and fl_dir_chooser() now return a + relative path. + - Fl_Help_View now supports all ampersand escapes. + + +CHANGES IN FLTK 1.1.0b5 + + **** NOTE: DUE TO CHANGES IN THE WIDGET CLASSES, **** + **** YOU MUST RECOMPILE ALL SOURCE FILES **** + **** THAT USE FLTK!!! **** + + - All FLTK color values are now 32-bits and support + both the legacy 8-bit color values as well as 24-bit + RGB values (0xRRGGBB00 for 24-bit RGB, 0x000000II + for indexed color). + - Fl::set_boxtype() and fl_internal_boxtype() now keep + track of when a boxtype is changed; this allows you to + override the "special" boxtypes without references to + those boxtypes causing them to be reset. + - Fl_Help_Func now takes a Fl_Widget pointer as well as + a pathname. + - Added code to support FL_KEYUP events. + - Focus did not return to the Fl_Text_Display and Editor + widgets when scrolling and then clicking inside the + editor window. + - Now set the line size of the vertical scrollbar in the + text editor to 1. + - The symbols demo didn't show the strings needed to + show the corresponding symbol (the label string was + not quoted...) + - FLTK should now compile with Cygwin cleanly. + - Shortcut changes were not being saved by FLUID. + - FLUID didn't write the deimage() static data. + + +CHANGES IN FLTK 1.1.0b4 + + **** NOTE: DUE TO CHANGES IN THE FL_WIDGET CLASS, **** + **** YOU MUST RECOMPILE ALL SOURCE FILES **** + **** THAT USE FLTK!!! **** + + - Updated the flags_ member of Fl_Widget to be an + integer instead of uchar, to support the new + FL_OVERRIDE flag for Fl_Window. + + - The parent() method of Fl_Widget now uses pointers to + Fl_Group instead of Fl_Widget. + + - Fl_Window now provides the FLTK 2.0 "override()" and + "set_override()" methods for windows. + + - Added a configure check (and warning) for GCC 3.0.x. + + - Updated the configure script to check for the + png_set_tRNS_to_alpha() function. + + - Updated the config.h files for all platforms for the + image and FLTK documentation defines. + + - Updated the makeinclude files for all platforms to + match the current makeinclude.in file. + + - FLUID would crash if you cleared an image for a + widget. + + - Fl_Help_View::add_image() did not initialize the image + member of the base (unscaled) image. + + - Fl_Help_View didn't support A elements with both a + NAME and HREF attribute - the HREF was ignored. + + - Miscellaneous compile warning fixes. + + - Tooltips were being reset by Fl::belowmouse(), which + caused problems with the FLUID main window (flashing + tooltip windows and serious problems with KDE 2.2) + + - The editor demo had the save and discard button + actions reversed. + + - The Fl_Help_View widget now uses + png_destroy_read_struct() if the older + png_read_destroy() function is not available. + + - The WIN32 DLL library now includes the OpenGL widgets. + This is a simpler solution for the export/import + dillemma under WIN32, as OpenGL and non-OpenGL symbols + need to be exported at different times with the + separate library scheme. Since OpenGL is standard + under Windows, this is less of a problem than under + UNIX... + + +CHANGES IN FLTK 1.1.0b3 + + - The top-level makefile did not include the makeinclude + file, causing the fltk-config installation commands to + fail. + + - The fl_file_chooser.cxx source file conflicted with + Fl_File_Chooser.cxx under Windows. Similarly, the + fl_file_chooser.H header file conflicts with the + Fl_File_Chooser.H header file. + + - Now save and restore the GDI pen object when + responding to WIN32 paint messages. + + - Documentation updates from A. Suatoni. + + +CHANGES IN FLTK 1.1.0b2 + + - New fltk-config script. + + - Fixed image/text label handling; in b1 the label + needed a non-blank text string to display the image. + This bug also caused all sorts of crashes and display + problems. + + - Added new filetype() method to Fl_FileBrowser to allow + for file or directory browsing. + + - Fixed the drawing of the focus box around + Fl_Return_Button. + + - Fixed menu item measurement bug (wasn't initializing + image pointers to 0...) + + - Radio and checkbox menu items now draw with the new + style (round radio buttons with dots and square check + buttons with check marks.) + + - Improved the appearance of Fl_Check_Button. + + - Improved the Fl_HelpView table formatting code; now + dynamically sizes the table columns, and supports + COLSPAN. + + - The FLUID keyboard shortcuts now work as expected + (CTRL-C copies, SHIFT-CTRL-C writes code, etc.) + + - The FLTK_DOCDIR environment variable can now be + used to tell FLUID where to find the on-line + documentation files. + + - FLUID now supports image labels in addition to text + labels + text over image alignment. + + - FLUID now supports tooltips. + + - The widget panel in FLUID is now tabbed, a la FLTK + 2.0. + + - The FLUID pixmap destructor tried to free 1 too many + lines of image data. + + - FLUID now provides on-line help. + + - Changed Fl_FileXYZ to Fl_File_XYZ. + + - Changed Fl_HelpXYZ to Fl_Help_XYZ. + + - Tooltip fixes for Fl_Browser_, Fl_Choice, and Fl_Input_. + + - Added tooltips to FLUID, help dialog, and file chooser. + + - Now load system icons in FLUID. + + +CHANGES IN FLTK 1.1.0b1 + + - Added new image() and deimage() methods to support + image + text labels more easily. + + - Added new alignment bit FL_ALIGN_TEXT_OVER_IMAGE. + + - Added tooltip support using Jacques Tremblay's tooltip + patch. + + - Added keyboard navigation to all widgets. + + - Added support for mouse wheels using the new + FL_MOUSEWHEEL event type. Get the mouse wheel + movement values from Fl::e_dx (horizontal) and + Fl::e_dy (vertical). + + - Added the Fl_Check_Browser, Fl_FileBrowser, + Fl_FileChooser, Fl_FileIcon, Fl_HelpDialog, + Fl_HelpView, Fl_Progress, and Fl_Wizard widgets from + the bazaar. + + - Added 2.0 Fl_Text_Display and Fl_Text_Editor widgets + based on NEdit. + + - The Fl_Choice widget now looks more line a combo box + than a Motif option menu. + + - Moved the OpenGL widgets into a separate library + called fltkgl - this eliminates shared library + dependencies on OpenGL when no OpenGL functionality is + used/required. + + - FLUID now supports the new Fl_CheckBrowser, + Fl_FileBrowser, Fl_FileIcon, Fl_HelpView, + Fl_Text_Display, Fl_Text_Editor, and Fl_Wizard + widgets. + + - Updated configure stuff to support shared libraries + under AIX (link to -lfltk_s) + + - Symbol labels can now contain regular text. + + - FLUID now supports relative filenames for the source + and header files you generate. + + - Fl_Menu_Item::add() didn't use the flags that were + passed in. + + - Fixed a bug in Fl_Scrollbar - clicking in the "trough" + of the scrollbar would move the scroller in the wrong + direction. + + - Made the Forms pixmap parameter const to match the + Fl_Pixmap.H definitions. + + - Changed the Fl_Pixmap constructor to use the explicit + keyword which should work for all C++ compilers. + + - Fl_Menu_add of a menu item with the same name as an + existing submenu title would mess up by replacing that + menu title, it now adds a new item. + + - Fl_Menu::add() of text starting with '/' to a menu is + assummed to be a filename. So "/foo/bar" creates a + single menu item. You can also put filenames into + submenus by doing "submenu//foo/bar", this will create + a submenu called "submenu" with an item "/foo/bar". + Menu items starting with "\_" will insert an item + starting with '_' rather than a divider line. These + changes make the menus compatable with fltk 2.0. + + - Another little fix for the BoXX OpenGL overlays. + + - Fl_Gl_Window no longer blanks the mouse pointer on + WIN32 unless an OpenGL overlay is being used. This + should make non-overlay displays faster when a cursor + is set. + + +CHANGES SINCE FLTK 1.0.10 + + - CHANGED THE DEFAULT RUN-TIME LINKING TO "MULTITHREADED + DLL". You'll need to change your project settings to + use this as well or you'll get errors. + + - Added new --disable-gl option to configure script. + + - Added new const const pointer versions of pixmap + functions to eliminate an annoying pointer warning + message that was generated by the Sun and other C++ + compilers. + + - Eliminated all "var hides class::var" warnings. + + - Eliminated all "string literal converted to char *" + warnings. + + - OS/2 updates from Alexander Mai. + + - Tidied up the HTML documentation to be more standards + compliant. + + - Compiling with -DBOXX_BUGS will work around some + problems with the newest X drivers that BoXX delivers, + the problems all affect use of Overlays for normal X + drawing and OpenGL drawing. Normal compilation is + unchanged. + + - The file chooser buttons use user_data() rather than + the label to decide what to do, allowing the label to + be somewhat cleaner. + + - Selection color on X changed to blue, to match what + happens on Windows now. + + - Added support for AIX (static library only). + + - Added support for SunOS 4.x + + - Now process WIN32 WM_ACTIVATEAPP message to reset the + key and button states in Fl::e_state. + + - Fl_has_idle only tested N-1 callbacks and missed one. + + - Restored WM_SYNCPAINT handling under WIN32; this fixed + a refresh bug under some versions of Windows. + + - Check for OpenGL headers before checking to see if + OpenGL is supported. This should eliminate compile + errors due to missing non-FLTK header files... + + - Add -D_INCLUDE_POSIX_SOURCE option when compiling with + the HP compilers. + + - Replaced remaining _WIN32 symbols with WIN32 + + - Removed reference to unused GL/glu.h header file, which is missing on + some Linux systems. + + - Fl_Gl_Window has a new method to allow you to get and set the context: + + void Fl_Gl_Window::context(void*, int destroy = 0) + void* Fl_Gl_Window::context() const; + + Return or set a pointer to the GLContext that this window is + using. This is a system-dependent structure, but it is portable to + copy the context from one window to another. You can also set it to + NULL, which will force FLTK to recreate the context the next time + make_current() is called, this is useful for getting around bugs in + OpenGL implementations. + + If destroy_flag is true the context will be destroyed by fltk when + the window is destroyed, or when the mode() is changed, or the next + time context(x) is called. + + - Some cleanup of Fl_Gl_Choice to move most of the system dependent + #ifdefs into Fl_Gl_Choice.cxx. + + - Fl_Gl_Window does not set drawbuffer(BACKBUFFER) for + single-buffered windows. + + - Fl_Input::replace(...) correctly updates the display + if the replaced region does not include the mark, + point, or selected region. + + - Added Fl::add_check(...), Fl::remove_check, and + Fl::has_check. These are similar to idle callbacks but + are only called just before it waits for new events. + They can be used to watch for changes in global state + and respond to them. + + - "accu-timer": some changes to repeat_timeout that seem + to make it accurate on Unix and WIN32 at speeds up to + 500000 timeouts/second (and 700000 on Linux), and + within about .001% as accurate as the system clock. + + - Fix to Fl_Valuator::step() by Guillermo Andrade. + + - Fixed the FLUID write-menu bug introduced in 1.0.10 + + - Fl::flush() now calls GdiFlush() under WIN32 to + ensure that all graphics are drawn. + + - fl_curve() now uses a much better algorithim to figure + out how many pieces to cut the curve into. + + - FLUID now uses GetTempPath() under WIN32 to determine + where to store the clipboard. + + - Right-ctrl does not delete selected text in Fl_Input, + until you type a composed character. + + - Added simple FLTK and FLUID manual pages. + + - Fl_Gl_Window leaked memory under WIN32. + + - The colbrowser demo was missing an include file when + compiled under OS/2. + + +CHANGES SINCE FLTK 1.0.9 + + - Added a strcasecmp() function to FLUID; AIX doesn't + have it. + + - Bug #115509: Fl_Scroll not repainting background. + + - Updated the configure script and makeinclude.in file + to work with the Sun PRO compilers. + + - Disabled the WIN32 async socket select code by default: + it doesn't seem to work anymore... + + - Fl::below_mouse() was incorrectly clearing e_is_click; + this prevented any double-clicks from getting + through... + + - No longer clear Fl::keysym on every event, this makes + better back compatability and fixes Win2000 + + - FLUID now restores which tab in an Fl_Tabs was + selected when loads .fl files. + + - Hack to fix the annoying "raise another application + when a modal window is closed" problem on WIN32. + + - Fl_Tabs now draws the background behind the tabs. + + - Fl::set_fonts() on WIN32 fixed to work before the + first window is shown. + + - CUA function keys, code submitted by George Yohng + + + - Another attempt to get glut.h to work on WIN32. + + - Fl_Menu_::add() ignores '&' signs when comparing menu + items, so you don't have to make the shortcuts the + same all the time. + + - Fixed bit-flipping patterns in WIN32 bitmap code. + + - Fixed size of data written by gif images to .C files + + - Menu titles and buttons in the menubar can be images + (allows it to be used as a toolbar) + + - Reads selectBackground from the xrdb database to set + the selection color. Adding this to your .Xdefaults + will make fltk and Motif programs look much more + Windoze-like: + + *selectForeground: white + *selectBackground: #000080 + + - FL_WHEN_RELEASE on Fl_Input will now do the callback + when the input field is hidden, for instance when it + is on a tab and the user switches to another tab. + + - Fl_Gl_Window with an overlay on X always resized any + child windows even if you turned resizable() off + because it turned it back on to resize the overlay + window. This patch avoids changing resizable(). + + - Fix so multiple Fl::add_idle() calls works + + - The input focus got messed up if you called + Fl_Tabs::value(x) and there was something that took + focus on an earlier tab. + + - Removed some (not all) of the warnings when compiled + with -Wwrite-strings, this should also get similar + warnings Solaris produces. + + - Made Fl_Browser not hide the Fl_Widget::show() method + + - Changes & additions for OS/2 from Alexander Mai + + - Patch from Mike Lindner to make the turning on/off of + scrollbars on Fl_Scroll smarter. + + - Added missing FL_EXPORT for Fl_Valuator::format() + + - Shortcuts for "buttons" in a Fl_Menu_Bar work again. + + - Fix for cut/paste support and Xdnd. + + - Shortcuts for submenu titles in a menubar pop up the + submenu (rather than calling the callback) + + - Added documentation for GL_SWAP_TYPE + + - Buttons with box(FL_NO_BOX) did not draw. Apparently + they did in older versions of fltk, I restored this. + (bug 108771) + + - Removed 8-bit colormap drawing code that was not doing + anything in fl_draw_image due to the colormap + allocation changes. I also made fl_color(r,g,b) + actually allocate the requested color rather than the + nearest fltk color-cube color (this is only done for + the first color that maps to a given entry in the fltk + color cube), the result is that pixmaps with a small + number of colors are drawn much more accurately. The + resulting code seems to produce better images and is a + good deal smaller! + + - Fixed makeinclude.in so CFLAGS are used for c source + code instead of CXXFLAGS. (bug 108694) + + - Better fix for gif files suggested by pauly (bug + 108770) + + - Performance of Fl_Gl_Window may be improved on some + types of OpenGL implementations, in particular MESA + or other software emulators, by setting the + GL_SWAP_TYPE environment variable. This variable + declares what is in the back buffer after you do a + swapbuffers: + + setenv GL_SWAP_TYPE COPY + + This indicates that the back buffer is copied to + the front buffer, and still contains it's old + data. This is true of many hardware + implementations. Setting this will speed up + emulation of overlays, and widgets that can do + partial update can take advantage of this as + damage() will not be cleared to -1. + + setenv GL_SWAP_TYPE NODAMAGE + + This indicates that nothing changes the back + buffer except drawing into it. This is true of + MESA and Win32 software emulation and perhaps some + hardware emulation on systems with lots of memory. + + All other values for GL_SWAP_TYPE, and not setting + the variable, cause fltk to assumme that the back + buffer must be completely redrawn after a swap. + + This is easily tested by running the gl_overlay demo + program and seeing if the display is correct when + you drag another window over it or if you drag the + window off the screen and back on. You have to exit + and run the program again for it to see any changes + to the environment variable. + + - Optimized colormap usage on 8-bit displays with + images. New code only allocates colors as they are + needed (still converts indexed images to full RGB and + dithers, tho...) + + - Fixed .gif files in FLUID, they were broken by the fix + for large .xpm files in version 1.0.9. + + - Fix for OpenGL hardware overlays with the transparent + index != 0. Tested on the brand new HP Linux + Workstations, this is the only bug encountered. Both + X and OpenGL hardware overlay works perfectly on + these, though configue may not enable it by + default...) + + - Fl_Choice and all other Fl_Menu_ subclasses draw the + items using textcolor() as the default color of the + text. + + - Fix suggested by Stuart Levy to fix scrolling when + deleting items from the browser. + + - Replaced the -$(MAKEFLAGS) with $(MFLAGS) as per the + gmake documenation. Apperntly this works with other + make programs and MAKEFLAGS is passed invisibly by + gmake, though the documenation is not too clear... + + +CHANGES SINCE FLTK 1.0.8 + + - More documentation fixes. + - GLUT_STROKE_*_ROMAN in glut.h are defined as 0,1 on + WIN32 to match the glut header files there. + - Added Fl::has_timeout() and Fl::has_idle() functions. + - Added new Fl::repeat_timeout() method that + measures time from when the last timeout was called. + This has slightly less overhead and allows accurate + spacing of timeouts. + - More Cygwin changes + - FLUID could crash with identifiers with trailing + whitespace. + - Fixed the XPM loading code in FLUID to handle files + longer than 2048 lines. + - Added a bunch of missing FL_EXTERN's to glut.h to + eliminate GLUT linking errors under WIN32. + - Fix for sliders so that clicking on one with a small + (or zero) slider_size will not move the slider. + - fl_shortcut.cxx didn't export fl_old_shortcut() in the + WIN32 DLL. + - Fixed xpaint link in the documentation. + - Included Fl_Input word-wrap fixes from Alexander Rabi + Beels. This will not affect things much because + word-wrap is normally disabled. + - Patch from Stuart Levy so the *last* widget in an + Fl_Pack may be resizable. This should be compatable + because resizable didn't do anything before so there + was no reason to set it. + - Cleaned up the timeout and Fl::wait() code. The new + code calls the clock function less than half as much, + which results in a noticable performance improvement + in some apps. + - Fl::wait(time) with a time greater than the system can + handle (24.855 days on NT, the same on some Unix + systems) will now act as though the time is infinity. + Before it would do unpredictable things. + - "USE_POLL" now compiles and works, although it is + disabled by default. poll() is an alternative to the + UNIX select() call which is available on some version + of UNIX and may be faster depending on the platform; + try it by editing config.h. + - The WIN32 USE_ASYNC_SELECT code now does translation + and dispatching of the select events; this makes + Windows a lot happier. + - Added a check for an open display in Fl::wait() so + that you don't need an open window under X to call it. + + [changes in snapshot 2] + + - fl_old_shortcut() wasn't being exported in the WIN32 DLL + project. + - Updated Cygwin and Mingw makefiles. + - Updated the BC++ project file. + - You can no longer insert control chars into Fl_Int/Float_Input. + - Fl_Multiline_Input now resets the horizontal position when + focus is changed; this caused problems when multiple multiline + widgets were used in an application. + - All handle() methods are now public, and all draw() methods are + now protected in FLTK widgets. + - More fixes to the OpenGL overlay code on win32. This now + seems to work quite reliably on several different pieces of + hardware. Apparently doing SetLayerPaletteEntries with a + palette larger than the overlay size caused the drivers to + screw up in unpredictable ways. Also SwapBuffers swapped both + the overlay and main window, which is not what fltk's + interface wanted, this was easy to fix however. + - Patch for full scrollbars so that clicking on them does not + move anything. + - Documentation fixes. + - Better horizontal scrolling of Fl_Input when cursor is near + the end of the line. + - Fl_Input::value(x) selects all text. + - Fl_Output and Fl_Multiline_Output would scroll to the end + of the text. + - filename_isdir() now drops any trailing slash from the + filename (needed for Windows) + - Added return type for main() function in line_style demo. + - Running FLUID with the "-cs" option writes the I18N message + file. + - The WIN32 version of XParseGeometry() didn't initialize some + variables. This caused a compiler warning but did not affect + the actual code. + + [changes in snapshot 1] + + - EMail changes - fltk-bugs@easysw.com now officially + fltk-bugs@fltk.org. + - The FLTK DLL project file didn't include fl_compose.cxx + - Dropped the GCC -fno-rtti option since it caused problems + with existing programs. + - Moved the .fl rules back to the test directory. + - Fixed some makefile and spec file problems. + - Fixed hardware overlays. The problem was the new + fl_clipped() code, which tests against the current window + size. The hardware overlay code did not set the current + window when drawing the overlay. I needed hardware overlay + for DD's code, I'm not sure if these fixes are good enough to + enable this in our general release. Hardware overlay still + only works on SGI Irix. + - Some patches to turn off the MSVC++ -Oa (assumme no aliasing) + optimization flag. Suprisingly this only broke a few parts + of fltk, or at least these are the only ones I found. + - Does not unmap child windows when the main window is + iconized. This reduces flashing when the window is + deiconized. + - Fl::key() is set to zero by all events except key down/up. + This will allow you to reliably test if an event or callback + was produced by a keystroke. Fixes the bug posted about + stopping Escape from closing the window. + - User defined cursors on OpenGL windows slowed down NT a + *LOT*. Some attempts to fix this by turning off the cursor + while drawing the window. + - Filename completion in the file chooser works better on NT. + Typing TAB fixes the case of everything you typed to match + the shortest name that can be completed. + + +CHANGES SINCE FLTK 1.0.7 + + - Many documentation changes/fixes/improvements. + - FLUID didn't save Fl_Double_Window's as + double-buffered windows. + - Fl_Menu_ text color is used if Fl_Menu_Item text color + is not set. + - Added Fl::first_window(window) method to change the + "top" window that is used when showing modal windows. + By default it is the window the user last + clicked/typed in. + - The Fl_Menu::global() handler now uses the current top + window instead of the menu bar for modal stuff. + - Added fl_line_style() function to set the line style. + Note that user-defined line styles ONLY WORK UNDER X11 + and Windows NT/2000. Windows 95/98 do, however, + support the "standard" line styles. + - Fl::wait() does not return immediately when no windows + - XForms keyboard shortcuts using hex keycode constants + now work. + - Updated the configure script for *BSD and to turn off + exceptions and RTTI in the FLTK library itself (does + not affect applications which use these things) + - FLUID now supports I18N using the POSIX or GNU + mechanisms. + - Fixed definition of glutBitmapWidth to match header + file. + - Does not turn visible() on when a window is iconized() + or if a modal window is shown and it's parent is + iconized. This allows the code "while (w->visible() + && w->damage()) Fl::check();" to reliably wait for the + window to be mapped and drawn the first time. + - Setting box(FL_NO_BOX) on a button makes it an + invisible overlay + - FL_NORMAL_SIZE is now a global variable so you can + change the default text size prior to creating your + widgets. + - Menus now draw properly with a box type of + FL_FLAT_BOX. + - Cygwin fixes to compile in POSIX mode. + - Fl_Value_Input callback can call value() or + destructor. + - OpenGL overlays now work under Windows NT! + - Fl_Slider and Fl_Scrollbar could cause a divide by + zero. + - Clicking in an Fl_Input field no longer selects the + whole field, it just moves the text cursor. + - Tru64 UNIX fixes for filename_list() + - Fl_Browser now draws itself properly when deactivated. + - FLUID GUIs now use Courier font for all code input. + - The FLUID OK and Cancel buttons are now all shown in + the same order in all windows. + - Fixes to compile under GCC 2.95.2 + - Fixed the BC5 project files. + - FL_LEFT_MOUSE and friends are now in + + - Fixes for fake OpenGL overlay code under WIN32. + - Message windows are now resizeable. + - On WIN32 non_modal (but not modal) windows have the + close and size boxes. + - Fl_Button and friends didn't honor the + FL_WHEN_NOT_CHANGED condition. + - Disabled XDBE on all platforms. + - XGetDefault patch from James Roth + - New fl_open_display(Display *) function to allow FLTK + to share a display connection with another toolkit + (like Xt, GTK, etc.) + - Shortcut labels for special keys should now display + properly under WIN32. + - fl_set_fonts() did not reuse fonts. + - Fixed shortcut problem under WIN32 when the focus + window changes. + - "dead" keys should now work under X11. + - Fixes to make FLTK compile with GCC 2.95.2 + - FL_SHORTCUT fix for I18N. + - Fixed cut/paste problems under WIN32 + - FLUID now produces correct code for nested class + destructors. + - Nested windows should now redraw properly under WIN32. + - "table" is now static in fl_cursor.cxx + - Fl_Chart used the textcolor() and not the color() for + horizontal bar charts. + - Now set the input hint for TWM and TWM-derived window + managers. + - Now look for TrueColor visual if FLTK is compiled with + USE_COLORMAP == 0. + - Fl_Scrollbar could generate a divide-by-0 error if the + min and max values were the same. + - Fl_Menu_::remove() now removes whole submenus if + needed. + - Scrollbar buttons now draw themselves pushed in as + needed. + - Fixed the gl_overlay demo (and gl overlays in general) + when they are faked with no hardware and the window is + resized. + - Selections weren't shown in Fl_Browser widgets when an + item used the @B (background) format. + - Windows can now be resized by the program under X11 + for more window managers. + - OS/2 makeinclude updates. + - Added Fl.H required by an inline function in + Fl_Repeat_Button.H + - Fl_add_idle adds new functions to the end of the queue + ring, rather than the start, so they are executed in + the order added, and a callback that adds itself does + not prevent others from being called. + - FLUID lets you type in code that starts with '#' for + cpp directives. + - XBell() could be called before the X11 display was + opened, causing a segfault. + - Fixed Fl_Gl_Window::ortho() - Borland C++ doesn't + define GLint to "int", but instead to "long"... + - Fixed Fl_Browser scrollbars within an Fl_Scroll + widget. + - Fl_Output (and non-focused Fl_Input) now scroll in + response to position() + - Fl_Input now does not scroll horizontally if the + entire string will fit in the widget. + - Fl_Scrollbar didn't push the right arrow buttons when + you clicked outside the scroller. + - Now use WSAAsyncSelect() for better socket performance + with Fl::add_fd() + + +CHANGES SINCE FLTK 1.0.6 + + - Fixed Fl_Input_ bug under WIN32 - no longer stop accepting input + when one of the "Windows" keys is pressed. + - Now call TranslateEvent for all events under WIN32. + - Fixes for OpenBSD and NetBSD + - The FL_CURSOR_HAND cursor now uses the IDC_HAND cursor instead of + IDC_UPARROW under Windows 98 and 2000. + - Fl_Scrollbar now does a page-up/down when you click outside the + scroller. + - Fl_Window::show(0, NULL) causes core dump + - Fixed a compile-time error in fl_call_main.c for Borland C++. + - "fluid -c filename.fl" would try to open an X display if the + FLUID file contained an Fl_Browser widget. + - Fl_Browser now correctly measures items with @C or @B color + formatting commands. + - Fixed a bitmap drawing bug for WIN32 (bit reversal table was wrong) + - fl_xyz() dialogs now set a title in the title bar. + - fl_alert() sounds the bell under X11. + - fl_xyz() dialogs now call MessageBeep() under WIN32. + - Fl_Browser_ didn't draw the selection box with the inactive color + when the browser wasn't activated. + - Fl_Browser now responds to FL_KEYBOARD as well as FL_SHORTCUT. If + you subclass it to accept focus then keyboard navigation will work. + - Fl_Tile and Fl_Tabs do their callback when the user changes their + display. + - Made some of the private methods of Fl_Browser protected. + - Now set win_gravity correctly, this helps some X + window managers that use it position the window where + FLTK wants it to be. + - 0-width browsers crashed. + - Minor change: if the X window manager does not do + anything else with windows that don't have their + position specified, the windows appear centered in the + screen, rather than in the top-left corner. This + happened with modal windows under Irix 4Dwm. This + also causes windows to be centered when no window + manager is running, which might be useful for + installation gui programs? + - Clicking in an Fl_Input field the first time selects the entire + field. + - Clicking the middle mouse button in an Fl_Input field now inserts + the text at the indicated position instead of the cursor position. + - Drag-selecting text in an Fl_Input field now copies the text + automatically. + - Fl::flush() no longer calls the draw() method for invisible windows. + - Calling deactivate() on an invisible widget could cause an + infinite loop in some obscure cases. + - Added #pragma's for SGI C++ compilers - the 6.{23} X headers had + errors in them. + - Fl_Gl_Window::ortho() changed so that text and images + are not erased if the origin is off the left/bottom of the + window. + - Small change to Fl_Input so that a click that gives it + the focus also selects all the text. + - Fixed a slider drawing problem. + - You can now add/delete children of Fl_Tabs widgets whether or + not they are visible. + - Now embed woff options for SGI C++ compilers (gets rid of X11 + header warnings) + - draw_pixmap used a cast that the Digital UNIX C++ compiler didn't + like. + - The GLUT function key constants were off by one. + - The XPM reading code didn't handle RGB colors other than #rrggbb. + + +CHANGES SINCE FLTK 1.0.5 + + - Fl_win32.cxx defined WM_MOUSE_LEAVE instead of WM_MOUSELEAVE. + - Fl_get_key_win32.cxx needed to include + - gl_draw_pixmap.cxx needed a pointer cast for ANSI C++. + - Fl_Repeat_Button didn't always delete its timeout. + - Now keep track of the current OpenGL context; this provides + significant performance improvements for OpenGL applications + with a single context. + + +CHANGES SINCE FLTK 1.0.4 + + - Fl_Roller didn't handle a width and height of 0. + - filename_list() fix for FreeBSD. + - Fixed RPM install docos - needed "--install" option... + - Fl_Browser_ wouldn't draw the vertical scrollbar right away if it + added a horizontal one which covered the last line. + - Fl_Tabs problems - single-character labels don't show up (problem in + measure_tabs() or measure_label() methods?), and doesn't clear top + tab area before drawing tabs. + - Fl_Browser needs a destructor. + - fl_draw_label() quoted characters between 0x80 and 0xa0, which + caused problems for some programs using the WinANSI character set. + - FLUID didn't handle declared class destructors. + - Fixed another WIN32 cut/paste bug. + - Fl_Tabs didn't work properly when there was only 1 tab. + - Fl_Menu::add() didn't delete the old array. + - Fl_Repeat_Button didn't delete its timeout when disabled. + - fl_draw() would crash if no font was set (now defaults to + a 14-pixel Helvetica font) + - Can't forward declare classes; need to check for "class ", "struct ", + "union ", etc. See Bill's message + - Added #pragma around xlib.h for IRIX + - FL_KEYBOARD events have the correct x/y when sent to child X + windows. Note that if you worked around this bug by adjusting the + x/y yourself you will have to change your code. In addition all + events have the correct x/y when sent to the grab() widget. And + the code to do all this was simplified a lot. + - The XPM code didn't handle named colors with spaces in the names. + - Pressing ESCape closed the window with pointer focus, even if there + was a modal window open (now closes the modal window). + - FLUID no longer produces trigraphs accidentally in the image data. + - FLUID uses string constant concatenation to produce shorter image + data. + - The Fl_Group deletion code crashed if there was exactly one child + widget. + - Simulated overlays in single-buffered Fl_Gl_Windows now draw + correctly (though very slowly as it requires the entire window to + be redrawn to erase the overlay). This fix ported our Digital + Domain programs better to systems with no overlay hardware. + - Added support for extern "C" declarations in FLUID. + - Added Fl_Pack support to FLUID. + - Fixed the order of #include's in FLUID generated header files. + - Fixed detection of vsnprintf and snprintf under HP-UX 10.20 once + and for all. + - The checkers demo did not compile with GCC 2.95 + - FLUID didn't output virtual destructors properly. + - Added inline "make_visible()" method to Fl_Browser. + - Fl::wait() now returns immediately if any timeouts are + called. + - 16-bit XPM files are now properly handled. + - Fl_Window::resize() was missing FL_EXPORT (caused problems + with Windows DLLs) + - FLUID was writing extern declarations twice. + - New FLUID arrow key functionality: arrows move by one pixel, shift+arrow + resizes, ctrl+arrow steps by grid + + +CHANGES SINCE FLTK 1.0.3 + + - Documentation updates + - Fl_Browser::bottomline(size) didn't scroll to the bottom + if the second-to-last line was visible. + - fl_wait() didn't poll FDs properly for WIN32. + - Fixed DLL definitions for BC++. + - FLUID now handles nested classes properly. + - The "connect" demo now does a wait() for the PPP process + so that you aren't left with a lot of zombie processes. + - Fixed the FLTK colormap to use FF instead of F4 for full + intensity values. + - Minor change to scrollbar drawing code to match other + toolkits. + - New selections would cancel themselves out in WIN32. + - The header file links were broken in the IRIX + distributions. + - fl_elapsed() now always uses GetClockTick() for WIN32. + - fl_display is now initialized to GetModuleHandle(NULL) - + this fixes problems people had with Cygwin and MingW32. + - WinMain() is no longer compiled in with Cygwin and + MingW32; it wasn't being used for those compilers anyways. + - Added Solaris compiler options to configure script. + - Fl_Value_Input wouldn't update properly if you set the + value from a callback. + - Fl_Tile wouldn't resize if the resizeable widget was the + last child. + - Was missing #include and #include in + several files, which caused problems on some platforms. + - Fixed another case where Fl_Browser_ could get in an + infinite resizing loop. + - Fl_win32.cxx now includes to export missing + DLL symbols. + - FLUID didn't handle member functions that include the + scope operator. + - Fl_Chart was dividing by 0 if there were no data samples + or if they were all the same (min == max). + + +CHANGES SINCE FLTK 1.0.2 + + - XDBE is now enabled for IRIX 6.[234] as well as 6.5. + - FLUID didn't write the when() condition properly. + - Tab/space/backtab/backspace can be used to navigate + through menus. + - Changed $(DSONAME) in the src/Makefile to "libfltk.so.1 + libfltk.sl.1". + - Fl_Browser could read past the end of the string when + computing the item height. + - Fl_Browser could get in an infinite loop when checking to + see if scrollbars needed to be displayed. + - FLUID now honors the return type of the outermost widget. + This was a problem when substituting Fl_Group in an + Fl_Window widget. + - Fl_Menu_::copy() wasn't allocating a power of 2 for the + array size. + - FLWM would crash if fl_xmousewin was deleted. + - The fast_slow demo now uses output widgets. + - Timers under WIN32 were unreliable. + + +CHANGES SINCE FLTK 1.0.1 + + - Documentation updates + - The Visual C++ project files didn't include fl_add_idle.cxx. + - LIBRARY/DSO name inconsistencies in src/Makefile. + - src/Makefile didn't clean the DSO. + - The valuator demo now has only a single callback. + - The code looked for HAVE_SYS_SELECT_H, but the + config file uses HAVE_SYS_SELECT. + - Fl_Image redraw not quite right under X11 or WIN32 + - Problems with timeouts & cube demo under WIN32 + - FLUID problems with inline functions. + - Documentation fixes... + - Fl_Browser::item_height() didn't handle blank lines or + non-default fonts properly. + - FL/math.h didn't have #ifndef...#define...#endif guards + against multiple inclusion... + - Fl_Menu_::copy() fix - didn't allocate power of 2... + - Fl::damage() now remains true until all windows are actually + redrawn. + - Fl_Widget destructor, hide(), and deactivate() methods no longer + send FL_LEAVE, FL_RELEASE, or FL_UNFOCUS events to the widget + (which could cause applications to crash). + - FLUID now outputs symbolic names for align() and when(). + - Fixed select() to use maxfd + 1 instead of maxfd. + - Added "Fl::remove_fd(fd, when)" function so you can remove the + read and write callbacks separately. + - The Fl::add_fd() and Fl::add_timeout() arrays are now dynamically + allocated. + - FLUID didn't always turn the FL_SUBMENU flag on for submenu titles. + - The "extra code" in FLUID now is placed before the "o->end()" call + for Fl_Group and its derived classes. + - You can now set a FL_Window widget's class in FLUID to Fl_Group to + generate a function or class that builds part of a GUI (i.e. no window). + - FLUID now displays "Save file before exiting?" with the standard yes, + no, and cancel buttons rather than "Discard changes?". + - Fl_Menu_::add() now works with any type of menu, even one set with + the menu() method. + - The keypad keys were not always decoded properly under X11. + - Some pointers were not being turned off when widgets were deleted, + which caused some applications (like FLWM) to crash. + + +CHANGES SINCE FLTK 1.0 + + - Documentation fixes. + - Fl::check() didn't return the correct value, breaking a number + of applications. + - Fixed FLUID bug that caused styles patch to crash when you delete + a menu item. + - Updated valuators demo to put the values in the gui box. + - Fl_Browser_::item_height() didn't always compute the correct + value. + - Fixed the alignment of Fl_Choice text. + - Fixes for OS/2. + - Fl_Menu_Item::clear() didn't clear value. + - Added some changes to make FLTK work with Borland C++. + - ANSI C++ fixes. + - Plugged a memory leak in the fractal demo. + - Fl::add_timeout() didn't work under WIN32 with small values. + - The configure script and makefiles now define DSONAME and + use the static library for all example programs. diff --git a/plugins/zynaddsubfx/fltk/CMake/CheckFunctionWithHeaderExists.cmake b/plugins/zynaddsubfx/fltk/CMake/CheckFunctionWithHeaderExists.cmake new file mode 100644 index 000000000..46694e82a --- /dev/null +++ b/plugins/zynaddsubfx/fltk/CMake/CheckFunctionWithHeaderExists.cmake @@ -0,0 +1,54 @@ +# +# Check if the symbol exists in include files +# +# CHECK_FUNCTIONWITHHEADER_EXISTS - macro which checks the symbol exists in include files. +# SYMBOL - symbol +# FILES - include files to check +# VARIABLE - variable to return result +# + +MACRO(CHECK_FUNCTIONWITHHEADER_EXISTS SYMBOL FILES VARIABLE) + IF("${VARIABLE}" MATCHES "^${VARIABLE}$") + SET(CHECK_SYMBOL_EXISTS_CONTENT "/* */\n") + SET(MACRO_CHECK_SYMBOL_EXISTS_FLAGS ${CMAKE_REQUIRED_FLAGS}) + IF(CMAKE_REQUIRED_LIBRARIES) + SET(CHECK_SYMBOL_EXISTS_LIBS + "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}") + ENDIF(CMAKE_REQUIRED_LIBRARIES) + FOREACH(FILE ${FILES}) + SET(CHECK_SYMBOL_EXISTS_CONTENT + "${CHECK_SYMBOL_EXISTS_CONTENT}#include <${FILE}>\n") + ENDFOREACH(FILE) + SET(CHECK_SYMBOL_EXISTS_CONTENT + "${CHECK_SYMBOL_EXISTS_CONTENT}\nint main()\n{\n${SYMBOL};return 0;\n}\n") + + FILE(WRITE ${CMAKE_BINARY_DIR}/CMakeTmp/CheckSymbolExists.c + "${CHECK_SYMBOL_EXISTS_CONTENT}") + + MESSAGE(STATUS "Looking for ${SYMBOL}") + TRY_COMPILE(${VARIABLE} + ${CMAKE_BINARY_DIR} + ${CMAKE_BINARY_DIR}/CMakeTmp/CheckSymbolExists.c + CMAKE_FLAGS + -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_SYMBOL_EXISTS_FLAGS} + "${CHECK_SYMBOL_EXISTS_LIBS}" + OUTPUT_VARIABLE OUTPUT) + IF(${VARIABLE}) + MESSAGE(STATUS "Looking for ${SYMBOL} - found") + SET(${VARIABLE} 1 CACHE INTERNAL "Have symbol ${SYMBOL}") + FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeOutput.log + "Determining if the ${SYMBOL} " + "exist passed with the following output:\n" + "${OUTPUT}\nFile ${CMAKE_BINARY_DIR}/CMakeTmp/CheckSymbolExists.c:\n" + "${CHECK_SYMBOL_EXISTS_CONTENT}\n") + ELSE(${VARIABLE}) + MESSAGE(STATUS "Looking for ${SYMBOL} - not found.") + SET(${VARIABLE} "" CACHE INTERNAL "Have symbol ${SYMBOL}") + FILE(APPEND ${CMAKE_BINARY_DIR}/CMakeError.log + "Determining if the ${SYMBOL} " + "exist failed with the following output:\n" + "${OUTPUT}\nFile ${CMAKE_BINARY_DIR}/CMakeTmp/CheckSymbolExists.c:\n" + "${CHECK_SYMBOL_EXISTS_CONTENT}\n") + ENDIF(${VARIABLE}) + ENDIF("${VARIABLE}" MATCHES "^${VARIABLE}$") +ENDMACRO(CHECK_FUNCTIONWITHHEADER_EXISTS) diff --git a/plugins/zynaddsubfx/fltk/CMake/FLTKConfig.cmake.in b/plugins/zynaddsubfx/fltk/CMake/FLTKConfig.cmake.in new file mode 100644 index 000000000..3ed435b11 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/CMake/FLTKConfig.cmake.in @@ -0,0 +1,37 @@ +#----------------------------------------------------------------------------- +# +# FLTKConfig.cmake - FLTK CMake configuration file for external projects. +# +# This file is configured by FLTK and used by the UseFLTK.cmake module +# to load FLTK's settings for an external project. + +# The FLTK source tree. +SET(FLTK_SOURCE_DIR "@FLTK_SOURCE_DIR@") + +# The FLTK include file directories. +SET(FLUID_COMMAND "@FLTK_FLUID_COMMAND@") +SET(FLTK_EXECUTABLE_DIRS "@FLTK_EXECUTABLE_DIRS@") +SET(FLTK_LIBRARY_DIRS "@FLTK_LIBRARY_DIRS@") +SET(FLTK_LIBRARIES "@FLTK_LIBRARIES@") +SET(FLTK_INCLUDE_DIRS "@FLTK_INCLUDE_DIRS@") + +# The C and C++ flags added by FLTK to the cmake-configured flags. +SET(FLTK_REQUIRED_C_FLAGS "@FLTK_REQUIRED_C_FLAGS@") +SET(FLTK_REQUIRED_CXX_FLAGS "@FLTK_REQUIRED_CXX_FLAGS@") + +# The FLTK version number +SET(FLTK_VERSION_MAJOR "@FLTK_VERSION_MAJOR@") +SET(FLTK_VERSION_MINOR "@FLTK_VERSION_MINOR@") +SET(FLTK_VERSION_PATCH "@FLTK_VERSION_PATCH@") + +# Is FLTK using shared libraries? +SET(FLTK_BUILD_SHARED_LIBS "@BUILD_SHARED_LIBS@") +SET(FLTK_BUILD_SETTINGS_FILE "@FLTK_BUILD_SETTINGS_FILE@") + +# The location of the UseFLTK.cmake file. +SET(FLTK11_USE_FILE "@FLTK_USE_FILE@") + +# The ExodusII library dependencies. +IF(NOT FLTK_NO_LIBRARY_DEPENDS) + INCLUDE("@FLTK_LIBRARY_DEPENDS_FILE@") +ENDIF(NOT FLTK_NO_LIBRARY_DEPENDS) diff --git a/plugins/zynaddsubfx/fltk/CMake/FLTKUse.cmake b/plugins/zynaddsubfx/fltk/CMake/FLTKUse.cmake new file mode 100644 index 000000000..3512b5ef9 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/CMake/FLTKUse.cmake @@ -0,0 +1,68 @@ +IF(NOT FLTK11_FOUND) + MESSAGE(FATAL_ERROR "Something went wrong. You are including FLTKUse.cmake but FLTK was not found") +ENDIF(NOT FLTK11_FOUND) + +# ------------------------------------------------------------- +# This macro automates wrapping of Fluid files +# Specify the output variable name and the list of sources +# The output variable can be directly added to the target. +# +# For example: +# FLTK_WRAP_FLUID(CubeView_SRCS CubeViewUI.fl) +# ADD_EXECUTABLE(CubeView CubeMain.cxx CubeView.cxx CubeView.h ${CubeView_SRCS}) +# ------------------------------------------------------------- +MACRO(FLTK_WRAP_FLUID VARIABLE) + FOREACH(src ${ARGN}) + IF("${src}" MATCHES ".fl$") + GET_FILENAME_COMPONENT(fname ${src} NAME_WE) + GET_FILENAME_COMPONENT(fpath ${src} PATH) + GET_SOURCE_FILE_PROPERTY(gen ${src} GENERATED) + IF(gen) + SET(fluid_name "${src}") + ELSE(gen) + SET(fluid_name "${CMAKE_CURRENT_SOURCE_DIR}/${fpath}/${fname}.fl") + IF(NOT EXISTS "${fluid_name}") + SET(fluid_name "${CMAKE_CURRENT_BINARY_DIR}/${fpath}/${fname}.fl") + IF(NOT EXISTS "${fluid_name}") + SET(fluid_name "${fpath}/${fname}.fl") + IF(NOT EXISTS "${fluid_name}") + MESSAGE(SEND_ERROR "Cannot find Fluid source file: ${fpath}/${fname}.fl") + ENDIF(NOT EXISTS "${fluid_name}") + ENDIF(NOT EXISTS "${fluid_name}") + ENDIF(NOT EXISTS "${fluid_name}") + ENDIF(gen) + SET(cxx_name "${CMAKE_CURRENT_BINARY_DIR}/${fname}.cxx") + SET(h_name "${CMAKE_CURRENT_BINARY_DIR}/${fname}.h") + SET(${VARIABLE} "${${VARIABLE}};${cxx_name}") + ADD_CUSTOM_COMMAND( + OUTPUT ${cxx_name} + DEPENDS "${fluid_name}" "${FLUID_COMMAND}" + COMMAND ${FLUID_COMMAND} + ARGS -c ${fluid_name}) + ADD_CUSTOM_COMMAND( + OUTPUT ${h_name} + DEPENDS "${fluid_name}" "${FLUID_COMMAND}" + COMMAND ${FLUID_COMMAND} + ARGS -c ${fluid_name}) + ENDIF("${src}" MATCHES ".fl$") + ENDFOREACH(src) +ENDMACRO(FLTK_WRAP_FLUID VARIABLE) + + +# Make FLTK easier to use +INCLUDE_DIRECTORIES(${FLTK_INCLUDE_DIRS}) +LINK_DIRECTORIES(${FLTK_LIBRARY_DIRS}) + +# Load the compiler settings used for FLTK. +IF(FLTK_BUILD_SETTINGS_FILE) + INCLUDE(CMakeImportBuildSettings) + CMAKE_IMPORT_BUILD_SETTINGS(${FLTK_BUILD_SETTINGS_FILE}) +ENDIF(FLTK_BUILD_SETTINGS_FILE) + +# Add compiler flags needed to use FLTK. +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FLTK_REQUIRED_C_FLAGS}") +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLTK_REQUIRED_CXX_FLAGS}") +SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FLTK_REQUIRED_EXE_LINKER_FLAGS}") +SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${FLTK_REQUIRED_SHARED_LINKER_FLAGS}") +SET(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${FLTK_REQUIRED_MODULE_LINKER_FLAGS}") + diff --git a/plugins/zynaddsubfx/fltk/CMake/PlatformTests.cxx b/plugins/zynaddsubfx/fltk/CMake/PlatformTests.cxx new file mode 100644 index 000000000..bfe97ac95 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/CMake/PlatformTests.cxx @@ -0,0 +1,81 @@ +#ifdef HAVE_LIBZ + +#include + +int main() +{ + unsigned long compressedSize = 0; + unsigned char cd[100]; + const unsigned char ud[100] = ""; + unsigned long uncompressedSize = 0; + + // Call zlib's compress function. + if(compress(cd, &compressedSize, ud, uncompressedSize) != Z_OK) + { + return 0; + } + return 1; +} + + +#endif + +#ifdef HAVE_LIBJPEG + +#include +#include + +int main() +{ + struct jpeg_decompress_struct cinfo; + jpeg_create_decompress(&cinfo); + jpeg_read_header(&cinfo, TRUE); + return 1; +} + +#endif + +#ifdef HAVE_LIBPNG +#include +int main() +{ + png_structp png_ptr = png_create_read_struct + (PNG_LIBPNG_VER_STRING, (png_voidp)NULL, + NULL, NULL); + png_infop info_ptr = png_create_info_struct(png_ptr); + png_set_sig_bytes(png_ptr, 8); + png_read_info(png_ptr, info_ptr); + + return 0; +} +#endif + +#ifdef HAVE_PNG_H +#include +int main() { retunr 0;} +#endif + +#ifdef HAVE_PNG_GET_VALID +#include +int main() +{ + png_structp png_ptr = png_create_read_struct + (PNG_LIBPNG_VER_STRING, (png_voidp)NULL, + NULL, NULL); + png_infop info_ptr = png_create_info_struct(png_ptr); + png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS); + return 0; +} +#endif + +#ifdef HAVE_PNG_SET_TRNS_TO_ALPHA +#include +int main() +{ + png_structp png_ptr = png_create_read_struct + (PNG_LIBPNG_VER_STRING, (png_voidp)NULL, + NULL, NULL); + png_set_tRNS_to_alpha(png_ptr); + return 0; +} +#endif diff --git a/plugins/zynaddsubfx/fltk/CMakeLists.txt b/plugins/zynaddsubfx/fltk/CMakeLists.txt new file mode 100644 index 000000000..55653d0c0 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/CMakeLists.txt @@ -0,0 +1,423 @@ +# Main CMakeLists.txt to build the FLTK project using CMake (www.cmake.org) +# Written by Andy Cedilnik and Julien Jomier + +PROJECT(FLTK) +CMAKE_MINIMUM_REQUIRED(VERSION 2.0) + +# The FLTK version +SET(FLTK_VERSION_MAJOR "1") +SET(FLTK_VERSION_MINOR "1") +SET(FLTK_VERSION_PATCH "9") +SET(FLTK_VERSION "${FLTK_VERSION_MAJOR}.${FLTK_VERSION_MINOR}") +SET(FLTK_VERSION_FULL "${FLTK_VERSION}.${FLTK_VERSION_PATCH}") + +SET(FLTK_LIBRARIES "fltk_images;fltk;fltk_gl;fltk_forms") + +# Executables and libraries should just go to bin +SET(EXECUTABLE_OUTPUT_PATH "${FLTK_BINARY_DIR}/bin" CACHE INTERNAL + "Where to put the executables for FLTK" + ) +SET(LIBRARY_OUTPUT_PATH "${FLTK_BINARY_DIR}/bin" CACHE INTERNAL + "Where to put the libraries for FLTK" + ) + +# Allow building shared libraries +OPTION(BUILD_SHARED_LIBS "Build FLTK as a shared library" OFF) + +# Search for modules in the FLTK source dir first +SET(CMAKE_MODULE_PATH "${FLTK_SOURCE_DIR}/CMake") + +#----------------------------------------------------------------------------- +# Test for some required system information. +FIND_PACKAGE(Threads) +SET (CMAKE_USE_PTHREADS + "${CMAKE_USE_PTHREADS_INIT}" CACHE BOOL "Use the pthreads library.") + +# We need ansi c-flags, especially on HP +SET(CMAKE_C_FLAGS "${CMAKE_ANSI_CFLAGS} ${CMAKE_C_FLAGS}") +SET(CMAKE_REQUIRED_FLAGS ${CMAKE_ANSI_CFLAGS}) + +IF(WIN32) + IF(NOT CYGWIN) + IF(BORLAND) + SET( FLTK_PLATFORM_DEPENDENT_LIBS import32 ) + ELSE(BORLAND) + SET( FLTK_PLATFORM_DEPENDENT_LIBS wsock32 comctl32 ) + ENDIF(BORLAND) + ENDIF(NOT CYGWIN) +ELSE(WIN32) + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") +ENDIF(WIN32) + +SET(FLTK_X11 1) +SET(FLTK_APPLE 0) +IF(APPLE) + OPTION(FLTK_APPLE_X11 "Use X11 on Mac instead of Carbon" OFF) + MARK_AS_ADVANCED(FLTK_APPLE_X11) + IF(NOT FLTK_APPLE_X11) + SET(FLTK_APPLE 1) + SET(FLTK_X11 0) + OPTION(FLTK_QUARTZ "Use Quartz instead of Quickdraw" OFF) + ENDIF(NOT FLTK_APPLE_X11) +ENDIF(APPLE) + +IF(UNIX) + FIND_PACKAGE(X11) + SET( FLTK_PLATFORM_DEPENDENT_LIBS ${X11_LIBRARIES} -lm) + SET( FLTK_PLATFORM_DEPENDENT_LIBS ${X11_LIBRARIES} -lm) + SET(USE_XFT 0) + IF(X11_Xft_FOUND) + FIND_PACKAGE(Freetype) + IF(FREETYPE_FOUND) + SET(FOUND_XFT 1) + SET(FLTK_PLATFORM_DEPENDENT_LIBS ${FLTK_PLATFORM_DEPENDENT_LIBS} ${X11_Xft_LIB} ${FREETYPE_LIBRARIES}) + INCLUDE_DIRECTORIES(${FREETYPE_INCLUDE_DIRS} ${X11_Xft_INCLUDE_PATH}) + ENDIF(FREETYPE_FOUND) + ENDIF(X11_Xft_FOUND) +ENDIF(UNIX) + +IF(APPLE AND NOT FLTK_APPLE_X11) + SET( FLTK_PLATFORM_DEPENDENT_LIBS + "-framework Carbon -framework Cocoa -framework ApplicationServices -lz") +ENDIF(APPLE AND NOT FLTK_APPLE_X11) + +IF(CYGWIN) + ADD_DEFINITIONS(-DWIN32) + SET( FLTK_PLATFORM_DEPENDENT_LIBS ole32 uuid comctl32 wsock32 supc++ -lm -lgdi32) +ENDIF(CYGWIN) + +IF(MINGW) + ADD_DEFINITIONS(-DWIN32) + SET( FLTK_PLATFORM_DEPENDENT_LIBS ole32 uuid wsock32 gdi32 comdlg32) +ENDIF(MINGW) + +INCLUDE(CheckIncludeFiles) +# Check if header file exists and add it to the list. +MACRO(CHECK_INCLUDE_FILE_CONCAT FILE VARIABLE) + CHECK_INCLUDE_FILES("${PROJECT_INCLUDES};${FILE}" ${VARIABLE}) + IF(${VARIABLE}) + SET(PROJECT_INCLUDES ${PROJECT_INCLUDES} ${FILE}) + ENDIF(${VARIABLE}) +ENDMACRO(CHECK_INCLUDE_FILE_CONCAT) +#CHECK_INCLUDE_FILE_CONCAT("GL/glu.h" HAVE_GL_GLU_H) +#CHECK_INCLUDE_FILE_CONCAT("OpenGL/glu.h" HAVE_OPENGL_GLU_H) +CHECK_INCLUDE_FILE_CONCAT("dirent.h" HAVE_DIRENT_H) +CHECK_INCLUDE_FILE_CONCAT("stdio.h" HAVE_STDIO_H) +CHECK_INCLUDE_FILE_CONCAT("strings.h" HAVE_STRINGS_H) +CHECK_INCLUDE_FILE_CONCAT("sys/dir.h" HAVE_SYS_DIR_H) +CHECK_INCLUDE_FILE_CONCAT("sys/ndir.h" HAVE_SYS_NDIR_H) +CHECK_INCLUDE_FILE_CONCAT("sys/select.h" HAVE_SYS_SELECT_H) +CHECK_INCLUDE_FILE_CONCAT("sys/stdtypes.h" HAVE_SYS_STDTYPES_H) +CHECK_INCLUDE_FILE("pthread.h" CMAKE_HAVE_PTHREAD_H) + +FIND_PACKAGE(ZLIB) +FIND_PACKAGE(PNG) +FIND_PACKAGE(JPEG) + +INCLUDE(CheckSymbolExists) +INCLUDE(CheckFunctionWithHeaderExists) + +CHECK_FUNCTIONWITHHEADER_EXISTS("int strcasecmp()" "${PROJECT_INCLUDES}" HAVE_STRCASECMP) + +CHECK_SYMBOL_EXISTS(strlcat "${PROJECT_INCLUDES}" HAVE_STRLCAT) +CHECK_SYMBOL_EXISTS(strlcpy "${PROJECT_INCLUDES}" HAVE_STRLCPY) +CHECK_SYMBOL_EXISTS(vsnprintf "${PROJECT_INCLUDES}" HAVE_VSNPRINTF) +CHECK_SYMBOL_EXISTS(snprintf "${PROJECT_INCLUDES}" HAVE_SNPRINTF) +CHECK_SYMBOL_EXISTS(scandir "${PROJECT_INCLUDES}" HAVE_SCANDIR) + +INCLUDE(CheckTypeSize) + +CHECK_TYPE_SIZE(short SIZEOF_SHORT) +CHECK_TYPE_SIZE(int SIZEOF_INT) +CHECK_TYPE_SIZE(long SIZEOF_LONG) + +IF(${SIZEOF_SHORT} MATCHES "^2$") + SET(U16 "unsigned short") +ENDIF(${SIZEOF_SHORT} MATCHES "^2$") + +IF(${SIZEOF_INT} MATCHES "^4$") + SET(U32 "unsigned") +ELSE(${SIZEOF_INT} MATCHES "^4$") + IF(${SIZEOF_LONG} MATCHES "^4$") + SET(U32 "unsigned long") + ENDIF(${SIZEOF_LONG} MATCHES "^4$") +ENDIF(${SIZEOF_INT} MATCHES "^4$") + +IF(${SIZEOF_INT} MATCHES "^8$") + SET(U64 "unsigned") +ELSE(${SIZEOF_INT} MATCHES "^8$") + IF(${SIZEOF_LONG} MATCHES "^8$") + SET(U64 "unsigned long") + ENDIF(${SIZEOF_LONG} MATCHES "^8$") +ENDIF(${SIZEOF_INT} MATCHES "^8$") + +# Set an option to build FLTK with OpenGL support +SET(HAVE_GL 0) +OPTION(USE_OPENGL "OpenGL Support" ON) +IF(USE_OPENGL) + FIND_PACKAGE(OpenGL) + IF(OPENGL_FOUND) + SET(HAVE_GL 1) + INCLUDE_DIRECTORIES(${OPENGL_INCLUDE_DIR}) + ENDIF(OPENGL_FOUND) +ENDIF(USE_OPENGL) + +# +# Perform the FLTK specific test with status output +# +MACRO(PERFORM_CMAKE_TEST FILE TEST) + IF("${TEST}" MATCHES "^${TEST}$") + # Perform test + SET(MACRO_CHECK_FUNCTION_DEFINITIONS + "-D${TEST} ${CMAKE_REQUIRED_FLAGS}") + IF(CMAKE_REQUIRED_LIBRARIES) + SET(TEST_ADD_LIBRARIES + "-DLINK_LIBRARIES:STRING=${CMAKE_REQUIRED_LIBRARIES}") + ENDIF(CMAKE_REQUIRED_LIBRARIES) + MESSAGE(STATUS "Performing Test ${TEST}") + + TRY_COMPILE(${TEST} + ${CMAKE_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/${FILE} + CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS} + -DLINK_LIBRARIES:STRING=${CMAKE_TEST_SPECIAL_LIBRARIES} + "${TEST_ADD_LIBRARIES}" + OUTPUT_VARIABLE OUTPUT) + IF(${TEST}) + SET(${TEST} 1 CACHE INTERNAL "CMake test ${FUNCTION}") + MESSAGE(STATUS "Performing Test ${TEST} - Success") + ELSE(${TEST}) + MESSAGE(STATUS "Performing Test ${TEST} - Failed") + SET(${TEST} 0 CACHE INTERNAL "Test ${FUNCTION}") + WRITE_FILE(${CMAKE_BINARY_DIR}/CMakeError.log + "Performing Test ${TEST} failed with the following output:\n" + "${OUTPUT}\n" APPEND) + ENDIF(${TEST}) + ENDIF("${TEST}" MATCHES "^${TEST}$") +ENDMACRO(PERFORM_CMAKE_TEST FILE TEST) + +# Set an option to build the zlib library or not +OPTION(FLTK_USE_SYSTEM_ZLIB "Use's system zlib" OFF) +IF(FLTK_USE_SYSTEM_ZLIB) + IF(ZLIB_FOUND) + SET(CMAKE_TEST_SPECIAL_LIBRARIES ${ZLIB_LIBRARIES}) + SET(FLTK_ZLIB_LIBRARIES ${ZLIB_LIBRARIES}) + PERFORM_CMAKE_TEST(CMake/PlatformTests.cxx HAVE_LIBZ) + ENDIF(ZLIB_FOUND) + # We build the fltk zlib +ELSE(FLTK_USE_SYSTEM_ZLIB) + MARK_AS_ADVANCED(ZLIB_INCLUDE_DIR) + MARK_AS_ADVANCED(ZLIB_LIBRARY) +# SUBDIRS(zlib) + SET(HAVE_LIBZ 1) + SET(FLTK_ZLIB_LIBRARIES fltk_zlib) + SET(FLTK_LIBRARIES "${FLTK_LIBRARIES};fltk_zlib") + INCLUDE_DIRECTORIES("${CMAKE_CURRENT_SOURCE_DIR}/zlib") +ENDIF(FLTK_USE_SYSTEM_ZLIB) + +# Set an option to build the jpeg library or not +OPTION(FLTK_USE_SYSTEM_JPEG "Use's system jpeg" OFF) +IF(FLTK_USE_SYSTEM_JPEG) + IF(JPEG_FOUND) + SET(CMAKE_TEST_SPECIAL_LIBRARIES ${JPEG_LIBRARIES}) + SET(FLTK_JPEG_LIBRARIES ${JPEG_LIBRARIES}) + PERFORM_CMAKE_TEST(CMake/PlatformTests.cxx HAVE_LIBJPEG) + ENDIF(JPEG_FOUND) + # We build the fltk png +ELSE(FLTK_USE_SYSTEM_JPEG) + MARK_AS_ADVANCED(JPEG_INCLUDE_DIR) + MARK_AS_ADVANCED(JPEG_LIBRARY) +# SUBDIRS(jpeg) + SET(HAVE_LIBJPEG 1) + SET(FLTK_JPEG_LIBRARIES fltk_jpeg) + SET(FLTK_LIBRARIES "${FLTK_LIBRARIES};fltk_jpeg") + INCLUDE_DIRECTORIES("${CMAKE_CURRENT_SOURCE_DIR}/jpeg") +ENDIF(FLTK_USE_SYSTEM_JPEG) + +# Set an option to build the png library or not +OPTION(FLTK_USE_SYSTEM_PNG "Use's system png" OFF) +IF(FLTK_USE_SYSTEM_PNG) + IF(PNG_FOUND) + SET(CMAKE_TEST_SPECIAL_LIBRARIES ${PNG_LIBRARIES}) + SET(FLTK_PNG_LIBRARIES ${PNG_LIBRARIES}) + PERFORM_CMAKE_TEST(CMake/PlatformTests.cxx HAVE_LIBPNG) + PERFORM_CMAKE_TEST(CMake/PlatformTests.cxx HAVE_PNG_GET_VALID) + PERFORM_CMAKE_TEST(CMake/PlatformTests.cxx HAVE_PNG_SET_TRNS_TO_ALPHA) + SET(HAVE_PNG_H 1) + ENDIF(PNG_FOUND) + # We build the fltk png +ELSE(FLTK_USE_SYSTEM_PNG) + MARK_AS_ADVANCED(PNG_INCLUDE_DIR) + MARK_AS_ADVANCED(PNG_LIBRARY) +# SUBDIRS(png) + SET(HAVE_LIBPNG 1) + SET(HAVE_PNG_H 1) + SET(FLTK_PNG_LIBRARIES fltk_png) + SET(FLTK_LIBRARIES "${FLTK_LIBRARIES};fltk_png") + INCLUDE_DIRECTORIES("${CMAKE_CURRENT_SOURCE_DIR}/png") +ENDIF(FLTK_USE_SYSTEM_PNG) + +SET(FLTK_DATADIR "${CMAKE_INSTALL_PREFIX}/share/FLTK") +SET(FLTK_DOCDIR "${CMAKE_INSTALL_PREFIX}/share/doc/FLTK") + +# Write out configuration header file +CONFIGURE_FILE(${FLTK_SOURCE_DIR}/configh.cmake.in + ${FLTK_BINARY_DIR}/config.h) + +# On unix create symlinks for backward compatibility +SET(FLTK_CREATE_SYMLINKS 1) +IF(WIN32) + IF(NOT UNIX) + SET(FLTK_CREATE_SYMLINKS 0) + ENDIF(NOT UNIX) +ENDIF(WIN32) + +MACRO(SAFE_CREATE_SYMLINK SOURCE DESTINATION) + IF(EXISTS "${DESTINATION}") + ELSE(EXISTS "${DESTINATION}") + MESSAGE(STATUS "Create symlink from: \"${SOURCE}\" to \"${DESTINATION}\"") + # The quoting here does seems unnatural, but this is to prevent bug in CMake + EXEC_PROGRAM(ln ARGS + "-s \"${SOURCE}\" \"${DESTINATION}\"" OUTPUT_VARIABLE ln_output + RETURN_VALUE ln_retval) + IF("${ln_retval}" GREATER 0) + MESSAGE(FATAL_ERROR "Problem creatin symlink from \"${SOURCE}\" to \"${DESTINATION}\":\n${ln_output}") + ENDIF("${ln_retval}" GREATER 0) + ENDIF(EXISTS "${DESTINATION}") +ENDMACRO(SAFE_CREATE_SYMLINK SOURCE DESTINATION) + +# If this is out-of-source build, then copy FL directory +FILE(GLOB FLTK_HEADER_FILES "${FLTK_SOURCE_DIR}/FL/*.[hHr]") +FOREACH(file ${FLTK_HEADER_FILES}) + GET_FILENAME_COMPONENT(ext "${file}" EXT) + GET_FILENAME_COMPONENT(namewe "${file}" NAME_WE) + GET_FILENAME_COMPONENT(name "${file}" NAME) + STRING(COMPARE EQUAL "${ext}" ".h" lower_case_h) + STRING(COMPARE EQUAL "${ext}" ".H" upper_case_h) + IF(lower_case_h OR upper_case_h) + SET(outfile_h "${FLTK_BINARY_DIR}/FL/${namewe}.h") + SET(outfile_H "${FLTK_BINARY_DIR}/FL/${namewe}.H") + CONFIGURE_FILE("${file}" "${outfile_H}" COPYONLY IMMEDIATE) + CONFIGURE_FILE("${file}" "${outfile_h}" COPYONLY IMMEDIATE) +# IF(FLTK_CREATE_SYMLINKS) +# SAFE_CREATE_SYMLINK("${outfile_H}" "${outfile_h}") +# ENDIF(FLTK_CREATE_SYMLINKS) + ELSE(lower_case_h OR upper_case_h) + STRING(COMPARE EQUAL "${ext}" ".r" mac_resource_file) + IF(mac_resource_file) + SET(outfile "${FLTK_BINARY_DIR}/FL/${name}") + CONFIGURE_FILE("${file}" "${outfile}" COPYONLY IMMEDIATE) + ENDIF(mac_resource_file) + ENDIF(lower_case_h OR upper_case_h) +ENDFOREACH(file) + +IF(FLTK_CREATE_SYMLINKS) + SAFE_CREATE_SYMLINK( + "${FLTK_BINARY_DIR}/FL" + "${FLTK_BINARY_DIR}/Fl") + +# SAFE_CREATE_SYMLINK( +# "${FLTK_BINARY_DIR}/FL/gl.H" +# "${FLTK_BINARY_DIR}/FL/gl.h") + + # Create the symlinks + FILE(READ ${FLTK_SOURCE_DIR}/fltk.list.in SYMLINKSFILE) + STRING(REGEX MATCHALL "(l 0000 root sys .includedir/)([^(\n)])+" + SYMLINKS ${SYMLINKSFILE}) + FOREACH(var ${SYMLINKS} ) + IF("${var}" MATCHES ".H") + STRING(REGEX MATCH "(/F)([^(\n)])+" tmp ${var}) + STRING(REGEX MATCH "(/F)([^( )])+" in ${tmp}) + STRING(REGEX MATCH "( )([^(\n)])+" out ${tmp}) + STRING(REGEX REPLACE "( )" "" out ${out}) + SAFE_CREATE_SYMLINK("${FLTK_BINARY_DIR}/FL/${out}" "${FLTK_BINARY_DIR}/${in}") + ENDIF("${var}" MATCHES ".H") + ENDFOREACH(var) +ENDIF(FLTK_CREATE_SYMLINKS) + +# Set the fluid executable path +#UTILITY_SOURCE(FLUID_COMMAND fluid fluid fluid.cxx) +#SET(FLUID_COMMAND "${FLUID_COMMAND}" CACHE INTERNAL "" FORCE) + +# Include header files in fltk binary tree +INCLUDE_DIRECTORIES(${FLTK_BINARY_DIR}) + +# Do the build of fltk libraries and fluid +SUBDIRS(src) +#SUBDIRS(fluid) + + +# Set an option to build the examples and testing +OPTION(BUILD_EXAMPLES "Build the tests" ON) +IF(BUILD_EXAMPLES) +# SUBDIRS(test) +ENDIF(BUILD_EXAMPLES) + +OPTION(BUILD_TESTING "Build testing of FLTK" ON) +IF(BUILD_TESTING) + ENABLE_TESTING() + INCLUDE(Dart) +ENDIF(BUILD_TESTING) + +#----------------------------------------------------------------------------- +# Help outside projects build FLTK projects. +INCLUDE(CMakeExportBuildSettings) +EXPORT_LIBRARY_DEPENDENCIES(${FLTK_BINARY_DIR}/FLTKLibraryDepends.cmake) +CMAKE_EXPORT_BUILD_SETTINGS(${FLTK_BINARY_DIR}/FLTKBuildSettings.cmake) +SET(FL_MAJOR_VERSION "${FLTK_VERSION_MAJOR}") +SET(FL_MINOR_VERSION "${FLTK_VERSION_MINOR}") +SET(FL_PATCH_VERSION "${FLTK_VERSION_PATCH}") + +SET(CFLAGS "${CMAKE_C_FLAGS}") +SET(CXXFLAGS "${CMAKE_CXX_FLAGS}") +SET(CC "${CMAKE_C_COMPILER}") +SET(CXX "${CMAKE_CXX_COMPILER}") + +# For build tree usage +SET(FLTK_FLUID_COMMAND "${FLUID_COMMAND}") +SET(FLTK_LIBRARY_DEPENDS_FILE ${FLTK_BINARY_DIR}/FLTKLibraryDepends.cmake) +SET(FLTK_EXECUTABLE_DIRS ${EXECUTABLE_OUTPUT_PATH}) +SET(FLTK_LIBRARY_DIRS ${LIBRARY_OUTPUT_PATH}) +SET(FLTK_USE_FILE ${FLTK_SOURCE_DIR}/CMake/FLTKUse.cmake) +SET(FLTK_INCLUDE_DIRS "${FLTK_BINARY_DIR}/") +SET(FLTK_BUILD_SETTINGS_FILE ${FLTK_BINARY_DIR}/FLTKBuildSettings.cmake) +SET(prefix "${FLTK_BINARY_DIR}") +SET(exec_prefix "${prefix}") +SET(exec_prefix_set "no") +SET(bindir "${prefix}/bin") +SET(includedir "${prefix}") +SET(libdir "${prefix}/bin") +SET(srcdir "${FLTK_SOURCE_DIR}") + +CONFIGURE_FILE("${FLTK_SOURCE_DIR}/CMake/FLTKConfig.cmake.in" + "${FLTK_BINARY_DIR}/FLTKConfig.cmake" @ONLY IMMEDIATE) +CONFIGURE_FILE("${FLTK_SOURCE_DIR}/fltk-config.in" + "${FLTK_BINARY_DIR}/fltk-config" @ONLY IMMEDIATE) + +# For installed tree usage +SET(FLTK_FLUID_COMMAND "${CMAKE_INSTALL_PREFIX}/bin/fluid") +SET(FLTK_LIBRARY_DEPENDS_FILE ${CMAKE_INSTALL_PREFIX}/lib/FLTK-${FLTK_VERSION}/FLTKLibraryDepends.cmake) +SET(FLTK_EXECUTABLE_DIRS "${CMAKE_INSTALL_PREFIX}/bin") +SET(FLTK_LIBRARY_DIRS "${CMAKE_INSTALL_PREFIX}/lib") +SET(FLTK_USE_FILE "${CMAKE_INSTALL_PREFIX}/lib/FLTK-${FLTK_VERSION}/FLTKUse.cmake") +SET(FLTK_INCLUDE_DIRS "${CMAKE_INSTALL_PREFIX}/") +SET(FLTK_BUILD_SETTINGS_FILE ${CMAKE_INSTALL_PREFIX}/lib/FLTK-${FLTK_VERSION}/FLTKBuildSettings.cmake) +SET(prefix "${CMAKE_INSTALL_PREFIX}") +SET(exec_prefix "${prefix}") +SET(exec_prefix_set "no") +SET(bindir "${prefix}/bin") +SET(includedir "${prefix}") +SET(libdir "${prefix}/lib") +SET(srcdir ".") + +CONFIGURE_FILE("${FLTK_SOURCE_DIR}/CMake/FLTKConfig.cmake.in" + "${FLTK_BINARY_DIR}/CMake/FLTKConfig.cmake" @ONLY IMMEDIATE) +CONFIGURE_FILE("${FLTK_SOURCE_DIR}/fltk-config.in" + "${FLTK_BINARY_DIR}/CMake/fltk-config" @ONLY IMMEDIATE) + +INSTALL_FILES(/include/FL FILES ${FLTK_HEADER_FILES}) +INSTALL_FILES(/lib/FLTK-${FLTK_VERSION} FILES "${FLTK_SOURCE_DIR}/CMake/FLTKUse.cmake") +INSTALL_FILES(/lib/FLTK-${FLTK_VERSION} FILES "${FLTK_BINARY_DIR}/FLTKBuildSettings.cmake") +INSTALL_FILES(/lib/FLTK-${FLTK_VERSION} FILES "${FLTK_BINARY_DIR}/FLTKLibraryDepends.cmake") +INSTALL_FILES(/lib/FLTK-${FLTK_VERSION} FILES "${FLTK_BINARY_DIR}/CMake/FLTKConfig.cmake") diff --git a/plugins/zynaddsubfx/fltk/COPYING b/plugins/zynaddsubfx/fltk/COPYING new file mode 100644 index 000000000..0dd0e80d3 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/COPYING @@ -0,0 +1,528 @@ + FLTK License + December 11, 2001 + +The FLTK library and included programs are provided under the terms +of the GNU Library General Public License (LGPL) with the following +exceptions: + + 1. Modifications to the FLTK configure script, config + header file, and makefiles by themselves to support + a specific platform do not constitute a modified or + derivative work. + + The authors do request that such modifications be + contributed to the FLTK project - send all + contributions to "fltk-bugs@fltk.org". + + 2. Widgets that are subclassed from FLTK widgets do not + constitute a derivative work. + + 3. Static linking of applications and widgets to the + FLTK library does not constitute a derivative work + and does not require the author to provide source + code for the application or widget, use the shared + FLTK libraries, or link their applications or + widgets against a user-supplied version of FLTK. + + If you link the application or widget to a modified + version of FLTK, then the changes to FLTK must be + provided under the terms of the LGPL in sections + 1, 2, and 4. + + 4. You do not have to provide a copy of the FLTK license + with programs that are linked to the FLTK library, nor + do you have to identify the FLTK license in your + program or documentation as required by section 6 + of the LGPL. + + However, programs must still identify their use of FLTK. + The following example statement can be included in user + documentation to satisfy this requirement: + + [program/widget] is based in part on the work of + the FLTK project (http://www.fltk.org). + +----------------------------------------------------------------------- + + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + [This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/plugins/zynaddsubfx/fltk/CREDITS b/plugins/zynaddsubfx/fltk/CREDITS new file mode 100644 index 000000000..4a0499879 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/CREDITS @@ -0,0 +1,54 @@ +CREDITS - Fast Light Tool Kit (FLTK) Version 1.1.5 +-------------------------------------------------- + + This file lists the people responsible for the toolkit you + are now using. If you've looking for your name in lights + but we've forgotten you here, please send an email to + "fltk-bugs@fltk.org" and we'll update this file accordingly. + + +CORE DEVELOPERS + + The following people do the day-to-day development of FLTK: + + Craig P. Earls + Curtis Edwards (trilec@users.sourceforge.net) + Gustavo Hime (hime@users.sourceforge.net) + Talbot Hughes + Robert Kesterson (robertk@users.sourceforge.net) + Matthias Melcher (matthias@users.sourceforge.net) + James Dean Palmer (jamespalmer@users.sourceforge.net) + Vincent Penne (vincentp@users.sourceforge.net) + Bill Spitzak (spitzak@users.sourceforge.net) + Michael Sweet (easysw@users.sourceforge.net) + Carl Thompson (clip@users.sourceforge.net) + Nafees Bin Zafar (nafees@users.sourceforge.net) + + +OTHER CONTRIBUTORS + + The following people have contributed fixes or enhancements + for FLTK: + + Teun Burgers + Paul Chambers + Fabien Costantini + Stephen Davies + Yuri D'Elia + Greg Ercolano + Yuri Fedorchenko + George Garvey + Mikael Hultgren + Stuart Levy + Howard Lightstone + Mike Lindner + Alexander Mai + Alexander Rabi + James Roth + Albrecht Schlosser + Andrea Suatoni + Paul Sydney + Aaron Ucko + Emanuele Vicentini + Jim Wilson + Ken Yarnall diff --git a/plugins/zynaddsubfx/fltk/FL/Enumerations.H b/plugins/zynaddsubfx/fltk/FL/Enumerations.H new file mode 100644 index 000000000..fec12837d --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Enumerations.H @@ -0,0 +1,456 @@ +// +// "$Id: Enumerations.H 6096 2008-04-12 04:18:58Z mike $" +// +// Enumerations for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Enumerations_H +#define Fl_Enumerations_H + +# include "Fl_Export.H" + + +// +// The FLTK version number; this is changed slightly from the beta versions +// because the old "const double" definition would not allow for conditional +// compilation... +// +// FL_VERSION is a double that describes the major and minor version numbers. +// Version 1.1 is actually stored as 1.01 to allow for more than 9 minor +// releases. +// +// The FL_MAJOR_VERSION, FL_MINOR_VERSION, and FL_PATCH_VERSION constants +// give the integral values for the major, minor, and patch releases +// respectively. +// + +#define FL_MAJOR_VERSION 1 +#define FL_MINOR_VERSION 1 +#define FL_PATCH_VERSION 9 +#define FL_VERSION ((double)FL_MAJOR_VERSION + \ + (double)FL_MINOR_VERSION * 0.01 + \ + (double)FL_PATCH_VERSION * 0.0001) + +typedef unsigned char uchar; +typedef unsigned long ulong; + +enum Fl_Event { // events + FL_NO_EVENT = 0, + FL_PUSH = 1, + FL_RELEASE = 2, + FL_ENTER = 3, + FL_LEAVE = 4, + FL_DRAG = 5, + FL_FOCUS = 6, + FL_UNFOCUS = 7, + FL_KEYDOWN = 8, + FL_KEYUP = 9, + FL_CLOSE = 10, + FL_MOVE = 11, + FL_SHORTCUT = 12, + FL_DEACTIVATE = 13, + FL_ACTIVATE = 14, + FL_HIDE = 15, + FL_SHOW = 16, + FL_PASTE = 17, + FL_SELECTIONCLEAR = 18, + FL_MOUSEWHEEL = 19, + FL_DND_ENTER = 20, + FL_DND_DRAG = 21, + FL_DND_LEAVE = 22, + FL_DND_RELEASE = 23 +}; +#define FL_KEYBOARD FL_KEYDOWN + +enum Fl_When { // Fl_Widget::when(): + FL_WHEN_NEVER = 0, + FL_WHEN_CHANGED = 1, + FL_WHEN_RELEASE = 4, + FL_WHEN_RELEASE_ALWAYS= 6, + FL_WHEN_ENTER_KEY = 8, + FL_WHEN_ENTER_KEY_ALWAYS=10, + FL_WHEN_ENTER_KEY_CHANGED=11, + FL_WHEN_NOT_CHANGED = 2 // modifier bit to disable changed() test +}; + +// Fl::event_key() and Fl::get_key(n) (use ascii letters for all other keys): +#define FL_Button 0xfee8 // use Fl_Button+FL_*_MOUSE +#define FL_BackSpace 0xff08 +#define FL_Tab 0xff09 +#define FL_Enter 0xff0d +#define FL_Pause 0xff13 +#define FL_Scroll_Lock 0xff14 +#define FL_Escape 0xff1b +#define FL_Home 0xff50 +#define FL_Left 0xff51 +#define FL_Up 0xff52 +#define FL_Right 0xff53 +#define FL_Down 0xff54 +#define FL_Page_Up 0xff55 +#define FL_Page_Down 0xff56 +#define FL_End 0xff57 +#define FL_Print 0xff61 +#define FL_Insert 0xff63 +#define FL_Menu 0xff67 // the "menu/apps" key on XFree86 +#define FL_Help 0xff68 // the 'help' key on Mac keyboards +#define FL_Num_Lock 0xff7f +#define FL_KP 0xff80 // use FL_KP+'x' for 'x' on numeric keypad +#define FL_KP_Enter 0xff8d // same as Fl_KP+'\r' +#define FL_KP_Last 0xffbd // use to range-check keypad +#define FL_F 0xffbd // use FL_F+n for function key n +#define FL_F_Last 0xffe0 // use to range-check function keys +#define FL_Shift_L 0xffe1 +#define FL_Shift_R 0xffe2 +#define FL_Control_L 0xffe3 +#define FL_Control_R 0xffe4 +#define FL_Caps_Lock 0xffe5 +#define FL_Meta_L 0xffe7 // the left MSWindows key on XFree86 +#define FL_Meta_R 0xffe8 // the right MSWindows key on XFree86 +#define FL_Alt_L 0xffe9 +#define FL_Alt_R 0xffea +#define FL_Delete 0xffff + +// Fl::event_button(): +#define FL_LEFT_MOUSE 1 +#define FL_MIDDLE_MOUSE 2 +#define FL_RIGHT_MOUSE 3 + +// Fl::event_state(): +#define FL_SHIFT 0x00010000 +#define FL_CAPS_LOCK 0x00020000 +#define FL_CTRL 0x00040000 +#define FL_ALT 0x00080000 +#define FL_NUM_LOCK 0x00100000 // most X servers do this? +#define FL_META 0x00400000 // correct for XFree86 +#define FL_SCROLL_LOCK 0x00800000 // correct for XFree86 +#define FL_BUTTON1 0x01000000 +#define FL_BUTTON2 0x02000000 +#define FL_BUTTON3 0x04000000 +#define FL_BUTTONS 0x7f000000 // All possible buttons +#define FL_BUTTON(n) (0x00800000<<(n)) + +#ifdef __APPLE__ +# define FL_COMMAND FL_META +#else +# define FL_COMMAND FL_CTRL +#endif // __APPLE__ + +enum Fl_Boxtype { // boxtypes (if you change these you must fix fl_boxtype.C): + FL_NO_BOX = 0, FL_FLAT_BOX, + + FL_UP_BOX, FL_DOWN_BOX, + FL_UP_FRAME, FL_DOWN_FRAME, + FL_THIN_UP_BOX, FL_THIN_DOWN_BOX, + FL_THIN_UP_FRAME, FL_THIN_DOWN_FRAME, + FL_ENGRAVED_BOX, FL_EMBOSSED_BOX, + FL_ENGRAVED_FRAME, FL_EMBOSSED_FRAME, + FL_BORDER_BOX, _FL_SHADOW_BOX, + FL_BORDER_FRAME, _FL_SHADOW_FRAME, + _FL_ROUNDED_BOX, _FL_RSHADOW_BOX, + _FL_ROUNDED_FRAME, _FL_RFLAT_BOX, + _FL_ROUND_UP_BOX, _FL_ROUND_DOWN_BOX, + _FL_DIAMOND_UP_BOX, _FL_DIAMOND_DOWN_BOX, + _FL_OVAL_BOX, _FL_OSHADOW_BOX, + _FL_OVAL_FRAME, _FL_OFLAT_BOX, + _FL_PLASTIC_UP_BOX, _FL_PLASTIC_DOWN_BOX, + _FL_PLASTIC_UP_FRAME, _FL_PLASTIC_DOWN_FRAME, + _FL_PLASTIC_THIN_UP_BOX, _FL_PLASTIC_THIN_DOWN_BOX, + _FL_PLASTIC_ROUND_UP_BOX, _FL_PLASTIC_ROUND_DOWN_BOX, + _FL_GTK_UP_BOX, _FL_GTK_DOWN_BOX, + _FL_GTK_UP_FRAME, _FL_GTK_DOWN_FRAME, + _FL_GTK_THIN_UP_BOX, _FL_GTK_THIN_DOWN_BOX, + _FL_GTK_THIN_UP_FRAME, _FL_GTK_THIN_DOWN_FRAME, + _FL_GTK_ROUND_UP_BOX, _FL_GTK_ROUND_DOWN_BOX, + FL_FREE_BOXTYPE +}; +extern FL_EXPORT Fl_Boxtype fl_define_FL_ROUND_UP_BOX(); +#define FL_ROUND_UP_BOX fl_define_FL_ROUND_UP_BOX() +#define FL_ROUND_DOWN_BOX (Fl_Boxtype)(fl_define_FL_ROUND_UP_BOX()+1) +extern FL_EXPORT Fl_Boxtype fl_define_FL_SHADOW_BOX(); +#define FL_SHADOW_BOX fl_define_FL_SHADOW_BOX() +#define FL_SHADOW_FRAME (Fl_Boxtype)(fl_define_FL_SHADOW_BOX()+2) +extern FL_EXPORT Fl_Boxtype fl_define_FL_ROUNDED_BOX(); +#define FL_ROUNDED_BOX fl_define_FL_ROUNDED_BOX() +#define FL_ROUNDED_FRAME (Fl_Boxtype)(fl_define_FL_ROUNDED_BOX()+2) +extern FL_EXPORT Fl_Boxtype fl_define_FL_RFLAT_BOX(); +#define FL_RFLAT_BOX fl_define_FL_RFLAT_BOX() +extern FL_EXPORT Fl_Boxtype fl_define_FL_RSHADOW_BOX(); +#define FL_RSHADOW_BOX fl_define_FL_RSHADOW_BOX() +extern FL_EXPORT Fl_Boxtype fl_define_FL_DIAMOND_BOX(); +#define FL_DIAMOND_UP_BOX fl_define_FL_DIAMOND_BOX() +#define FL_DIAMOND_DOWN_BOX (Fl_Boxtype)(fl_define_FL_DIAMOND_BOX()+1) +extern FL_EXPORT Fl_Boxtype fl_define_FL_OVAL_BOX(); +#define FL_OVAL_BOX fl_define_FL_OVAL_BOX() +#define FL_OSHADOW_BOX (Fl_Boxtype)(fl_define_FL_OVAL_BOX()+1) +#define FL_OVAL_FRAME (Fl_Boxtype)(fl_define_FL_OVAL_BOX()+2) +#define FL_OFLAT_BOX (Fl_Boxtype)(fl_define_FL_OVAL_BOX()+3) + +extern FL_EXPORT Fl_Boxtype fl_define_FL_PLASTIC_UP_BOX(); +#define FL_PLASTIC_UP_BOX fl_define_FL_PLASTIC_UP_BOX() +#define FL_PLASTIC_DOWN_BOX (Fl_Boxtype)(fl_define_FL_PLASTIC_UP_BOX()+1) +#define FL_PLASTIC_UP_FRAME (Fl_Boxtype)(fl_define_FL_PLASTIC_UP_BOX()+2) +#define FL_PLASTIC_DOWN_FRAME (Fl_Boxtype)(fl_define_FL_PLASTIC_UP_BOX()+3) +#define FL_PLASTIC_THIN_UP_BOX (Fl_Boxtype)(fl_define_FL_PLASTIC_UP_BOX()+4) +#define FL_PLASTIC_THIN_DOWN_BOX (Fl_Boxtype)(fl_define_FL_PLASTIC_UP_BOX()+5) +#define FL_PLASTIC_ROUND_UP_BOX (Fl_Boxtype)(fl_define_FL_PLASTIC_UP_BOX()+6) +#define FL_PLASTIC_ROUND_DOWN_BOX (Fl_Boxtype)(fl_define_FL_PLASTIC_UP_BOX()+7) + +extern FL_EXPORT Fl_Boxtype fl_define_FL_GTK_UP_BOX(); +#define FL_GTK_UP_BOX fl_define_FL_GTK_UP_BOX() +#define FL_GTK_DOWN_BOX (Fl_Boxtype)(fl_define_FL_GTK_UP_BOX()+1) +#define FL_GTK_UP_FRAME (Fl_Boxtype)(fl_define_FL_GTK_UP_BOX()+2) +#define FL_GTK_DOWN_FRAME (Fl_Boxtype)(fl_define_FL_GTK_UP_BOX()+3) +#define FL_GTK_THIN_UP_BOX (Fl_Boxtype)(fl_define_FL_GTK_UP_BOX()+4) +#define FL_GTK_THIN_DOWN_BOX (Fl_Boxtype)(fl_define_FL_GTK_UP_BOX()+5) +#define FL_GTK_THIN_UP_FRAME (Fl_Boxtype)(fl_define_FL_GTK_UP_BOX()+6) +#define FL_GTK_THIN_DOWN_FRAME (Fl_Boxtype)(fl_define_FL_GTK_UP_BOX()+7) +#define FL_GTK_ROUND_UP_BOX (Fl_Boxtype)(fl_define_FL_GTK_UP_BOX()+8) +#define FL_GTK_ROUND_DOWN_BOX (Fl_Boxtype)(fl_define_FL_GTK_UP_BOX()+9) + +// conversions of box types to other boxtypes: +inline Fl_Boxtype fl_box(Fl_Boxtype b) { + return (Fl_Boxtype)((b1)?b:(b-2)); +} +inline Fl_Boxtype fl_down(Fl_Boxtype b) { + return (Fl_Boxtype)((b lines) Fl_Browser_::display(find_line(lines)); + else Fl_Browser_::display(find_line(n)); + } + + // for back compatability only: + void replace(int a, const char* b) {text(a, b);} + void display(int, int=1); +}; + +#endif + +// +// End of "$Id: Fl_Browser.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Browser_.H b/plugins/zynaddsubfx/fltk/FL/Fl_Browser_.H new file mode 100644 index 000000000..3469be40c --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Browser_.H @@ -0,0 +1,154 @@ +// +// "$Id: Fl_Browser_.H 4879 2006-03-28 23:27:20Z matt $" +// +// Common browser header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// This is the base class for browsers. To be useful it must +// be subclassed and several virtual functions defined. The +// Forms-compatable browser and the file chooser's browser are +// subclassed off of this. + +// Yes, I know this should be a template... + +#ifndef Fl_Browser__H +#define Fl_Browser__H + +#ifndef Fl_Group_H +#include "Fl_Group.H" +#endif +#include "Fl_Scrollbar.H" + +#define FL_NORMAL_BROWSER 0 +#define FL_SELECT_BROWSER 1 +#define FL_HOLD_BROWSER 2 +#define FL_MULTI_BROWSER 3 + +class FL_EXPORT Fl_Browser_ : public Fl_Group { + int position_; // where user wants it scrolled to + int real_position_; // the current vertical scrolling position + int hposition_; // where user wants it panned to + int real_hposition_; // the current horizontal scrolling position + int offset_; // how far down top_ item the real_position is + int max_width; // widest object seen so far + uchar has_scrollbar_; // which scrollbars are enabled + uchar textfont_, textsize_; + unsigned textcolor_; + void* top_; // which item scrolling position is in + void* selection_; // which is selected (except for FL_MULTI_BROWSER) + void *redraw1,*redraw2; // minimal update pointers + void* max_width_item; // which item has max_width_ + + static int scrollbar_width_; + + void update_top(); + +protected: + + // All of the following must be supplied by the subclass: + virtual void *item_first() const = 0; + virtual void *item_next(void *) const = 0; + virtual void *item_prev(void *) const = 0; + virtual int item_height(void *) const = 0; + virtual int item_width(void *) const = 0; + virtual int item_quick_height(void *) const ; + virtual void item_draw(void *,int,int,int,int) const = 0; + // you don't have to provide these but it may help speed it up: + virtual int full_width() const ; // current width of all items + virtual int full_height() const ; // current height of all items + virtual int incr_height() const ; // average height of an item + // These only need to be done by subclass if you want a multi-browser: + virtual void item_select(void *,int=1); + virtual int item_selected(void *) const ; + + // things the subclass may want to call: + void *top() const {return top_;} + void *selection() const {return selection_;} + void new_list(); // completely clobber all data, as though list replaced + void deleting(void *a); // get rid of any pointers to a + void replacing(void *a,void *b); // change a pointers to b + void swapping(void *a,void *b); // exchange pointers a and b + void inserting(void *a,void *b); // insert b near a + int displayed(void *) const ; // true if this line is visible + void redraw_line(void *); // minimal update, no change in size + void redraw_lines() {damage(FL_DAMAGE_SCROLL);} // redraw all of them + void bbox(int&,int&,int&,int&) const; + int leftedge() const; // x position after scrollbar & border + void *find_item(int my); // item under mouse + void draw(int,int,int,int); + int handle(int,int,int,int,int); + + void draw(); + Fl_Browser_(int,int,int,int,const char * = 0); + +public: + + Fl_Scrollbar scrollbar; // Vertical scrollbar + Fl_Scrollbar hscrollbar; // Horizontal scrollbar + + int handle(int); + void resize(int,int,int,int); + + int select(void *,int=1,int docallbacks=0); + int select_only(void *,int docallbacks=0); + int deselect(int docallbacks=0); + int position() const {return position_;} + int hposition() const {return hposition_;} + void position(int); // scroll to here + void hposition(int); // pan to here + void display(void*); // scroll so this item is shown + + uchar has_scrollbar() const {return has_scrollbar_;} + void has_scrollbar(uchar i) {has_scrollbar_ = i;} + enum { // values for has_scrollbar() + HORIZONTAL = 1, + VERTICAL = 2, + BOTH = 3, + ALWAYS_ON = 4, + HORIZONTAL_ALWAYS = 5, + VERTICAL_ALWAYS = 6, + BOTH_ALWAYS = 7 + }; + + Fl_Font textfont() const {return (Fl_Font)textfont_;} + void textfont(uchar s) {textfont_ = s;} + uchar textsize() const {return textsize_;} + void textsize(uchar s) {textsize_ = s;} + Fl_Color textcolor() const {return (Fl_Color)textcolor_;} + void textcolor(unsigned n) {textcolor_ = n;} + + static void scrollbar_width(int b) {scrollbar_width_ = b;} + static int scrollbar_width() {return scrollbar_width_;} + + // for back compatability: + void scrollbar_right() {scrollbar.align(FL_ALIGN_RIGHT);} + void scrollbar_left() {scrollbar.align(FL_ALIGN_LEFT);} + +}; + +#endif + +// +// End of "$Id: Fl_Browser_.H 4879 2006-03-28 23:27:20Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Button.H b/plugins/zynaddsubfx/fltk/FL/Fl_Button.H new file mode 100644 index 000000000..15510b137 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Button.H @@ -0,0 +1,78 @@ +// +// "$Id: Fl_Button.H 4288 2005-04-16 00:13:17Z mike $" +// +// Button header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Button_H +#define Fl_Button_H + +#ifndef Fl_Widget_H +#include "Fl_Widget.H" +#endif + +// values for type() +#define FL_NORMAL_BUTTON 0 +#define FL_TOGGLE_BUTTON 1 +#define FL_RADIO_BUTTON (FL_RESERVED_TYPE+2) +#define FL_HIDDEN_BUTTON 3 // for Forms compatability + +extern FL_EXPORT int fl_old_shortcut(const char*); + +class FL_EXPORT Fl_Button : public Fl_Widget { + + int shortcut_; + char value_; + char oldval; + uchar down_box_; + +protected: + + virtual void draw(); + +public: + + virtual int handle(int); + Fl_Button(int,int,int,int,const char * = 0); + int value(int); + char value() const {return value_;} + int set() {return value(1);} + int clear() {return value(0);} + void setonly(); // this should only be called on FL_RADIO_BUTTONs + int shortcut() const {return shortcut_;} + void shortcut(int s) {shortcut_ = s;} + Fl_Boxtype down_box() const {return (Fl_Boxtype)down_box_;} + void down_box(Fl_Boxtype b) {down_box_ = b;} + + // back compatability: + void shortcut(const char *s) {shortcut(fl_old_shortcut(s));} + Fl_Color down_color() const {return selection_color();} + void down_color(unsigned c) {selection_color(c);} +}; + +#endif + +// +// End of "$Id: Fl_Button.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Chart.H b/plugins/zynaddsubfx/fltk/FL/Fl_Chart.H new file mode 100644 index 000000000..a70593099 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Chart.H @@ -0,0 +1,93 @@ +// +// "$Id: Fl_Chart.H 4288 2005-04-16 00:13:17Z mike $" +// +// Forms chart header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Chart_H +#define Fl_Chart_H + +#ifndef Fl_Widget_H +#include "Fl_Widget.H" +#endif + +// values for type() +#define FL_BAR_CHART 0 +#define FL_HORBAR_CHART 1 +#define FL_LINE_CHART 2 +#define FL_FILL_CHART 3 +#define FL_SPIKE_CHART 4 +#define FL_PIE_CHART 5 +#define FL_SPECIALPIE_CHART 6 + +#define FL_FILLED_CHART FL_FILL_CHART // compatibility + +#define FL_CHART_MAX 128 +#define FL_CHART_LABEL_MAX 18 + +struct FL_CHART_ENTRY { + float val; + unsigned col; + char str[FL_CHART_LABEL_MAX+1]; +}; + +class FL_EXPORT Fl_Chart : public Fl_Widget { + int numb; + int maxnumb; + int sizenumb; + FL_CHART_ENTRY *entries; + double min,max; + uchar autosize_; + uchar textfont_,textsize_; + unsigned textcolor_; +protected: + void draw(); +public: + Fl_Chart(int,int,int,int,const char * = 0); + ~Fl_Chart(); + void clear(); + void add(double, const char * =0, unsigned=0); + void insert(int, double, const char * =0, unsigned=0); + void replace(int, double, const char * =0, unsigned=0); + void bounds(double *a,double *b) const {*a = min; *b = max;} + void bounds(double a,double b); + int size() const {return numb;} + void size(int W, int H) { Fl_Widget::size(W, H); } + int maxsize() const {return maxnumb;} + void maxsize(int); + Fl_Font textfont() const {return (Fl_Font)textfont_;} + void textfont(uchar s) {textfont_ = s;} + uchar textsize() const {return textsize_;} + void textsize(uchar s) {textsize_ = s;} + Fl_Color textcolor() const {return (Fl_Color)textcolor_;} + void textcolor(unsigned n) {textcolor_ = n;} + uchar autosize() const {return autosize_;} + void autosize(uchar n) {autosize_ = n;} +}; + +#endif + +// +// End of "$Id: Fl_Chart.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Check_Browser.H b/plugins/zynaddsubfx/fltk/FL/Fl_Check_Browser.H new file mode 100644 index 000000000..b3c741d33 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Check_Browser.H @@ -0,0 +1,103 @@ +// +// "$Id: Fl_Check_Browser.H 5979 2007-11-19 15:46:24Z matt $" +// +// Fl_Check_Browser header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Check_Browser_H +#define Fl_Check_Browser_H + +#include "Fl.H" +#include "Fl_Browser_.H" + +class FL_EXPORT Fl_Check_Browser : public Fl_Browser_ { + /* required routines for Fl_Browser_ subclass: */ + + void *item_first() const; + void *item_next(void *) const; + void *item_prev(void *) const; + int item_height(void *) const; + int item_width(void *) const; + void item_draw(void *, int, int, int, int) const; + void item_select(void *, int); + int item_selected(void *) const; + + /* private data */ + + public: // IRIX 5.3 C++ compiler doesn't support private structures... + + struct cb_item { + cb_item *next; + cb_item *prev; + char checked; + char selected; + char *text; + }; + + private: + + cb_item *first; + cb_item *last; + cb_item *cache; + int cached_item; + int nitems_; + int nchecked_; + cb_item *find_item(int) const; + int lineno(cb_item *) const; + + public: + + Fl_Check_Browser(int x, int y, int w, int h, const char *l = 0); + ~Fl_Check_Browser() { clear(); } + int add(char *s); // add an (unchecked) item + int add(char *s, int b); // add an item and set checked + // both return the new nitems() + int remove(int item); // delete an item. Returns nitems() + + // inline const char * methods to avoid breaking binary compatibility... + int add(const char *s) { return add((char *)s); } + int add(const char *s, int b) { return add((char *)s, b); } + + void clear(); // delete all items + int nitems() const { return nitems_; } + int nchecked() const { return nchecked_; } + int checked(int item) const; + void checked(int item, int b); + void set_checked(int item) { checked(item, 1); } + void check_all(); + void check_none(); + int value() const; // currently selected item + char *text(int item) const; // returns pointer to internal buffer + + protected: + + int handle(int); +}; + +#endif // Fl_Check_Browser_H + +// +// End of "$Id: Fl_Check_Browser.H 5979 2007-11-19 15:46:24Z matt $". +// + diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Check_Button.H b/plugins/zynaddsubfx/fltk/FL/Fl_Check_Button.H new file mode 100644 index 000000000..4064cf5b9 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Check_Button.H @@ -0,0 +1,42 @@ +// +// "$Id: Fl_Check_Button.H 4288 2005-04-16 00:13:17Z mike $" +// +// Check button header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Check_Button_H +#define Fl_Check_Button_H + +#include "Fl_Light_Button.H" + +class FL_EXPORT Fl_Check_Button : public Fl_Light_Button { +public: + Fl_Check_Button(int x,int y,int w,int h,const char *l = 0); +}; + +#endif + +// +// End of "$Id: Fl_Check_Button.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Choice.H b/plugins/zynaddsubfx/fltk/FL/Fl_Choice.H new file mode 100644 index 000000000..64e59b68f --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Choice.H @@ -0,0 +1,48 @@ +// +// "$Id: Fl_Choice.H 4288 2005-04-16 00:13:17Z mike $" +// +// Choice header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Choice_H +#define Fl_Choice_H + +#include "Fl_Menu_.H" + +class FL_EXPORT Fl_Choice : public Fl_Menu_ { +protected: + void draw(); +public: + int handle(int); + Fl_Choice(int,int,int,int,const char * = 0); + int value(const Fl_Menu_Item*); + int value(int i); + int value() const {return Fl_Menu_::value();} +}; + +#endif + +// +// End of "$Id: Fl_Choice.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Clock.H b/plugins/zynaddsubfx/fltk/FL/Fl_Clock.H new file mode 100644 index 000000000..261470c9f --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Clock.H @@ -0,0 +1,75 @@ +// +// "$Id: Fl_Clock.H 4288 2005-04-16 00:13:17Z mike $" +// +// Clock header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Clock_H +#define Fl_Clock_H + +#ifndef Fl_Widget_H +#include "Fl_Widget.H" +#endif + +// values for type: +#define FL_SQUARE_CLOCK 0 +#define FL_ROUND_CLOCK 1 +#define FL_ANALOG_CLOCK FL_SQUARE_CLOCK +#define FL_DIGITAL_CLOCK FL_SQUARE_CLOCK // nyi + +// a Fl_Clock_Output can be used to display a program-supplied time: + +class FL_EXPORT Fl_Clock_Output : public Fl_Widget { + int hour_, minute_, second_; + ulong value_; + void drawhands(Fl_Color,Fl_Color); // part of draw +protected: + void draw(int, int, int, int); + void draw(); +public: + Fl_Clock_Output(int x,int y,int w,int h, const char *l = 0); + void value(ulong v); // set to this Unix time + void value(int,int,int); // set hour, minute, second + ulong value() const {return value_;} + int hour() const {return hour_;} + int minute() const {return minute_;} + int second() const {return second_;} +}; + +// a Fl_Clock displays the current time always by using a timeout: + +class FL_EXPORT Fl_Clock : public Fl_Clock_Output { +public: + int handle(int); + void update(); + Fl_Clock(int x,int y,int w,int h, const char *l = 0); + Fl_Clock(uchar t,int x,int y,int w,int h, const char *l); + ~Fl_Clock(); +}; + +#endif + +// +// End of "$Id: Fl_Clock.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Color_Chooser.H b/plugins/zynaddsubfx/fltk/FL/Fl_Color_Chooser.H new file mode 100644 index 000000000..2ef725063 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Color_Chooser.H @@ -0,0 +1,104 @@ +// +// "$Id: Fl_Color_Chooser.H 4288 2005-04-16 00:13:17Z mike $" +// +// Color chooser header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// The color chooser object and the color chooser popup. The popup +// is just a window containing a single color chooser and some boxes +// to indicate the current and cancelled color. + +#ifndef Fl_Color_Chooser_H +#define Fl_Color_Chooser_H + +#include +#include +#include +#include +#include + +class FL_EXPORT Flcc_HueBox : public Fl_Widget { + int px, py; +protected: + void draw(); + int handle_key(int); +public: + int handle(int); + Flcc_HueBox(int X, int Y, int W, int H) : Fl_Widget(X,Y,W,H) { + px = py = 0;} +}; + +class FL_EXPORT Flcc_ValueBox : public Fl_Widget { + int py; +protected: + void draw(); + int handle_key(int); +public: + int handle(int); + Flcc_ValueBox(int X, int Y, int W, int H) : Fl_Widget(X,Y,W,H) { + py = 0;} +}; + +class FL_EXPORT Flcc_Value_Input : public Fl_Value_Input { +public: + int format(char*); + Flcc_Value_Input(int X, int Y, int W, int H) : Fl_Value_Input(X,Y,W,H) {} +}; + +class FL_EXPORT Fl_Color_Chooser : public Fl_Group { + Flcc_HueBox huebox; + Flcc_ValueBox valuebox; + Fl_Choice choice; + Flcc_Value_Input rvalue; + Flcc_Value_Input gvalue; + Flcc_Value_Input bvalue; + Fl_Box resize_box; + double hue_, saturation_, value_; + double r_, g_, b_; + void set_valuators(); + static void rgb_cb(Fl_Widget*, void*); + static void mode_cb(Fl_Widget*, void*); +public: + int mode() {return choice.value();} + double hue() const {return hue_;} + double saturation() const {return saturation_;} + double value() const {return value_;} + double r() const {return r_;} + double g() const {return g_;} + double b() const {return b_;} + int hsv(double,double,double); + int rgb(double,double,double); + static void hsv2rgb(double, double, double,double&,double&,double&); + static void rgb2hsv(double, double, double,double&,double&,double&); + Fl_Color_Chooser(int,int,int,int,const char* = 0); +}; + +FL_EXPORT int fl_color_chooser(const char* name, double& r, double& g, double& b); +FL_EXPORT int fl_color_chooser(const char* name, uchar& r, uchar& g, uchar& b); + +#endif + +// +// End of "$Id: Fl_Color_Chooser.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Counter.H b/plugins/zynaddsubfx/fltk/FL/Fl_Counter.H new file mode 100644 index 000000000..73781a8b8 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Counter.H @@ -0,0 +1,76 @@ +// +// "$Id: Fl_Counter.H 4288 2005-04-16 00:13:17Z mike $" +// +// Counter header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// A numerical value with up/down step buttons. From Forms. + +#ifndef Fl_Counter_H +#define Fl_Counter_H + +#ifndef Fl_Valuator_H +#include "Fl_Valuator.H" +#endif + +// values for type(): +#define FL_NORMAL_COUNTER 0 +#define FL_SIMPLE_COUNTER 1 + +class FL_EXPORT Fl_Counter : public Fl_Valuator { + + uchar textfont_, textsize_; + unsigned textcolor_; + double lstep_; + uchar mouseobj; + static void repeat_callback(void *); + int calc_mouseobj(); + void increment_cb(); + +protected: + + void draw(); + +public: + + int handle(int); + Fl_Counter(int,int,int,int,const char * = 0); + ~Fl_Counter(); + void lstep(double a) {lstep_ = a;} + void step(double a,double b) {Fl_Valuator::step(a); lstep_ = b;} + void step(double a) {Fl_Valuator::step(a);} + Fl_Font textfont() const {return (Fl_Font)textfont_;} + void textfont(uchar s) {textfont_ = s;} + uchar textsize() const {return textsize_;} + void textsize(uchar s) {textsize_ = s;} + Fl_Color textcolor() const {return (Fl_Color)textcolor_;} + void textcolor(unsigned s) {textcolor_ = s;} + +}; + +#endif + +// +// End of "$Id: Fl_Counter.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Dial.H b/plugins/zynaddsubfx/fltk/FL/Fl_Dial.H new file mode 100644 index 000000000..f067036ff --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Dial.H @@ -0,0 +1,67 @@ +// +// "$Id: Fl_Dial.H 4288 2005-04-16 00:13:17Z mike $" +// +// Dial header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Dial_H +#define Fl_Dial_H + +#ifndef Fl_Valuator_H +#include "Fl_Valuator.H" +#endif + +// values for type(): +#define FL_NORMAL_DIAL 0 +#define FL_LINE_DIAL 1 +#define FL_FILL_DIAL 2 + +class FL_EXPORT Fl_Dial : public Fl_Valuator { + + short a1,a2; + +protected: + + // these allow subclasses to put the dial in a smaller area: + void draw(int, int, int, int); + int handle(int, int, int, int, int); + void draw(); + +public: + + int handle(int); + Fl_Dial(int x,int y,int w,int h, const char *l = 0); + short angle1() const {return a1;} + void angle1(short a) {a1 = a;} + short angle2() const {return a2;} + void angle2(short a) {a2 = a;} + void angles(short a, short b) {a1 = a; a2 = b;} + +}; + +#endif + +// +// End of "$Id: Fl_Dial.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Double_Window.H b/plugins/zynaddsubfx/fltk/FL/Fl_Double_Window.H new file mode 100644 index 000000000..635c7cb3c --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Double_Window.H @@ -0,0 +1,54 @@ +// +// "$Id: Fl_Double_Window.H 4288 2005-04-16 00:13:17Z mike $" +// +// Double-buffered window header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Double_Window_H +#define Fl_Double_Window_H + +#include "Fl_Window.H" + +class FL_EXPORT Fl_Double_Window : public Fl_Window { +protected: + void flush(int eraseoverlay); + char force_doublebuffering_; // force db, even if the OS already buffers windows (overlays need that on MacOS and Windows2000) +public: + void show(); + void show(int a, char **b) {Fl_Window::show(a,b);} + void flush(); + void resize(int,int,int,int); + void hide(); + ~Fl_Double_Window(); + Fl_Double_Window(int W, int H, const char *l = 0) + : Fl_Window(W,H,l), force_doublebuffering_(0) { type(FL_DOUBLE_WINDOW); } + Fl_Double_Window(int X, int Y, int W, int H, const char *l = 0) + : Fl_Window(X,Y,W,H,l), force_doublebuffering_(0) { type(FL_DOUBLE_WINDOW); } +}; + +#endif + +// +// End of "$Id: Fl_Double_Window.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Export.H b/plugins/zynaddsubfx/fltk/FL/Fl_Export.H new file mode 100644 index 000000000..267f63222 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Export.H @@ -0,0 +1,49 @@ +/* + * "$Id: Fl_Export.H 4288 2005-04-16 00:13:17Z mike $" + * + * WIN32 DLL export definitions for the Fast Light Tool Kit (FLTK). + * + * Copyright 1998-2005 by Bill Spitzak and others. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems on the following page: + * + * http://www.fltk.org/str.php + */ + +#ifndef Fl_Export_H +# define Fl_Export_H + +/* + * The following is only used when building DLLs under WIN32... + */ + +# if defined(FL_DLL) && (defined(_MSC_VER) || defined(__MWERKS__) || defined(__BORLANDC__) || __GNUC__ >= 3) +# ifdef FL_LIBRARY +# define FL_EXPORT __declspec(dllexport) +# else +# define FL_EXPORT __declspec(dllimport) +# endif /* FL_LIBRARY */ +# else +# define FL_EXPORT +# endif /* FL_DLL */ + +#endif /* !Fl_Export_H */ + +/* + * End of "$Id: Fl_Export.H 4288 2005-04-16 00:13:17Z mike $". + */ diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_File_Browser.H b/plugins/zynaddsubfx/fltk/FL/Fl_File_Browser.H new file mode 100644 index 000000000..3efbecc6a --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_File_Browser.H @@ -0,0 +1,81 @@ +// +// "$Id: Fl_File_Browser.H 4288 2005-04-16 00:13:17Z mike $" +// +// FileBrowser definitions. +// +// Copyright 1999-2005 by Michael Sweet. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// +// Include necessary header files... +// + +#ifndef _Fl_File_Browser_H_ +# define _Fl_File_Browser_H_ + +# include "Fl_Browser.H" +# include "Fl_File_Icon.H" +# include "filename.H" + + +// +// Fl_File_Browser class... +// + +class FL_EXPORT Fl_File_Browser : public Fl_Browser +{ + int filetype_; + const char *directory_; + uchar iconsize_; + const char *pattern_; + + int full_height() const; + int item_height(void *) const; + int item_width(void *) const; + void item_draw(void *, int, int, int, int) const; + int incr_height() const { return (item_height(0)); } + +public: + enum { FILES, DIRECTORIES }; + + Fl_File_Browser(int, int, int, int, const char * = 0); + + uchar iconsize() const { return (iconsize_); }; + void iconsize(uchar s) { iconsize_ = s; redraw(); }; + + void filter(const char *pattern); + const char *filter() const { return (pattern_); }; + + int load(const char *directory, Fl_File_Sort_F *sort = fl_numericsort); + + uchar textsize() const { return (Fl_Browser::textsize()); }; + void textsize(uchar s) { Fl_Browser::textsize(s); iconsize_ = (uchar)(3 * s / 2); }; + + int filetype() const { return (filetype_); }; + void filetype(int t) { filetype_ = t; }; +}; + +#endif // !_Fl_File_Browser_H_ + +// +// End of "$Id: Fl_File_Browser.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_File_Chooser.H b/plugins/zynaddsubfx/fltk/FL/Fl_File_Chooser.H new file mode 100644 index 000000000..727c73dc3 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_File_Chooser.H @@ -0,0 +1,187 @@ +// +// "$Id: Fl_File_Chooser.H 5644 2007-01-28 19:41:56Z mike $" +// +// Fl_File_Chooser dialog for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// generated by Fast Light User Interface Designer (fluid) version 1.0108 + +#ifndef Fl_File_Chooser_H +#define Fl_File_Chooser_H +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class FL_EXPORT Fl_File_Chooser { +public: + enum { SINGLE = 0, MULTI = 1, CREATE = 2, DIRECTORY = 4 }; +private: + static Fl_Preferences prefs_; + void (*callback_)(Fl_File_Chooser*, void *); + void *data_; + char directory_[1024]; + char pattern_[1024]; + char preview_text_[2048]; + int type_; + void favoritesButtonCB(); + void favoritesCB(Fl_Widget *w); + void fileListCB(); + void fileNameCB(); + void newdir(); + static void previewCB(Fl_File_Chooser *fc); + void showChoiceCB(); + void update_favorites(); + void update_preview(); +public: + Fl_File_Chooser(const char *d, const char *p, int t, const char *title); +private: + Fl_Double_Window *window; + void cb_window_i(Fl_Double_Window*, void*); + static void cb_window(Fl_Double_Window*, void*); + Fl_Choice *showChoice; + void cb_showChoice_i(Fl_Choice*, void*); + static void cb_showChoice(Fl_Choice*, void*); + Fl_Menu_Button *favoritesButton; + void cb_favoritesButton_i(Fl_Menu_Button*, void*); + static void cb_favoritesButton(Fl_Menu_Button*, void*); +public: + Fl_Button *newButton; +private: + void cb_newButton_i(Fl_Button*, void*); + static void cb_newButton(Fl_Button*, void*); + void cb__i(Fl_Tile*, void*); + static void cb_(Fl_Tile*, void*); + Fl_File_Browser *fileList; + void cb_fileList_i(Fl_File_Browser*, void*); + static void cb_fileList(Fl_File_Browser*, void*); + Fl_Box *previewBox; +public: + Fl_Check_Button *previewButton; +private: + void cb_previewButton_i(Fl_Check_Button*, void*); + static void cb_previewButton(Fl_Check_Button*, void*); + Fl_File_Input *fileName; + void cb_fileName_i(Fl_File_Input*, void*); + static void cb_fileName(Fl_File_Input*, void*); + Fl_Return_Button *okButton; + void cb_okButton_i(Fl_Return_Button*, void*); + static void cb_okButton(Fl_Return_Button*, void*); + Fl_Button *cancelButton; + void cb_cancelButton_i(Fl_Button*, void*); + static void cb_cancelButton(Fl_Button*, void*); + Fl_Double_Window *favWindow; + Fl_File_Browser *favList; + void cb_favList_i(Fl_File_Browser*, void*); + static void cb_favList(Fl_File_Browser*, void*); + Fl_Button *favUpButton; + void cb_favUpButton_i(Fl_Button*, void*); + static void cb_favUpButton(Fl_Button*, void*); + Fl_Button *favDeleteButton; + void cb_favDeleteButton_i(Fl_Button*, void*); + static void cb_favDeleteButton(Fl_Button*, void*); + Fl_Button *favDownButton; + void cb_favDownButton_i(Fl_Button*, void*); + static void cb_favDownButton(Fl_Button*, void*); + Fl_Button *favCancelButton; + void cb_favCancelButton_i(Fl_Button*, void*); + static void cb_favCancelButton(Fl_Button*, void*); + Fl_Return_Button *favOkButton; + void cb_favOkButton_i(Fl_Return_Button*, void*); + static void cb_favOkButton(Fl_Return_Button*, void*); +public: + ~Fl_File_Chooser(); + void callback(void (*cb)(Fl_File_Chooser *, void *), void *d = 0); + void color(Fl_Color c); + Fl_Color color(); + int count(); + void directory(const char *d); + char * directory(); + void filter(const char *p); + const char * filter(); + int filter_value(); + void filter_value(int f); + void hide(); + void iconsize(uchar s); + uchar iconsize(); + void label(const char *l); + const char * label(); + void ok_label(const char *l); + const char * ok_label(); + void preview(int e); + int preview() const { return previewButton->value(); }; + void rescan(); + void rescan_keep_filename(); + void show(); + int shown(); + void textcolor(Fl_Color c); + Fl_Color textcolor(); + void textfont(uchar f); + uchar textfont(); + void textsize(uchar s); + uchar textsize(); + void type(int t); + int type(); + void * user_data() const; + void user_data(void *d); + const char *value(int f = 1); + void value(const char *filename); + int visible(); + static const char *add_favorites_label; + static const char *all_files_label; + static const char *custom_filter_label; + static const char *existing_file_label; + static const char *favorites_label; + static const char *filename_label; + static const char *filesystems_label; + static const char *manage_favorites_label; + static const char *new_directory_label; + static const char *new_directory_tooltip; + static const char *preview_label; + static const char *save_label; + static const char *show_label; + static Fl_File_Sort_F *sort; +}; +FL_EXPORT char *fl_dir_chooser(const char *message,const char *fname,int relative=0); +FL_EXPORT char *fl_file_chooser(const char *message,const char *pat,const char *fname,int relative=0); +FL_EXPORT void fl_file_chooser_callback(void (*cb)(const char*)); +FL_EXPORT void fl_file_chooser_ok_label(const char*l); +#endif + +// +// End of "$Id: Fl_File_Chooser.H 5644 2007-01-28 19:41:56Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_File_Icon.H b/plugins/zynaddsubfx/fltk/FL/Fl_File_Icon.H new file mode 100644 index 000000000..85201296a --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_File_Icon.H @@ -0,0 +1,115 @@ +// +// "$Id: Fl_File_Icon.H 4288 2005-04-16 00:13:17Z mike $" +// +// Fl_File_Icon definitions. +// +// Copyright 1999-2005 by Michael Sweet. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// +// Include necessary header files... +// + +#ifndef _Fl_Fl_File_Icon_H_ +# define _Fl_Fl_File_Icon_H_ + +# include "Fl.H" + + +// +// Special color value for the icon color. +// + +# define FL_ICON_COLOR (Fl_Color)0xffffffff + + +// +// Fl_File_Icon class... +// + +class FL_EXPORT Fl_File_Icon //// Icon data +{ + static Fl_File_Icon *first_; // Pointer to first icon/filetype + Fl_File_Icon *next_; // Pointer to next icon/filetype + const char *pattern_; // Pattern string + int type_; // Match only if directory or file? + int num_data_; // Number of data elements + int alloc_data_; // Number of allocated elements + short *data_; // Icon data + + public: + + enum // File types + { + ANY, // Any kind of file + PLAIN, // Only plain files + FIFO, // Only named pipes + DEVICE, // Only character and block devices + LINK, // Only symbolic links + DIRECTORY // Only directories + }; + + enum // Data opcodes + { + END, // End of primitive/icon + COLOR, // Followed by color value (2 shorts) + LINE, // Start of line + CLOSEDLINE, // Start of closed line + POLYGON, // Start of polygon + OUTLINEPOLYGON, // Followed by outline color (2 shorts) + VERTEX // Followed by scaled X,Y + }; + + Fl_File_Icon(const char *p, int t, int nd = 0, short *d = 0); + ~Fl_File_Icon(); + + short *add(short d); + short *add_color(Fl_Color c) + { short *d = add((short)COLOR); add((short)(c >> 16)); add((short)c); return (d); } + short *add_vertex(int x, int y) + { short *d = add((short)VERTEX); add((short)x); add((short)y); return (d); } + short *add_vertex(float x, float y) + { short *d = add((short)VERTEX); add((short)(x * 10000.0)); + add((short)(y * 10000.0)); return (d); } + void clear() { num_data_ = 0; } + void draw(int x, int y, int w, int h, Fl_Color ic, int active = 1); + void label(Fl_Widget *w); + static void labeltype(const Fl_Label *o, int x, int y, int w, int h, Fl_Align a); + void load(const char *f); + int load_fti(const char *fti); + int load_image(const char *i); + Fl_File_Icon *next() { return (next_); } + const char *pattern() { return (pattern_); } + int size() { return (num_data_); } + int type() { return (type_); } + short *value() { return (data_); } + + static Fl_File_Icon *find(const char *filename, int filetype = ANY); + static Fl_File_Icon *first() { return (first_); } + static void load_system_icons(void); +}; + +#endif // !_Fl_Fl_File_Icon_H_ + +// +// End of "$Id: Fl_File_Icon.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_File_Input.H b/plugins/zynaddsubfx/fltk/FL/Fl_File_Input.H new file mode 100644 index 000000000..b5ec6f104 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_File_Input.H @@ -0,0 +1,68 @@ +// +// "$Id: Fl_File_Input.H 4288 2005-04-16 00:13:17Z mike $" +// +// File_Input header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// Original version Copyright 1998 by Curtis Edwards. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_File_Input_H +# define Fl_File_Input_H + +# include + + +class FL_EXPORT Fl_File_Input : public Fl_Input +{ + Fl_Color errorcolor_; + char ok_entry_; + uchar down_box_; + short buttons_[200]; + short pressed_; + + void draw_buttons(); + int handle_button(int event); + void update_buttons(); + +public: + + Fl_File_Input(int,int,int,int,const char *t=0); + + virtual int handle(int); + virtual void draw(); + + Fl_Boxtype down_box() const { return (Fl_Boxtype)down_box_; } + void down_box(Fl_Boxtype b) { down_box_ = b; } + Fl_Color errorcolor() const { return errorcolor_; } + void errorcolor(Fl_Color c) { errorcolor_ = c; } + int value(const char*); + int value(const char*, int); + const char *value() { return Fl_Input_::value(); } +}; + +#endif // !Fl_File_Input_H + + +// +// End of "$Id: Fl_File_Input.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Fill_Dial.H b/plugins/zynaddsubfx/fltk/FL/Fl_Fill_Dial.H new file mode 100644 index 000000000..2472f6dc4 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Fill_Dial.H @@ -0,0 +1,43 @@ +// +// "$Id: Fl_Fill_Dial.H 4288 2005-04-16 00:13:17Z mike $" +// +// Filled dial header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Fill_Dial_H +#define Fl_Fill_Dial_H + +#include "Fl_Dial.H" + +class Fl_Fill_Dial : public Fl_Dial { +public: + Fl_Fill_Dial(int x,int y,int w,int h, const char *l = 0) + : Fl_Dial(x,y,w,h,l) {type(FL_FILL_DIAL);} +}; + +#endif + +// +// End of "$Id: Fl_Fill_Dial.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Fill_Slider.H b/plugins/zynaddsubfx/fltk/FL/Fl_Fill_Slider.H new file mode 100644 index 000000000..8635eeb82 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Fill_Slider.H @@ -0,0 +1,43 @@ +// +// "$Id: Fl_Fill_Slider.H 4288 2005-04-16 00:13:17Z mike $" +// +// Filled slider header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Fill_Slider_H +#define Fl_Fill_Slider_H + +#include "Fl_Slider.H" + +class Fl_Fill_Slider : public Fl_Slider { +public: + Fl_Fill_Slider(int x,int y,int w,int h,const char *l=0) + : Fl_Slider(x,y,w,h,l) {type(FL_VERT_FILL_SLIDER);} +}; + +#endif + +// +// End of "$Id: Fl_Fill_Slider.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Float_Input.H b/plugins/zynaddsubfx/fltk/FL/Fl_Float_Input.H new file mode 100644 index 000000000..526674d2b --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Float_Input.H @@ -0,0 +1,43 @@ +// +// "$Id: Fl_Float_Input.H 4288 2005-04-16 00:13:17Z mike $" +// +// Floating point input header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Float_Input_H +#define Fl_Float_Input_H + +#include "Fl_Input.H" + +class Fl_Float_Input : public Fl_Input { +public: + Fl_Float_Input(int X,int Y,int W,int H,const char *l = 0) + : Fl_Input(X,Y,W,H,l) {type(FL_FLOAT_INPUT);} +}; + +#endif + +// +// End of "$Id: Fl_Float_Input.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_FormsBitmap.H b/plugins/zynaddsubfx/fltk/FL/Fl_FormsBitmap.H new file mode 100644 index 000000000..caa3a0734 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_FormsBitmap.H @@ -0,0 +1,48 @@ +// +// "$Id: Fl_FormsBitmap.H 4288 2005-04-16 00:13:17Z mike $" +// +// Forms bitmap header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_FormsBitmap_H +#define Fl_FormsBitmap_H + +#include "Fl_Bitmap.H" + +class FL_EXPORT Fl_FormsBitmap : public Fl_Widget { + Fl_Bitmap *b; +protected: + void draw(); +public: + Fl_FormsBitmap(Fl_Boxtype, int, int, int, int, const char * = 0); + void set(int W, int H, const uchar *bits); + void bitmap(Fl_Bitmap *B) {b = B;} + Fl_Bitmap *bitmap() const {return b;} +}; + +#endif + +// +// End of "$Id: Fl_FormsBitmap.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_FormsPixmap.H b/plugins/zynaddsubfx/fltk/FL/Fl_FormsPixmap.H new file mode 100644 index 000000000..f25bed6d7 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_FormsPixmap.H @@ -0,0 +1,48 @@ +// +// "$Id: Fl_FormsPixmap.H 4288 2005-04-16 00:13:17Z mike $" +// +// Forms pixmap header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_FormsPixmap_H +#define Fl_FormsPixmap_H + +#include "Fl_Pixmap.H" + +class FL_EXPORT Fl_FormsPixmap : public Fl_Widget { + Fl_Pixmap *b; +protected: + void draw(); +public: + Fl_FormsPixmap(Fl_Boxtype, int, int, int, int, const char * = 0); + void set(/*const*/char * const * bits); + void Pixmap(Fl_Pixmap *B) {b = B;} + Fl_Pixmap *Pixmap() const {return b;} +}; + +#endif + +// +// End of "$Id: Fl_FormsPixmap.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Free.H b/plugins/zynaddsubfx/fltk/FL/Fl_Free.H new file mode 100644 index 000000000..7895dfe17 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Free.H @@ -0,0 +1,66 @@ +// +// "$Id: Fl_Free.H 4288 2005-04-16 00:13:17Z mike $" +// +// Forms free header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Free_H +#define Fl_Free_H + +#ifndef Fl_Widget_H +#include "Fl_Widget.H" +#endif + +#define FL_NORMAL_FREE 1 +#define FL_SLEEPING_FREE 2 +#define FL_INPUT_FREE 3 +#define FL_CONTINUOUS_FREE 4 +#define FL_ALL_FREE 5 + +typedef int (*FL_HANDLEPTR)(Fl_Widget *, int , float, float, char); + +class FL_EXPORT Fl_Free : public Fl_Widget { + FL_HANDLEPTR hfunc; + static void step(void *); +protected: + void draw(); +public: + int handle(int); + Fl_Free(uchar t,int x,int y,int w,int h,const char *l,FL_HANDLEPTR hdl); + ~Fl_Free(); +}; + +// old event names for compatability: +#define FL_MOUSE FL_DRAG +#define FL_DRAW 100 // NOT USED +#define FL_STEP 101 +#define FL_FREEMEM 102 // NOT USED +#define FL_FREEZE 103 // NOT USED +#define FL_THAW 104 // NOT USED + +#endif + +// +// End of "$Id: Fl_Free.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Group.H b/plugins/zynaddsubfx/fltk/FL/Fl_Group.H new file mode 100644 index 000000000..8e4bb926d --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Group.H @@ -0,0 +1,111 @@ +// +// "$Id: Fl_Group.H 5993 2007-12-15 16:42:00Z mike $" +// +// Group header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Group_H +#define Fl_Group_H + +#ifndef Fl_Widget_H +#include "Fl_Widget.H" +#endif + +class FL_EXPORT Fl_Group : public Fl_Widget { + + Fl_Widget** array_; + Fl_Widget* savedfocus_; + Fl_Widget* resizable_; + int children_; + short *sizes_; // remembered initial sizes of children + + int navigation(int); + static Fl_Group *current_; + + // unimplemented copy ctor and assignment operator + Fl_Group(const Fl_Group&); + Fl_Group& operator=(const Fl_Group&); + +protected: + enum { CLIP_CHILDREN = 2048 }; + + void clip_children(int c) { if (c) set_flag(CLIP_CHILDREN); else clear_flag(CLIP_CHILDREN); } + int clip_children() { return (flags() & CLIP_CHILDREN) != 0; } + + void draw(); + void draw_child(Fl_Widget&) const; + void draw_children(); + void draw_outside_label(const Fl_Widget&) const ; + void update_child(Fl_Widget&) const; + short* sizes(); + +public: + + int handle(int); + void begin(); + void end(); + static Fl_Group *current(); + static void current(Fl_Group *g); + + int children() const {return children_;} + Fl_Widget* child(int n) const {return array()[n];} + int find(const Fl_Widget*) const; + int find(const Fl_Widget& o) const {return find(&o);} + Fl_Widget* const* array() const; + + void resize(int,int,int,int); + Fl_Group(int,int,int,int, const char * = 0); + virtual ~Fl_Group(); + void add(Fl_Widget&); + void add(Fl_Widget* o) {add(*o);} + void insert(Fl_Widget&, int i); + void insert(Fl_Widget& o, Fl_Widget* before) {insert(o,find(before));} + void remove(Fl_Widget&); + void remove(Fl_Widget* o) {remove(*o);} + void clear(); + + void resizable(Fl_Widget& o) {resizable_ = &o;} + void resizable(Fl_Widget* o) {resizable_ = o;} + Fl_Widget* resizable() const {return resizable_;} + void add_resizable(Fl_Widget& o) {resizable_ = &o; add(o);} + void init_sizes(); + + // back compatability function: + void focus(Fl_Widget* o) {o->take_focus();} + Fl_Widget* & _ddfdesign_kludge() {return resizable_;} + void forms_end(); +}; + +// dummy class used to end child groups in constructors for complex +// subclasses of Fl_Group: +class FL_EXPORT Fl_End { +public: + Fl_End() {Fl_Group::current()->end();} +}; + +#endif + +// +// End of "$Id: Fl_Group.H 5993 2007-12-15 16:42:00Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Help_Dialog.H b/plugins/zynaddsubfx/fltk/FL/Fl_Help_Dialog.H new file mode 100644 index 000000000..bf86af767 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Help_Dialog.H @@ -0,0 +1,92 @@ +// +// "$Id: Fl_Help_Dialog.H 5643 2007-01-28 19:36:51Z mike $" +// +// Fl_Help_Dialog dialog for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// generated by Fast Light User Interface Designer (fluid) version 1.0108 + +#ifndef Fl_Help_Dialog_H +#define Fl_Help_Dialog_H +#include +#include +#include +#include +#include +#include +#include + +class FL_EXPORT Fl_Help_Dialog { + int index_; + int max_; + int line_[100]; + char file_[100][256]; + int find_pos_; +public: + Fl_Help_Dialog(); +private: + Fl_Double_Window *window_; + Fl_Button *back_; + void cb_back__i(Fl_Button*, void*); + static void cb_back_(Fl_Button*, void*); + Fl_Button *forward_; + void cb_forward__i(Fl_Button*, void*); + static void cb_forward_(Fl_Button*, void*); + Fl_Button *smaller_; + void cb_smaller__i(Fl_Button*, void*); + static void cb_smaller_(Fl_Button*, void*); + Fl_Button *larger_; + void cb_larger__i(Fl_Button*, void*); + static void cb_larger_(Fl_Button*, void*); + Fl_Input *find_; + void cb_find__i(Fl_Input*, void*); + static void cb_find_(Fl_Input*, void*); + Fl_Help_View *view_; + void cb_view__i(Fl_Help_View*, void*); + static void cb_view_(Fl_Help_View*, void*); +public: + ~Fl_Help_Dialog(); + int h(); + void hide(); + void load(const char *f); + void position(int xx, int yy); + void resize(int xx, int yy, int ww, int hh); + void show(); + void show(int argc, char **argv); + void textsize(uchar s); + uchar textsize(); + void topline(const char *n); + void topline(int n); + void value(const char *f); + const char * value() const; + int visible(); + int w(); + int x(); + int y(); +}; +#endif + +// +// End of "$Id: Fl_Help_Dialog.H 5643 2007-01-28 19:36:51Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Help_View.H b/plugins/zynaddsubfx/fltk/FL/Fl_Help_View.H new file mode 100644 index 000000000..0229115e9 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Help_View.H @@ -0,0 +1,221 @@ +// +// "$Id: Fl_Help_View.H 5991 2007-12-15 16:08:23Z mike $" +// +// Help Viewer widget definitions. +// +// Copyright 1997-2005 by Easy Software Products. +// Image support donated by Matthias Melcher, Copyright 2000. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Help_View_H +# define Fl_Help_View_H + +// +// Include necessary header files... +// + +# include +# include "Fl.H" +# include "Fl_Group.H" +# include "Fl_Scrollbar.H" +# include "fl_draw.H" +# include "Fl_Shared_Image.H" + + +// +// Fl_Help_Func type - link callback function for files... +// + + +typedef const char *(Fl_Help_Func)(Fl_Widget *, const char *); + + +// +// Fl_Help_Block structure... +// + +struct Fl_Help_Block +{ + const char *start, // Start of text + *end; // End of text + uchar border; // Draw border? + Fl_Color bgcolor; // Background color + int x, // Indentation/starting X coordinate + y, // Starting Y coordinate + w, // Width + h; // Height + int line[32]; // Left starting position for each line +}; + +// +// Fl_Help_Link structure... +// + +struct Fl_Help_Link +{ + char filename[192], // Reference filename + name[32]; // Link target (blank if none) + int x, // X offset of link text + y, // Y offset of link text + w, // Width of link text + h; // Height of link text +}; + +// +// Fl_Help_Target structure... +// + +struct Fl_Help_Target +{ + char name[32]; // Target name + int y; // Y offset of target +}; + +// +// Fl_Help_View class... +// + +class FL_EXPORT Fl_Help_View : public Fl_Group //// Help viewer widget +{ + enum { RIGHT = -1, CENTER, LEFT }; // Alignments + + char title_[1024]; // Title string + Fl_Color defcolor_, // Default text color + bgcolor_, // Background color + textcolor_, // Text color + linkcolor_; // Link color + uchar textfont_, // Default font for text + textsize_; // Default font size + const char *value_; // HTML text value + + int nblocks_, // Number of blocks/paragraphs + ablocks_; // Allocated blocks + Fl_Help_Block *blocks_; // Blocks + + int nfonts_; // Number of fonts in stack + uchar fonts_[100][2]; // Font stack + + Fl_Help_Func *link_; // Link transform function + + int nlinks_, // Number of links + alinks_; // Allocated links + Fl_Help_Link *links_; // Links + + int ntargets_, // Number of targets + atargets_; // Allocated targets + Fl_Help_Target *targets_; // Targets + + char directory_[1024]; // Directory for current file + char filename_[1024]; // Current filename + int topline_, // Top line in document + leftline_, // Lefthand position + size_, // Total document length + hsize_; // Maximum document width + Fl_Scrollbar scrollbar_, // Vertical scrollbar for document + hscrollbar_; // Horizontal scrollbar + + static int selection_first; + static int selection_last; + static int selection_push_first; + static int selection_push_last; + static int selection_drag_first; + static int selection_drag_last; + static int selected; + static int draw_mode; + static int mouse_x; + static int mouse_y; + static int current_pos; + static Fl_Help_View *current_view; + static Fl_Color hv_selection_color; + static Fl_Color hv_selection_text_color; + + Fl_Help_Block *add_block(const char *s, int xx, int yy, int ww, int hh, uchar border = 0); + void add_link(const char *n, int xx, int yy, int ww, int hh); + void add_target(const char *n, int yy); + static int compare_targets(const Fl_Help_Target *t0, const Fl_Help_Target *t1); + int do_align(Fl_Help_Block *block, int line, int xx, int a, int &l); + void draw(); + void format(); + void format_table(int *table_width, int *columns, const char *table); + void free_data(); + int get_align(const char *p, int a); + const char *get_attr(const char *p, const char *n, char *buf, int bufsize); + Fl_Color get_color(const char *n, Fl_Color c); + Fl_Shared_Image *get_image(const char *name, int W, int H); + int get_length(const char *l); + int handle(int); + + void initfont(uchar &f, uchar &s) { nfonts_ = 0; + fl_font(f = fonts_[0][0] = textfont_, + s = fonts_[0][1] = textsize_); } + void pushfont(uchar f, uchar s) { if (nfonts_ < 99) nfonts_ ++; + fl_font(fonts_[nfonts_][0] = f, + fonts_[nfonts_][1] = s); } + void popfont(uchar &f, uchar &s) { if (nfonts_ > 0) nfonts_ --; + fl_font(f = fonts_[nfonts_][0], + s = fonts_[nfonts_][1]); } + + void hv_draw(const char *t, int x, int y); + char begin_selection(); + char extend_selection(); + void end_selection(int c=0); + void clear_global_selection(); + Fl_Help_Link *find_link(int, int); + void follow_link(Fl_Help_Link*); + +public: + + Fl_Help_View(int xx, int yy, int ww, int hh, const char *l = 0); + ~Fl_Help_View(); + const char *directory() const { if (directory_[0]) return (directory_); + else return ((const char *)0); } + const char *filename() const { if (filename_[0]) return (filename_); + else return ((const char *)0); } + int find(const char *s, int p = 0); + void link(Fl_Help_Func *fn) { link_ = fn; } + int load(const char *f); + void resize(int,int,int,int); + int size() const { return (size_); } + void size(int W, int H) { Fl_Widget::size(W, H); } + void textcolor(Fl_Color c) { if (textcolor_ == defcolor_) textcolor_ = c; defcolor_ = c; } + Fl_Color textcolor() const { return (defcolor_); } + void textfont(uchar f) { textfont_ = f; format(); } + uchar textfont() const { return (textfont_); } + void textsize(uchar s) { textsize_ = s; format(); } + uchar textsize() const { return (textsize_); } + const char *title() { return (title_); } + void topline(const char *n); + void topline(int); + int topline() const { return (topline_); } + void leftline(int); + int leftline() const { return (leftline_); } + void value(const char *v); + const char *value() const { return (value_); } + void clear_selection(); + void select_all(); +}; + +#endif // !Fl_Help_View_H + +// +// End of "$Id: Fl_Help_View.H 5991 2007-12-15 16:08:23Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Hold_Browser.H b/plugins/zynaddsubfx/fltk/FL/Fl_Hold_Browser.H new file mode 100644 index 000000000..6286a60bf --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Hold_Browser.H @@ -0,0 +1,43 @@ +// +// "$Id: Fl_Hold_Browser.H 4288 2005-04-16 00:13:17Z mike $" +// +// Hold browser header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Hold_Browser_H +#define Fl_Hold_Browser_H + +#include "Fl_Browser.H" + +class Fl_Hold_Browser : public Fl_Browser { +public: + Fl_Hold_Browser(int X,int Y,int W,int H,const char *l=0) + : Fl_Browser(X,Y,W,H,l) {type(FL_HOLD_BROWSER);} +}; + +#endif + +// +// End of "$Id: Fl_Hold_Browser.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Hor_Fill_Slider.H b/plugins/zynaddsubfx/fltk/FL/Fl_Hor_Fill_Slider.H new file mode 100644 index 000000000..a7a87f5ea --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Hor_Fill_Slider.H @@ -0,0 +1,42 @@ +// +// "$Id: Fl_Hor_Fill_Slider.H 4288 2005-04-16 00:13:17Z mike $" +// +// Horizontal fill slider header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +#ifndef Fl_Hor_Fill_Slider_H +#define Fl_Hor_Fill_Slider_H + +#include "Fl_Slider.H" + +class Fl_Hor_Fill_Slider : public Fl_Slider { +public: + Fl_Hor_Fill_Slider(int x,int y,int w,int h,const char *l=0) + : Fl_Slider(x,y,w,h,l) {type(FL_HOR_FILL_SLIDER);} +}; + +#endif + +// +// End of "$Id: Fl_Hor_Fill_Slider.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Hor_Nice_Slider.H b/plugins/zynaddsubfx/fltk/FL/Fl_Hor_Nice_Slider.H new file mode 100644 index 000000000..bed75a51c --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Hor_Nice_Slider.H @@ -0,0 +1,43 @@ +// +// "$Id: Fl_Hor_Nice_Slider.H 4288 2005-04-16 00:13:17Z mike $" +// +// Horizontal "nice" slider header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Hor_Nice_Slider_H +#define Fl_Hor_Nice_Slider_H + +#include "Fl_Slider.H" + +class Fl_Hor_Nice_Slider : public Fl_Slider { +public: + Fl_Hor_Nice_Slider(int x,int y,int w,int h,const char *l=0) + : Fl_Slider(x,y,w,h,l) {type(FL_HOR_NICE_SLIDER); box(FL_FLAT_BOX);} +}; + +#endif + +// +// End of "$Id: Fl_Hor_Nice_Slider.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Hor_Slider.H b/plugins/zynaddsubfx/fltk/FL/Fl_Hor_Slider.H new file mode 100644 index 000000000..34be6961e --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Hor_Slider.H @@ -0,0 +1,43 @@ +// +// "$Id: Fl_Hor_Slider.H 4288 2005-04-16 00:13:17Z mike $" +// +// Horizontal slider header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Hor_Slider_H +#define Fl_Hor_Slider_H + +#include "Fl_Slider.H" + +class Fl_Hor_Slider : public Fl_Slider { +public: + Fl_Hor_Slider(int X,int Y,int W,int H,const char *l=0) + : Fl_Slider(X,Y,W,H,l) {type(FL_HOR_SLIDER);} +}; + +#endif + +// +// End of "$Id: Fl_Hor_Slider.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Hor_Value_Slider.H b/plugins/zynaddsubfx/fltk/FL/Fl_Hor_Value_Slider.H new file mode 100644 index 000000000..d499feadf --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Hor_Value_Slider.H @@ -0,0 +1,43 @@ +// +// "$Id: Fl_Hor_Value_Slider.H 4288 2005-04-16 00:13:17Z mike $" +// +// Horizontal value slider header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Hor_Value_Slider_H +#define Fl_Hor_Value_Slider_H + +#include "Fl_Value_Slider.H" + +class Fl_Hor_Value_Slider : public Fl_Value_Slider { +public: + Fl_Hor_Value_Slider(int X,int Y,int W,int H,const char *l=0) + : Fl_Value_Slider(X,Y,W,H,l) {type(FL_HOR_SLIDER);} +}; + +#endif + +// +// End of "$Id: Fl_Hor_Value_Slider.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Image.H b/plugins/zynaddsubfx/fltk/FL/Fl_Image.H new file mode 100644 index 000000000..4d6f052d5 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Image.H @@ -0,0 +1,112 @@ +// +// "$Id: Fl_Image.H 4288 2005-04-16 00:13:17Z mike $" +// +// Image header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Image_H +# define Fl_Image_H + +# include "Enumerations.H" + +class Fl_Widget; +struct Fl_Menu_Item; +struct Fl_Label; + +class FL_EXPORT Fl_Image { + int w_, h_, d_, ld_, count_; + const char * const *data_; + + // Forbid use of copy contructor and assign operator + Fl_Image & operator=(const Fl_Image &); + Fl_Image(const Fl_Image &); + + protected: + + void w(int W) {w_ = W;} + void h(int H) {h_ = H;} + void d(int D) {d_ = D;} + void ld(int LD) {ld_ = LD;} + void data(const char * const *p, int c) {data_ = p; count_ = c;} + void draw_empty(int X, int Y); + + static void labeltype(const Fl_Label *lo, int lx, int ly, int lw, int lh, Fl_Align la); + static void measure(const Fl_Label *lo, int &lw, int &lh); + + public: + + int w() const {return w_;} + int h() const {return h_;} + int d() const {return d_;} + int ld() const {return ld_;} + int count() const {return count_;} + const char * const *data() const {return data_;} + + Fl_Image(int W, int H, int D) {w_ = W; h_ = H; d_ = D; ld_ = 0; count_ = 0; data_ = 0;} + virtual ~Fl_Image(); + virtual Fl_Image *copy(int W, int H); + Fl_Image *copy() { return copy(w(), h()); } + virtual void color_average(Fl_Color c, float i); + void inactive() { color_average(FL_GRAY, .33f); } + virtual void desaturate(); + virtual void label(Fl_Widget*w); + virtual void label(Fl_Menu_Item*m); + virtual void draw(int X, int Y, int W, int H, int cx=0, int cy=0); + void draw(int X, int Y) {draw(X, Y, w(), h(), 0, 0);} + virtual void uncache(); +}; + +class FL_EXPORT Fl_RGB_Image : public Fl_Image { + public: + + const uchar *array; + int alloc_array; // Non-zero if array was allocated + +#if defined(__APPLE__) || defined(WIN32) + void *id; // for internal use + void *mask; // for internal use (mask bitmap) +#else + unsigned id; // for internal use + unsigned mask; // for internal use (mask bitmap) +#endif // __APPLE__ || WIN32 + + Fl_RGB_Image(const uchar *bits, int W, int H, int D=3, int LD=0) : + Fl_Image(W,H,D), array(bits), alloc_array(0), id(0), mask(0) {data((const char **)&array, 1); ld(LD);} + virtual ~Fl_RGB_Image(); + virtual Fl_Image *copy(int W, int H); + Fl_Image *copy() { return copy(w(), h()); } + virtual void color_average(Fl_Color c, float i); + virtual void desaturate(); + virtual void draw(int X, int Y, int W, int H, int cx=0, int cy=0); + void draw(int X, int Y) {draw(X, Y, w(), h(), 0, 0);} + virtual void label(Fl_Widget*w); + virtual void label(Fl_Menu_Item*m); + virtual void uncache(); +}; + +#endif // !Fl_Image_H + +// +// End of "$Id: Fl_Image.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Input.H b/plugins/zynaddsubfx/fltk/FL/Fl_Input.H new file mode 100644 index 000000000..03823fe08 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Input.H @@ -0,0 +1,47 @@ +// +// "$Id: Fl_Input.H 5300 2006-08-14 07:06:45Z matt $" +// +// Input header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Input_H +#define Fl_Input_H + +#include "Fl_Input_.H" + +class FL_EXPORT Fl_Input : public Fl_Input_ { + int handle_key(); + int shift_position(int p); + int shift_up_down_position(int p); +public: + void draw(); + int handle(int); + Fl_Input(int,int,int,int,const char * = 0); +}; + +#endif + +// +// End of "$Id: Fl_Input.H 5300 2006-08-14 07:06:45Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Input_.H b/plugins/zynaddsubfx/fltk/FL/Fl_Input_.H new file mode 100644 index 000000000..0c52ce613 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Input_.H @@ -0,0 +1,145 @@ +// +// "$Id: Fl_Input_.H 4288 2005-04-16 00:13:17Z mike $" +// +// Input base class header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Input__H +#define Fl_Input__H + +#ifndef Fl_Widget_H +#include "Fl_Widget.H" +#endif + +#define FL_NORMAL_INPUT 0 +#define FL_FLOAT_INPUT 1 +#define FL_INT_INPUT 2 +#define FL_HIDDEN_INPUT 3 +#define FL_MULTILINE_INPUT 4 +#define FL_SECRET_INPUT 5 +#define FL_INPUT_TYPE 7 +#define FL_INPUT_READONLY 8 +#define FL_NORMAL_OUTPUT (FL_NORMAL_INPUT | FL_INPUT_READONLY) +#define FL_MULTILINE_OUTPUT (FL_MULTILINE_INPUT | FL_INPUT_READONLY) +#define FL_INPUT_WRAP 16 +#define FL_MULTILINE_INPUT_WRAP (FL_MULTILINE_INPUT | FL_INPUT_WRAP) +#define FL_MULTILINE_OUTPUT_WRAP (FL_MULTILINE_INPUT | FL_INPUT_READONLY | FL_INPUT_WRAP) + +class FL_EXPORT Fl_Input_ : public Fl_Widget { + + const char* value_; + char* buffer; + + int size_; + int bufsize; + int position_; + int mark_; + int xscroll_, yscroll_; + int mu_p; + int maximum_size_; + + uchar erase_cursor_only; + uchar textfont_; + uchar textsize_; + unsigned textcolor_; + unsigned cursor_color_; + + const char* expand(const char*, char*) const; + double expandpos(const char*, const char*, const char*, int*) const; + void minimal_update(int, int); + void minimal_update(int p); + void put_in_buffer(int newsize); + + void setfont() const; + +protected: + + int word_start(int i) const; + int word_end(int i) const; + int line_start(int i) const; + int line_end(int i) const; + void drawtext(int, int, int, int); + int up_down_position(int, int keepmark=0); + void handle_mouse(int, int, int, int, int keepmark=0); + int handletext(int e, int, int, int, int); + void maybe_do_callback(); + int xscroll() const {return xscroll_;} + int yscroll() const {return yscroll_;} + +public: + + void resize(int, int, int, int); + + Fl_Input_(int, int, int, int, const char* = 0); + ~Fl_Input_(); + + int value(const char*); + int value(const char*, int); + int static_value(const char*); + int static_value(const char*, int); + const char* value() const {return value_;} + char index(int i) const {return value_[i];} + int size() const {return size_;} + void size(int W, int H) { Fl_Widget::size(W, H); } + int maximum_size() const {return maximum_size_;} + void maximum_size(int m) {maximum_size_ = m;} + + int position() const {return position_;} + int mark() const {return mark_;} + int position(int p, int m); + int position(int p) {return position(p, p);} + int mark(int m) {return position(position(), m);} + int replace(int, int, const char*, int=0); + int cut() {return replace(position(), mark(), 0);} + int cut(int n) {return replace(position(), position()+n, 0);} + int cut(int a, int b) {return replace(a, b, 0);} + int insert(const char* t, int l=0){return replace(position_, mark_, t, l);} + int copy(int clipboard); + int undo(); + int copy_cuts(); + + Fl_Font textfont() const {return (Fl_Font)textfont_;} + void textfont(uchar s) {textfont_ = s;} + uchar textsize() const {return textsize_;} + void textsize(uchar s) {textsize_ = s;} + Fl_Color textcolor() const {return (Fl_Color)textcolor_;} + void textcolor(unsigned n) {textcolor_ = n;} + Fl_Color cursor_color() const {return (Fl_Color)cursor_color_;} + void cursor_color(unsigned n) {cursor_color_ = n;} + + int input_type() const {return type() & FL_INPUT_TYPE; } + void input_type(int t) { type((uchar)(t | readonly())); } + int readonly() const { return type() & FL_INPUT_READONLY; } + void readonly(int b) { if (b) type((uchar)(type() | FL_INPUT_READONLY)); + else type((uchar)(type() & ~FL_INPUT_READONLY)); } + int wrap() const { return type() & FL_INPUT_WRAP; } + void wrap(int b) { if (b) type((uchar)(type() | FL_INPUT_WRAP)); + else type((uchar)(type() & ~FL_INPUT_WRAP)); } +}; + +#endif + +// +// End of "$Id: Fl_Input_.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Input_Choice.H b/plugins/zynaddsubfx/fltk/FL/Fl_Input_Choice.H new file mode 100644 index 000000000..3c2c22f96 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Input_Choice.H @@ -0,0 +1,199 @@ +// +// "$Id$" +// +// An input/chooser widget. +// ______________ ____ +// | || __ | +// | input area || \/ | +// |______________||____| +// +// Copyright 1998-2005 by Bill Spitzak and others. +// Copyright 2004 by Greg Ercolano. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Input_Choice_H +#define Fl_Input_Choice_H + +#include +#include +#include +#include +#include +#include + +class Fl_Input_Choice : public Fl_Group { + // Private class to handle slightly 'special' behavior of menu button + class InputMenuButton : public Fl_Menu_Button { + void draw() { + draw_box(FL_UP_BOX, color()); + fl_color(active_r() ? labelcolor() : fl_inactive(labelcolor())); + int xc = x()+w()/2, yc=y()+h()/2; + fl_polygon(xc-5,yc-3,xc+5,yc-3,xc,yc+3); + if (Fl::focus() == this) draw_focus(); + } + public: + InputMenuButton(int x,int y,int w,int h,const char*l=0) : + Fl_Menu_Button(x,y,w,h,l) { box(FL_UP_BOX); } + }; + + Fl_Input *inp_; + InputMenuButton *menu_; + + static void menu_cb(Fl_Widget*, void *data) { + Fl_Input_Choice *o=(Fl_Input_Choice *)data; + const Fl_Menu_Item *item = o->menubutton()->mvalue(); + if (item && item->flags & (FL_SUBMENU|FL_SUBMENU_POINTER)) return; // ignore submenus + if (!strcmp(o->inp_->value(), o->menu_->text())) + { + o->Fl_Widget::clear_changed(); + if (o->when() & FL_WHEN_NOT_CHANGED) + o->do_callback(); + } + else + { + o->inp_->value(o->menu_->text()); + o->inp_->set_changed(); + o->Fl_Widget::set_changed(); + if (o->when() & (FL_WHEN_CHANGED|FL_WHEN_RELEASE)) + o->do_callback(); + } + + if (o->callback() != default_callback) + { + o->Fl_Widget::clear_changed(); + o->inp_->clear_changed(); + } + } + + static void inp_cb(Fl_Widget*, void *data) { + Fl_Input_Choice *o=(Fl_Input_Choice *)data; + if (o->inp_->changed()) { + o->Fl_Widget::set_changed(); + if (o->when() & (FL_WHEN_CHANGED|FL_WHEN_RELEASE)) + o->do_callback(); + } else { + o->Fl_Widget::clear_changed(); + if (o->when() & FL_WHEN_NOT_CHANGED) + o->do_callback(); + } + + if (o->callback() != default_callback) + o->Fl_Widget::clear_changed(); + } + + // Custom resize behavior -- input stretches, menu button doesn't + inline int inp_x() { return(x() + Fl::box_dx(box())); } + inline int inp_y() { return(y() + Fl::box_dy(box())); } + inline int inp_w() { return(w() - Fl::box_dw(box()) - 20); } + inline int inp_h() { return(h() - Fl::box_dh(box())); } + + inline int menu_x() { return(x() + w() - 20 - Fl::box_dx(box())); } + inline int menu_y() { return(y() + Fl::box_dy(box())); } + inline int menu_w() { return(20); } + inline int menu_h() { return(h() - Fl::box_dh(box())); } + +public: + Fl_Input_Choice (int x,int y,int w,int h,const char*l=0) : Fl_Group(x,y,w,h,l) { + Fl_Group::box(FL_DOWN_BOX); + align(FL_ALIGN_LEFT); // default like Fl_Input + inp_ = new Fl_Input(inp_x(), inp_y(), + inp_w(), inp_h()); + inp_->callback(inp_cb, (void*)this); + inp_->box(FL_FLAT_BOX); // cosmetic + inp_->when(FL_WHEN_CHANGED|FL_WHEN_NOT_CHANGED); + menu_ = new InputMenuButton(menu_x(), menu_y(), + menu_w(), menu_h()); + menu_->callback(menu_cb, (void*)this); + menu_->box(FL_FLAT_BOX); // cosmetic + end(); + } + void add(const char *s) { + menu_->add(s); + } + int changed() const { + return inp_->changed() | Fl_Widget::changed(); + } + void clear_changed() { + inp_->clear_changed(); + Fl_Widget::clear_changed(); + } + void set_changed() { + inp_->set_changed(); + // no need to call Fl_Widget::set_changed() + } + void clear() { + menu_->clear(); + } + Fl_Boxtype down_box() const { + return (menu_->down_box()); + } + void down_box(Fl_Boxtype b) { + menu_->down_box(b); + } + const Fl_Menu_Item *menu() { + return (menu_->menu()); + } + void menu(const Fl_Menu_Item *m) { + menu_->menu(m); + } + void resize(int X, int Y, int W, int H) { + Fl_Group::resize(X,Y,W,H); + inp_->resize(inp_x(), inp_y(), inp_w(), inp_h()); + menu_->resize(menu_x(), menu_y(), menu_w(), menu_h()); + } + Fl_Color textcolor() const { + return (inp_->textcolor()); + } + void textcolor(Fl_Color c) { + inp_->textcolor(c); + } + uchar textfont() const { + return (inp_->textfont()); + } + void textfont(uchar f) { + inp_->textfont(f); + } + uchar textsize() const { + return (inp_->textsize()); + } + void textsize(uchar s) { + inp_->textsize(s); + } + const char* value() const { + return (inp_->value()); + } + void value(const char *val) { + inp_->value(val); + } + void value(int val) { + menu_->value(val); + inp_->value(menu_->text(val)); + } + Fl_Menu_Button *menubutton() { return menu_; } + Fl_Input *input() { return inp_; } +}; + +#endif // !Fl_Input_Choice_H + +// +// End of "$Id$". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Int_Input.H b/plugins/zynaddsubfx/fltk/FL/Fl_Int_Input.H new file mode 100644 index 000000000..641ad1639 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Int_Input.H @@ -0,0 +1,43 @@ +// +// "$Id: Fl_Int_Input.H 4288 2005-04-16 00:13:17Z mike $" +// +// Integer input header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Int_Input_H +#define Fl_Int_Input_H + +#include "Fl_Input.H" + +class Fl_Int_Input : public Fl_Input { +public: + Fl_Int_Input(int X,int Y,int W,int H,const char *l = 0) + : Fl_Input(X,Y,W,H,l) {type(FL_INT_INPUT);} +}; + +#endif + +// +// End of "$Id: Fl_Int_Input.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Light_Button.H b/plugins/zynaddsubfx/fltk/FL/Fl_Light_Button.H new file mode 100644 index 000000000..f056a3001 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Light_Button.H @@ -0,0 +1,45 @@ +// +// "$Id: Fl_Light_Button.H 4288 2005-04-16 00:13:17Z mike $" +// +// Lighted button header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Light_Button_H +#define Fl_Light_Button_H + +#include "Fl_Button.H" + +class FL_EXPORT Fl_Light_Button : public Fl_Button { +protected: + virtual void draw(); +public: + virtual int handle(int); + Fl_Light_Button(int x,int y,int w,int h,const char *l = 0); +}; + +#endif + +// +// End of "$Id: Fl_Light_Button.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Line_Dial.H b/plugins/zynaddsubfx/fltk/FL/Fl_Line_Dial.H new file mode 100644 index 000000000..301bff9de --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Line_Dial.H @@ -0,0 +1,43 @@ +// +// "$Id: Fl_Line_Dial.H 4288 2005-04-16 00:13:17Z mike $" +// +// Line dial header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Line_Dial_H +#define Fl_Line_Dial_H + +#include "Fl_Dial.H" + +class Fl_Line_Dial : public Fl_Dial { +public: + Fl_Line_Dial(int x,int y,int w,int h, const char *l = 0) + : Fl_Dial(x,y,w,h,l) {type(FL_LINE_DIAL);} +}; + +#endif + +// +// End of "$Id: Fl_Line_Dial.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Menu.H b/plugins/zynaddsubfx/fltk/FL/Fl_Menu.H new file mode 100644 index 000000000..9d7798017 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Menu.H @@ -0,0 +1,33 @@ +// +// "$Id: Fl_Menu.H 4288 2005-04-16 00:13:17Z mike $" +// +// Old menu header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// this include file is for back compatability only +#include "Fl_Menu_Item.H" + +// +// End of "$Id: Fl_Menu.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Menu_.H b/plugins/zynaddsubfx/fltk/FL/Fl_Menu_.H new file mode 100644 index 000000000..b04e4e93d --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Menu_.H @@ -0,0 +1,102 @@ +// +// "$Id: Fl_Menu_.H 4288 2005-04-16 00:13:17Z mike $" +// +// Menu base class header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Menu__H +#define Fl_Menu__H + +#ifndef Fl_Widget_H +#include "Fl_Widget.H" +#endif +#include "Fl_Menu_Item.H" + +class FL_EXPORT Fl_Menu_ : public Fl_Widget { + + Fl_Menu_Item *menu_; + const Fl_Menu_Item *value_; + +protected: + + uchar alloc; + uchar down_box_; + uchar textfont_; + uchar textsize_; + unsigned textcolor_; + +public: + Fl_Menu_(int,int,int,int,const char * =0); + ~Fl_Menu_(); + + int item_pathname(char *name, int namelen, const Fl_Menu_Item *finditem=0) const; + const Fl_Menu_Item* picked(const Fl_Menu_Item*); + const Fl_Menu_Item* find_item(const char *name); + + const Fl_Menu_Item* test_shortcut() {return picked(menu()->test_shortcut());} + void global(); + + const Fl_Menu_Item *menu() const {return menu_;} + void menu(const Fl_Menu_Item *m); + void copy(const Fl_Menu_Item *m, void* user_data = 0); + int add(const char*, int shortcut, Fl_Callback*, void* = 0, int = 0); + int add(const char* a, const char* b, Fl_Callback* c, + void* d = 0, int e = 0) {return add(a,fl_old_shortcut(b),c,d,e);} + int size() const ; + void size(int W, int H) { Fl_Widget::size(W, H); } + void clear(); + int add(const char *); + void replace(int,const char *); + void remove(int); + void shortcut(int i, int s) {menu_[i].shortcut(s);} + void mode(int i,int fl) {menu_[i].flags = fl;} + int mode(int i) const {return menu_[i].flags;} + + const Fl_Menu_Item *mvalue() const {return value_;} + int value() const {return value_ ? (int)(value_-menu_) : -1;} + int value(const Fl_Menu_Item*); + int value(int i) {return value(menu_+i);} + const char *text() const {return value_ ? value_->text : 0;} + const char *text(int i) const {return menu_[i].text;} + + Fl_Font textfont() const {return (Fl_Font)textfont_;} + void textfont(uchar c) {textfont_=c;} + uchar textsize() const {return textsize_;} + void textsize(uchar c) {textsize_=c;} + Fl_Color textcolor() const {return (Fl_Color)textcolor_;} + void textcolor(unsigned c) {textcolor_=c;} + + Fl_Boxtype down_box() const {return (Fl_Boxtype)down_box_;} + void down_box(Fl_Boxtype b) {down_box_ = b;} + + // back compatability: + Fl_Color down_color() const {return selection_color();} + void down_color(unsigned c) {selection_color(c);} +}; + +#endif + +// +// End of "$Id: Fl_Menu_.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Menu_Bar.H b/plugins/zynaddsubfx/fltk/FL/Fl_Menu_Bar.H new file mode 100644 index 000000000..ab240da7a --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Menu_Bar.H @@ -0,0 +1,46 @@ +// +// "$Id: Fl_Menu_Bar.H 4288 2005-04-16 00:13:17Z mike $" +// +// Menu bar header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Menu_Bar_H +#define Fl_Menu_Bar_H + +#include "Fl_Menu_.H" + +class FL_EXPORT Fl_Menu_Bar : public Fl_Menu_ { +protected: + void draw(); +public: + int handle(int); + Fl_Menu_Bar(int X, int Y, int W, int H,const char *l=0) + : Fl_Menu_(X,Y,W,H,l) {} +}; + +#endif + +// +// End of "$Id: Fl_Menu_Bar.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Menu_Button.H b/plugins/zynaddsubfx/fltk/FL/Fl_Menu_Button.H new file mode 100644 index 000000000..39a2665a0 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Menu_Button.H @@ -0,0 +1,48 @@ +// +// "$Id: Fl_Menu_Button.H 4288 2005-04-16 00:13:17Z mike $" +// +// Menu button header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Menu_Button_H +#define Fl_Menu_Button_H + +#include "Fl_Menu_.H" + +class FL_EXPORT Fl_Menu_Button : public Fl_Menu_ { +protected: + void draw(); +public: + // values for type: + enum {POPUP1 = 1, POPUP2, POPUP12, POPUP3, POPUP13, POPUP23, POPUP123}; + int handle(int); + const Fl_Menu_Item* popup(); + Fl_Menu_Button(int,int,int,int,const char * =0); +}; + +#endif + +// +// End of "$Id: Fl_Menu_Button.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Menu_Item.H b/plugins/zynaddsubfx/fltk/FL/Fl_Menu_Item.H new file mode 100644 index 000000000..33e520a67 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Menu_Item.H @@ -0,0 +1,167 @@ +// +// "$Id: Fl_Menu_Item.H 4288 2005-04-16 00:13:17Z mike $" +// +// Menu item header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Menu_Item_H +#define Fl_Menu_Item_H + +# include "Fl_Widget.H" +# include "Fl_Image.H" + +# if defined(__APPLE__) && defined(check) +# undef check +# endif + +enum { // values for flags: + FL_MENU_INACTIVE = 1, + FL_MENU_TOGGLE= 2, + FL_MENU_VALUE = 4, + FL_MENU_RADIO = 8, + FL_MENU_INVISIBLE = 0x10, + FL_SUBMENU_POINTER = 0x20, + FL_SUBMENU = 0x40, + FL_MENU_DIVIDER = 0x80, + FL_MENU_HORIZONTAL = 0x100 +}; + +extern FL_EXPORT int fl_old_shortcut(const char*); + +class Fl_Menu_; + +struct FL_EXPORT Fl_Menu_Item { + const char *text; // label() + int shortcut_; + Fl_Callback *callback_; + void *user_data_; + int flags; + uchar labeltype_; + uchar labelfont_; + uchar labelsize_; + unsigned labelcolor_; + + // advance N items, skipping submenus: + const Fl_Menu_Item *next(int=1) const; + Fl_Menu_Item *next(int i=1) { + return (Fl_Menu_Item*)(((const Fl_Menu_Item*)this)->next(i));} + const Fl_Menu_Item *first() const { return next(0); } + Fl_Menu_Item *first() { return next(0); } + + // methods on menu items: + const char* label() const {return text;} + void label(const char* a) {text=a;} + void label(Fl_Labeltype a,const char* b) {labeltype_ = a; text = b;} + Fl_Labeltype labeltype() const {return (Fl_Labeltype)labeltype_;} + void labeltype(Fl_Labeltype a) {labeltype_ = a;} + Fl_Color labelcolor() const {return (Fl_Color)labelcolor_;} + void labelcolor(unsigned a) {labelcolor_ = a;} + Fl_Font labelfont() const {return (Fl_Font)labelfont_;} + void labelfont(uchar a) {labelfont_ = a;} + uchar labelsize() const {return labelsize_;} + void labelsize(uchar a) {labelsize_ = a;} + Fl_Callback_p callback() const {return callback_;} + void callback(Fl_Callback* c, void* p) {callback_=c; user_data_=p;} + void callback(Fl_Callback* c) {callback_=c;} + void callback(Fl_Callback0*c) {callback_=(Fl_Callback*)c;} + void callback(Fl_Callback1*c, long p=0) {callback_=(Fl_Callback*)c; user_data_=(void*)p;} + void* user_data() const {return user_data_;} + void user_data(void* v) {user_data_ = v;} + long argument() const {return (long)user_data_;} + void argument(long v) {user_data_ = (void*)v;} + int shortcut() const {return shortcut_;} + void shortcut(int s) {shortcut_ = s;} + int submenu() const {return flags&(FL_SUBMENU|FL_SUBMENU_POINTER);} + int checkbox() const {return flags&FL_MENU_TOGGLE;} + int radio() const {return flags&FL_MENU_RADIO;} + int value() const {return flags&FL_MENU_VALUE;} + void set() {flags |= FL_MENU_VALUE;} + void clear() {flags &= ~FL_MENU_VALUE;} + void setonly(); + int visible() const {return !(flags&FL_MENU_INVISIBLE);} + void show() {flags &= ~FL_MENU_INVISIBLE;} + void hide() {flags |= FL_MENU_INVISIBLE;} + int active() const {return !(flags&FL_MENU_INACTIVE);} + void activate() {flags &= ~FL_MENU_INACTIVE;} + void deactivate() {flags |= FL_MENU_INACTIVE;} + int activevisible() const {return !(flags&0x11);} + + // compatibility for FLUID so it can set the image of a menu item... + void image(Fl_Image* a) {a->label(this);} + void image(Fl_Image& a) {a.label(this);} + + // used by menubar: + int measure(int* h, const Fl_Menu_*) const; + void draw(int x, int y, int w, int h, const Fl_Menu_*, int t=0) const; + + // popup menus without using an Fl_Menu_ widget: + const Fl_Menu_Item* popup( + int X, int Y, + const char *title = 0, + const Fl_Menu_Item* picked=0, + const Fl_Menu_* = 0) const; + const Fl_Menu_Item* pulldown( + int X, int Y, int W, int H, + const Fl_Menu_Item* picked = 0, + const Fl_Menu_* = 0, + const Fl_Menu_Item* title = 0, + int menubar=0) const; + const Fl_Menu_Item* test_shortcut() const; + const Fl_Menu_Item* find_shortcut(int *ip=0) const; + + void do_callback(Fl_Widget* o) const {callback_(o, user_data_);} + void do_callback(Fl_Widget* o,void* arg) const {callback_(o, arg);} + void do_callback(Fl_Widget* o,long arg) const {callback_(o, (void*)arg);} + + // back-compatability, do not use: + int checked() const {return flags&FL_MENU_VALUE;} + void check() {flags |= FL_MENU_VALUE;} + void uncheck() {flags &= ~FL_MENU_VALUE;} + int add(const char*, int shortcut, Fl_Callback*, void* =0, int = 0); + int add(const char*a, const char* b, Fl_Callback* c, + void* d = 0, int e = 0) { + return add(a,fl_old_shortcut(b),c,d,e);} + int size() const ; +}; + +typedef Fl_Menu_Item Fl_Menu; // back compatability + +enum { // back-compatability enum: + FL_PUP_NONE = 0, + FL_PUP_GREY = FL_MENU_INACTIVE, + FL_PUP_GRAY = FL_MENU_INACTIVE, + FL_MENU_BOX = FL_MENU_TOGGLE, + FL_PUP_BOX = FL_MENU_TOGGLE, + FL_MENU_CHECK = FL_MENU_VALUE, + FL_PUP_CHECK = FL_MENU_VALUE, + FL_PUP_RADIO = FL_MENU_RADIO, + FL_PUP_INVISIBLE = FL_MENU_INVISIBLE, + FL_PUP_SUBMENU = FL_SUBMENU_POINTER +}; + +#endif + +// +// End of "$Id: Fl_Menu_Item.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Menu_Window.H b/plugins/zynaddsubfx/fltk/FL/Fl_Menu_Window.H new file mode 100644 index 000000000..1056fb2e0 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Menu_Window.H @@ -0,0 +1,54 @@ +// +// "$Id: Fl_Menu_Window.H 4288 2005-04-16 00:13:17Z mike $" +// +// Menu window header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Menu_Window_H +#define Fl_Menu_Window_H + +#include "Fl_Single_Window.H" + +class FL_EXPORT Fl_Menu_Window : public Fl_Single_Window { + enum {NO_OVERLAY = 128}; +public: + void show(); + void erase(); + void flush(); + void hide(); + int overlay() {return !(flags()&NO_OVERLAY);} + void set_overlay() {clear_flag(NO_OVERLAY);} + void clear_overlay() {set_flag(NO_OVERLAY);} + ~Fl_Menu_Window(); + Fl_Menu_Window(int W, int H, const char *l = 0) + : Fl_Single_Window(W,H,l) { image(0); } + Fl_Menu_Window(int X, int Y, int W, int H, const char *l = 0) + : Fl_Single_Window(X,Y,W,H,l) { image(0); } +}; + +#endif + +// +// End of "$Id: Fl_Menu_Window.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Multi_Browser.H b/plugins/zynaddsubfx/fltk/FL/Fl_Multi_Browser.H new file mode 100644 index 000000000..c1646dc05 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Multi_Browser.H @@ -0,0 +1,43 @@ +// +// "$Id: Fl_Multi_Browser.H 4288 2005-04-16 00:13:17Z mike $" +// +// Multi browser header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Multi_Browser_H +#define Fl_Multi_Browser_H + +#include "Fl_Browser.H" + +class Fl_Multi_Browser : public Fl_Browser { +public: + Fl_Multi_Browser(int X,int Y,int W,int H,const char *L=0) + : Fl_Browser(X,Y,W,H,L) {type(FL_MULTI_BROWSER);} +}; + +#endif + +// +// End of "$Id: Fl_Multi_Browser.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Multi_Label.H b/plugins/zynaddsubfx/fltk/FL/Fl_Multi_Label.H new file mode 100644 index 000000000..f4f915112 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Multi_Label.H @@ -0,0 +1,47 @@ +// +// "$Id: Fl_Multi_Label.H 4288 2005-04-16 00:13:17Z mike $" +// +// Multi-label header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Multi_Label_H +#define Fl_Multi_Label_H + +class Fl_Widget; +struct Fl_Menu_Item; + +struct FL_EXPORT Fl_Multi_Label { + const char* labela; + const char* labelb; + uchar typea; + uchar typeb; + void label(Fl_Widget*); + void label(Fl_Menu_Item*); +}; + +#endif + +// +// End of "$Id: Fl_Multi_Label.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Multiline_Input.H b/plugins/zynaddsubfx/fltk/FL/Fl_Multiline_Input.H new file mode 100644 index 000000000..0d6d1ddd2 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Multiline_Input.H @@ -0,0 +1,43 @@ +// +// "$Id: Fl_Multiline_Input.H 4288 2005-04-16 00:13:17Z mike $" +// +// Multiline input header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Multiline_Input_H +#define Fl_Multiline_Input_H + +#include "Fl_Input.H" + +class Fl_Multiline_Input : public Fl_Input { +public: + Fl_Multiline_Input(int X,int Y,int W,int H,const char *l = 0) + : Fl_Input(X,Y,W,H,l) {type(FL_MULTILINE_INPUT);} +}; + +#endif + +// +// End of "$Id: Fl_Multiline_Input.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Multiline_Output.H b/plugins/zynaddsubfx/fltk/FL/Fl_Multiline_Output.H new file mode 100644 index 000000000..6d243587d --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Multiline_Output.H @@ -0,0 +1,43 @@ +// +// "$Id: Fl_Multiline_Output.H 4288 2005-04-16 00:13:17Z mike $" +// +// Multi line output header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Multiline_Output_H +#define Fl_Multiline_Output_H + +#include "Fl_Output.H" + +class Fl_Multiline_Output : public Fl_Output { +public: + Fl_Multiline_Output(int X,int Y,int W,int H,const char *l = 0) + : Fl_Output(X,Y,W,H,l) {type(FL_MULTILINE_OUTPUT);} +}; + +#endif + +// +// End of "$Id: Fl_Multiline_Output.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Nice_Slider.H b/plugins/zynaddsubfx/fltk/FL/Fl_Nice_Slider.H new file mode 100644 index 000000000..6a623f9ed --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Nice_Slider.H @@ -0,0 +1,42 @@ +// +// "$Id: Fl_Nice_Slider.H 4288 2005-04-16 00:13:17Z mike $" +// +// "Nice" slider header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +#ifndef Fl_Nice_Slider_H +#define Fl_Nice_Slider_H + +#include "Fl_Slider.H" + +class Fl_Nice_Slider : public Fl_Slider { +public: + Fl_Nice_Slider(int x,int y,int w,int h,const char *l=0) + : Fl_Slider(x,y,w,h,l) {type(FL_VERT_NICE_SLIDER); box(FL_FLAT_BOX);} +}; + +#endif + +// +// End of "$Id: Fl_Nice_Slider.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Object.H b/plugins/zynaddsubfx/fltk/FL/Fl_Object.H new file mode 100644 index 000000000..e2a040452 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Object.H @@ -0,0 +1,36 @@ +// +// "$Id: Fl_Object.H 4288 2005-04-16 00:13:17Z mike $" +// +// Old Fl_Object header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// This file is provided for back compatability only. Please use Fl_Widget +#ifndef Fl_Object +#define Fl_Object Fl_Widget +#endif +#include "Fl_Widget.H" + +// +// End of "$Id: Fl_Object.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Output.H b/plugins/zynaddsubfx/fltk/FL/Fl_Output.H new file mode 100644 index 000000000..23414b402 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Output.H @@ -0,0 +1,43 @@ +// +// "$Id: Fl_Output.H 4288 2005-04-16 00:13:17Z mike $" +// +// Output header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Output_H +#define Fl_Output_H + +#include "Fl_Input.H" + +class Fl_Output : public Fl_Input { +public: + Fl_Output(int X,int Y,int W,int H, const char *l = 0) + : Fl_Input(X, Y, W, H, l) {type(FL_NORMAL_OUTPUT);} +}; + +#endif + +// +// End of "$Id: Fl_Output.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Overlay_Window.H b/plugins/zynaddsubfx/fltk/FL/Fl_Overlay_Window.H new file mode 100644 index 000000000..bf873d2fb --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Overlay_Window.H @@ -0,0 +1,56 @@ +// +// "$Id: Fl_Overlay_Window.H 4288 2005-04-16 00:13:17Z mike $" +// +// Overlay window header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Overlay_Window_H +#define Fl_Overlay_Window_H + +#include "Fl_Double_Window.H" + +class FL_EXPORT Fl_Overlay_Window : public Fl_Double_Window { + friend class _Fl_Overlay; + virtual void draw_overlay() = 0; + Fl_Window *overlay_; +public: + void show(); + void flush(); + void hide(); + void resize(int,int,int,int); + ~Fl_Overlay_Window(); + int can_do_overlay(); + void redraw_overlay(); + Fl_Overlay_Window(int W, int H, const char *l=0) + : Fl_Double_Window(W,H,l) {overlay_ = 0; force_doublebuffering_=1; image(0); } + Fl_Overlay_Window(int X, int Y, int W, int H, const char *l=0) + : Fl_Double_Window(X,Y,W,H,l) {overlay_ = 0; force_doublebuffering_=1; image(0); } + void show(int a, char **b) {Fl_Double_Window::show(a,b);} +}; + +#endif + +// +// End of "$Id: Fl_Overlay_Window.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Pack.H b/plugins/zynaddsubfx/fltk/FL/Fl_Pack.H new file mode 100644 index 000000000..8e3c2ba72 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Pack.H @@ -0,0 +1,51 @@ +// +// "$Id: Fl_Pack.H 4288 2005-04-16 00:13:17Z mike $" +// +// Pack header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Pack_H +#define Fl_Pack_H + +#include + +class FL_EXPORT Fl_Pack : public Fl_Group { + int spacing_; +public: + enum { // values for type(int) + VERTICAL = 0, + HORIZONTAL = 1 + }; + void draw(); + Fl_Pack(int x,int y,int w ,int h,const char *l = 0); + int spacing() const {return spacing_;} + void spacing(int i) {spacing_ = i;} + uchar horizontal() const {return type();} +}; + +#endif + +// +// End of "$Id: Fl_Pack.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Pixmap.H b/plugins/zynaddsubfx/fltk/FL/Fl_Pixmap.H new file mode 100644 index 000000000..97f1f2695 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Pixmap.H @@ -0,0 +1,80 @@ +// +// "$Id: Fl_Pixmap.H 4288 2005-04-16 00:13:17Z mike $" +// +// Pixmap header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Pixmap_H +#define Fl_Pixmap_H +# include "Fl_Image.H" + +class Fl_Widget; +struct Fl_Menu_Item; + +// Older C++ compilers don't support the explicit keyword... :( +# if defined(__sgi) && !defined(_COMPILER_VERSION) +# define explicit +# endif // __sgi && !_COMPILER_VERSION + +class FL_EXPORT Fl_Pixmap : public Fl_Image { + void copy_data(); + void delete_data(); + void set_data(const char * const *p); + + protected: + + void measure(); + + public: + + int alloc_data; // Non-zero if data was allocated +#if defined(__APPLE__) || defined(WIN32) + void *id; // for internal use + void *mask; // for internal use (mask bitmap) +#else + unsigned id; // for internal use + unsigned mask; // for internal use (mask bitmap) +#endif // __APPLE__ || WIN32 + + explicit Fl_Pixmap(char * const * D) : Fl_Image(-1,0,1), alloc_data(0), id(0), mask(0) {set_data((const char*const*)D); measure();} + explicit Fl_Pixmap(uchar* const * D) : Fl_Image(-1,0,1), alloc_data(0), id(0), mask(0) {set_data((const char*const*)D); measure();} + explicit Fl_Pixmap(const char * const * D) : Fl_Image(-1,0,1), alloc_data(0), id(0), mask(0) {set_data((const char*const*)D); measure();} + explicit Fl_Pixmap(const uchar* const * D) : Fl_Image(-1,0,1), alloc_data(0), id(0), mask(0) {set_data((const char*const*)D); measure();} + virtual ~Fl_Pixmap(); + virtual Fl_Image *copy(int W, int H); + Fl_Image *copy() { return copy(w(), h()); } + virtual void color_average(Fl_Color c, float i); + virtual void desaturate(); + virtual void draw(int X, int Y, int W, int H, int cx=0, int cy=0); + void draw(int X, int Y) {draw(X, Y, w(), h(), 0, 0);} + virtual void label(Fl_Widget*w); + virtual void label(Fl_Menu_Item*m); + virtual void uncache(); +}; + +#endif + +// +// End of "$Id: Fl_Pixmap.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Positioner.H b/plugins/zynaddsubfx/fltk/FL/Fl_Positioner.H new file mode 100644 index 000000000..dbd147f37 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Positioner.H @@ -0,0 +1,77 @@ +// +// "$Id: Fl_Positioner.H 4288 2005-04-16 00:13:17Z mike $" +// +// Positioner header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Positioner_H +#define Fl_Positioner_H + +#ifndef Fl_Widget_H +#include "Fl_Widget.H" +#endif + +class FL_EXPORT Fl_Positioner : public Fl_Widget { + + double xmin, ymin; + double xmax, ymax; + double xvalue_, yvalue_; + double xstep_, ystep_; + +protected: + + // these allow subclasses to put the dial in a smaller area: + void draw(int, int, int, int); + int handle(int, int, int, int, int); + void draw(); + +public: + + int handle(int); + Fl_Positioner(int x,int y,int w,int h, const char *l=0); + double xvalue() const {return xvalue_;} + double yvalue() const {return yvalue_;} + int xvalue(double); + int yvalue(double); + int value(double,double); + void xbounds(double, double); + double xminimum() const {return xmin;} + void xminimum(double a) {xbounds(a,xmax);} + double xmaximum() const {return xmax;} + void xmaximum(double a) {xbounds(xmin,a);} + void ybounds(double, double); + double yminimum() const {return ymin;} + void yminimum(double a) {ybounds(a,ymax);} + double ymaximum() const {return ymax;} + void ymaximum(double a) {ybounds(ymin,a);} + void xstep(double a) {xstep_ = a;} + void ystep(double a) {ystep_ = a;} + +}; + +#endif + +// +// End of "$Id: Fl_Positioner.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Preferences.H b/plugins/zynaddsubfx/fltk/FL/Fl_Preferences.H new file mode 100644 index 000000000..392ac0568 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Preferences.H @@ -0,0 +1,171 @@ +// +// "$Id: Fl_Preferences.H 5330 2006-08-18 07:29:09Z matt $" +// +// Preferences definitions for the Fast Light Tool Kit (FLTK). +// +// Copyright 2002-2005 by Matthias Melcher. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Preferences_H +# define Fl_Preferences_H + +# ifdef WIN32 +# include +# endif // WIN32 + +# include +# include "Fl_Export.H" + + +/** + * Preferences are a data tree containing a root, branches and leafs + */ +class FL_EXPORT Fl_Preferences +{ + +public: + + enum Root { SYSTEM=0, USER }; + // enum Type { win32, macos, fltk }; + + Fl_Preferences( Root root, const char *vendor, const char *application ); + Fl_Preferences( const char *path, const char *vendor, const char *application ); + Fl_Preferences( Fl_Preferences&, const char *group ); + Fl_Preferences( Fl_Preferences*, const char *group ); + ~Fl_Preferences(); + + int groups(); + const char *group( int ); + char groupExists( const char *group ); + char deleteGroup( const char *group ); + + int entries(); + const char *entry( int ); + char entryExists( const char *entry ); + char deleteEntry( const char *entry ); + + char set( const char *entry, int value ); + char set( const char *entry, float value ); + char set( const char *entry, float value, int precision ); + char set( const char *entry, double value ); + char set( const char *entry, double value, int precision ); + char set( const char *entry, const char *value ); + char set( const char *entry, const void *value, int size ); + + char get( const char *entry, int &value, int defaultValue ); + char get( const char *entry, float &value, float defaultValue ); + char get( const char *entry, double &value, double defaultValue ); + char get( const char *entry, char *&value, const char *defaultValue ); + char get( const char *entry, char *value, const char *defaultValue, int maxSize ); + char get( const char *entry, void *&value, const void *defaultValue, int defaultSize ); + char get( const char *entry, void *value, const void *defaultValue, int defaultSize, int maxSize ); + int size( const char *entry ); + + char getUserdataPath( char *path, int pathlen ); + + void flush(); + + // char export( const char *filename, Type fileFormat ); + // char import( const char *filename ); + + class FL_EXPORT Name { + char *data_; + public: + Name( unsigned int n ); + Name( const char *format, ... ); + operator const char *() { return data_; } + ~Name(); + }; + + struct Entry + { + char *name, *value; + }; + +private: + + // make the following functions unavailable + Fl_Preferences(); + Fl_Preferences(const Fl_Preferences&); + Fl_Preferences &operator=(const Fl_Preferences&); + + static char nameBuffer[128]; + + class FL_EXPORT Node // a node contains a list to all its entries + { // and all means to manage the tree structure + Node *child_, *next_, *parent_; + char *path_; + char dirty_; + public: + Node( const char *path ); + ~Node(); + // node methods + int write( FILE *f ); + Node *find( const char *path ); + Node *search( const char *path, int offset=0 ); + Node *addChild( const char *path ); + void setParent( Node *parent ); + Node *parent() { return parent_; } + char remove(); + char dirty(); + // entry methods + int nChildren(); + const char *child( int ix ); + void set( const char *name, const char *value ); + void set( const char *line ); + void add( const char *line ); + const char *get( const char *name ); + int getEntry( const char *name ); + char deleteEntry( const char *name ); + // public values + Entry *entry; + int nEntry, NEntry; + static int lastEntrySet; + }; + friend class Node; + + class FL_EXPORT RootNode // the root node manages file paths and basic reading and writing + { + Fl_Preferences *prefs_; + char *filename_; + char *vendor_, *application_; + public: + RootNode( Fl_Preferences *, Root root, const char *vendor, const char *application ); + RootNode( Fl_Preferences *, const char *path, const char *vendor, const char *application ); + ~RootNode(); + int read(); + int write(); + char getPath( char *path, int pathlen ); + }; + friend class RootNode; + + Node *node; + RootNode *rootNode; + +}; + + +#endif // !Fl_Preferences_H + +// +// End of "$Id: Fl_Preferences.H 5330 2006-08-18 07:29:09Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Progress.H b/plugins/zynaddsubfx/fltk/FL/Fl_Progress.H new file mode 100644 index 000000000..836d53ad7 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Progress.H @@ -0,0 +1,70 @@ +// +// "$Id: Fl_Progress.H 4288 2005-04-16 00:13:17Z mike $" +// +// Progress bar widget definitions. +// +// Copyright 2000-2005 by Michael Sweet. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef _Fl_Progress_H_ +# define _Fl_Progress_H_ + +// +// Include necessary headers. +// + +#include "Fl_Widget.H" + + +// +// Progress class... +// + +class FL_EXPORT Fl_Progress : public Fl_Widget +{ + float value_, + minimum_, + maximum_; + + protected: + + virtual void draw(); + + public: + + Fl_Progress(int x, int y, int w, int h, const char *l = 0); + + void maximum(float v) { maximum_ = v; redraw(); } + float maximum() const { return (maximum_); } + + void minimum(float v) { minimum_ = v; redraw(); } + float minimum() const { return (minimum_); } + + void value(float v) { value_ = v; redraw(); } + float value() const { return (value_); } +}; + +#endif // !_Fl_Progress_H_ + +// +// End of "$Id: Fl_Progress.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Radio_Button.H b/plugins/zynaddsubfx/fltk/FL/Fl_Radio_Button.H new file mode 100644 index 000000000..888a9ac7b --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Radio_Button.H @@ -0,0 +1,43 @@ +// +// "$Id: Fl_Radio_Button.H 4288 2005-04-16 00:13:17Z mike $" +// +// Radio button header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Radio_Button_H +#define Fl_Radio_Button_H + +#include "Fl_Button.H" + +class Fl_Radio_Button : public Fl_Button { +public: + Fl_Radio_Button(int x,int y,int w,int h,const char *l=0) + : Fl_Button(x,y,w,h,l) {type(FL_RADIO_BUTTON);} +}; + +#endif + +// +// End of "$Id: Fl_Radio_Button.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Radio_Light_Button.H b/plugins/zynaddsubfx/fltk/FL/Fl_Radio_Light_Button.H new file mode 100644 index 000000000..0d6a3ae7e --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Radio_Light_Button.H @@ -0,0 +1,42 @@ +// +// "$Id: Fl_Radio_Light_Button.H 4288 2005-04-16 00:13:17Z mike $" +// +// Radio light button header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +#ifndef Fl_Radio_Light_Button_H +#define Fl_Radio_Light_Button_H + +#include "Fl_Light_Button.H" + +class Fl_Radio_Light_Button : public Fl_Light_Button { +public: + Fl_Radio_Light_Button(int X,int Y,int W,int H,const char *l=0) + : Fl_Light_Button(X,Y,W,H,l) {type(FL_RADIO_BUTTON);} +}; + +#endif + +// +// End of "$Id: Fl_Radio_Light_Button.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Radio_Round_Button.H b/plugins/zynaddsubfx/fltk/FL/Fl_Radio_Round_Button.H new file mode 100644 index 000000000..7e525c518 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Radio_Round_Button.H @@ -0,0 +1,43 @@ +// +// "$Id: Fl_Radio_Round_Button.H 4288 2005-04-16 00:13:17Z mike $" +// +// Radio round button header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Radio_Round_Button_H +#define Fl_Radio_Round_Button_H + +#include "Fl_Round_Button.H" + +class Fl_Radio_Round_Button : public Fl_Round_Button { +public: + Fl_Radio_Round_Button(int x,int y,int w,int h,const char *l=0) + : Fl_Round_Button(x,y,w,h,l) {type(FL_RADIO_BUTTON);} +}; + +#endif + +// +// End of "$Id: Fl_Radio_Round_Button.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Repeat_Button.H b/plugins/zynaddsubfx/fltk/FL/Fl_Repeat_Button.H new file mode 100644 index 000000000..5e0b65075 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Repeat_Button.H @@ -0,0 +1,49 @@ +// +// "$Id: Fl_Repeat_Button.H 4288 2005-04-16 00:13:17Z mike $" +// +// Repeat button header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Repeat_Button_H +#define Fl_Repeat_Button_H +#include "Fl.H" +#include "Fl_Button.H" + +class FL_EXPORT Fl_Repeat_Button : public Fl_Button { + static void repeat_callback(void *); +public: + int handle(int); + Fl_Repeat_Button(int X,int Y,int W,int H,const char *l=0) + : Fl_Button(X,Y,W,H,l) {} + void deactivate() { + Fl::remove_timeout(repeat_callback,this); + Fl_Button::deactivate(); + } +}; + +#endif + +// +// End of "$Id: Fl_Repeat_Button.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Return_Button.H b/plugins/zynaddsubfx/fltk/FL/Fl_Return_Button.H new file mode 100644 index 000000000..f9cb52a07 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Return_Button.H @@ -0,0 +1,45 @@ +// +// "$Id: Fl_Return_Button.H 4288 2005-04-16 00:13:17Z mike $" +// +// Return button header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Return_Button_H +#define Fl_Return_Button_H +#include "Fl_Button.H" + +class FL_EXPORT Fl_Return_Button : public Fl_Button { +protected: + void draw(); +public: + int handle(int); + Fl_Return_Button(int X, int Y, int W, int H,const char *l=0) + : Fl_Button(X,Y,W,H,l) {} +}; + +#endif + +// +// End of "$Id: Fl_Return_Button.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Roller.H b/plugins/zynaddsubfx/fltk/FL/Fl_Roller.H new file mode 100644 index 000000000..064b15068 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Roller.H @@ -0,0 +1,47 @@ +// +// "$Id: Fl_Roller.H 4288 2005-04-16 00:13:17Z mike $" +// +// Roller header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Roller_H +#define Fl_Roller_H + +#ifndef Fl_Valuator_H +#include "Fl_Valuator.H" +#endif + +class FL_EXPORT Fl_Roller : public Fl_Valuator { +protected: + void draw(); +public: + int handle(int); + Fl_Roller(int X,int Y,int W,int H,const char* L=0); +}; + +#endif + +// +// End of "$Id: Fl_Roller.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Round_Button.H b/plugins/zynaddsubfx/fltk/FL/Fl_Round_Button.H new file mode 100644 index 000000000..c47e92cd1 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Round_Button.H @@ -0,0 +1,42 @@ +// +// "$Id: Fl_Round_Button.H 4288 2005-04-16 00:13:17Z mike $" +// +// Round button header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Round_Button_H +#define Fl_Round_Button_H + +#include "Fl_Light_Button.H" + +class FL_EXPORT Fl_Round_Button : public Fl_Light_Button { +public: + Fl_Round_Button(int x,int y,int w,int h,const char *l = 0); +}; + +#endif + +// +// End of "$Id: Fl_Round_Button.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Round_Clock.H b/plugins/zynaddsubfx/fltk/FL/Fl_Round_Clock.H new file mode 100644 index 000000000..d3b9fb091 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Round_Clock.H @@ -0,0 +1,43 @@ +// +// "$Id: Fl_Round_Clock.H 4288 2005-04-16 00:13:17Z mike $" +// +// Round clock header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Round_Clock_H +#define Fl_Round_Clock_H + +#include "Fl_Clock.H" + +class Fl_Round_Clock : public Fl_Clock { +public: + Fl_Round_Clock(int x,int y,int w,int h, const char *l = 0) + : Fl_Clock(x,y,w,h,l) {type(FL_ROUND_CLOCK); box(FL_NO_BOX);} +}; + +#endif + +// +// End of "$Id: Fl_Round_Clock.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Scroll.H b/plugins/zynaddsubfx/fltk/FL/Fl_Scroll.H new file mode 100644 index 000000000..67c650fac --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Scroll.H @@ -0,0 +1,79 @@ +// +// "$Id: Fl_Scroll.H 5618 2007-01-18 19:23:24Z matt $" +// +// Scroll header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Scroll_H +#define Fl_Scroll_H + +#include "Fl_Group.H" +#include "Fl_Scrollbar.H" + +class FL_EXPORT Fl_Scroll : public Fl_Group { + + int xposition_, yposition_; + int width_, height_; + int oldx, oldy; + static void hscrollbar_cb(Fl_Widget*, void*); + static void scrollbar_cb(Fl_Widget*, void*); + void fix_scrollbar_order(); + static void draw_clip(void*,int,int,int,int); + +protected: + + void bbox(int&,int&,int&,int&); + void draw(); + +public: + + Fl_Scrollbar scrollbar; + Fl_Scrollbar hscrollbar; + + void resize(int,int,int,int); + int handle(int); + + Fl_Scroll(int X,int Y,int W,int H,const char*l=0); + + enum { // values for type() + HORIZONTAL = 1, + VERTICAL = 2, + BOTH = 3, + ALWAYS_ON = 4, + HORIZONTAL_ALWAYS = 5, + VERTICAL_ALWAYS = 6, + BOTH_ALWAYS = 7 + }; + + int xposition() const {return xposition_;} + int yposition() const {return yposition_;} + void position(int, int); + void clear(); +}; + +#endif + +// +// End of "$Id: Fl_Scroll.H 5618 2007-01-18 19:23:24Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Scrollbar.H b/plugins/zynaddsubfx/fltk/FL/Fl_Scrollbar.H new file mode 100644 index 000000000..bea51e2d2 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Scrollbar.H @@ -0,0 +1,61 @@ +// +// "$Id: Fl_Scrollbar.H 6042 2008-02-25 13:00:53Z matt $" +// +// Scroll bar header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Scrollbar_H +#define Fl_Scrollbar_H + +#include "Fl_Slider.H" + +class FL_EXPORT Fl_Scrollbar : public Fl_Slider { + + int linesize_; + int pushed_; + static void timeout_cb(void*); + void increment_cb(); +protected: + void draw(); + +public: + + Fl_Scrollbar(int x,int y,int w,int h, const char *l = 0); + ~Fl_Scrollbar(); + int handle(int); + + int value() {return int(Fl_Slider::value());} + int value(int p, int s, int top, int total) { + return scrollvalue(p, s, top, total); + } + int linesize() const {return linesize_;} + void linesize(int i) {linesize_ = i;} + +}; + +#endif + +// +// End of "$Id: Fl_Scrollbar.H 6042 2008-02-25 13:00:53Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Secret_Input.H b/plugins/zynaddsubfx/fltk/FL/Fl_Secret_Input.H new file mode 100644 index 000000000..a87bef59d --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Secret_Input.H @@ -0,0 +1,43 @@ +// +// "$Id: Fl_Secret_Input.H 4288 2005-04-16 00:13:17Z mike $" +// +// Secret input header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Secret_Input_H +#define Fl_Secret_Input_H + +#include "Fl_Input.H" + +class Fl_Secret_Input : public Fl_Input { +public: + Fl_Secret_Input(int X,int Y,int W,int H,const char *l = 0) + : Fl_Input(X,Y,W,H,l) {type(FL_SECRET_INPUT);} +}; + +#endif + +// +// End of "$Id: Fl_Secret_Input.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Select_Browser.H b/plugins/zynaddsubfx/fltk/FL/Fl_Select_Browser.H new file mode 100644 index 000000000..4a8ef9210 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Select_Browser.H @@ -0,0 +1,43 @@ +// +// "$Id: Fl_Select_Browser.H 4288 2005-04-16 00:13:17Z mike $" +// +// Select browser header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Select_Browser_H +#define Fl_Select_Browser_H + +#include "Fl_Browser.H" + +class Fl_Select_Browser : public Fl_Browser { +public: + Fl_Select_Browser(int X,int Y,int W,int H,const char *l=0) + : Fl_Browser(X,Y,W,H,l) {type(FL_SELECT_BROWSER);} +}; + +#endif + +// +// End of "$Id: Fl_Select_Browser.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Shared_Image.H b/plugins/zynaddsubfx/fltk/FL/Fl_Shared_Image.H new file mode 100644 index 000000000..042b7827d --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Shared_Image.H @@ -0,0 +1,99 @@ +// +// "$Id: Fl_Shared_Image.H 4288 2005-04-16 00:13:17Z mike $" +// +// Shared image header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Shared_Image_H +# define Fl_Shared_Image_H + +# include "Fl_Image.H" + + +// Test function for adding new formats +typedef Fl_Image *(*Fl_Shared_Handler)(const char *name, uchar *header, + int headerlen); + +// Shared images class. +class FL_EXPORT Fl_Shared_Image : public Fl_Image { + protected: + + static Fl_Shared_Image **images_; // Shared images + static int num_images_; // Number of shared images + static int alloc_images_; // Allocated shared images + static Fl_Shared_Handler *handlers_; // Additional format handlers + static int num_handlers_; // Number of format handlers + static int alloc_handlers_; // Allocated format handlers + + const char *name_; // Name of image file + int original_; // Original image? + int refcount_; // Number of times this image has been used + Fl_Image *image_; // The image that is shared + int alloc_image_; // Was the image allocated? + + static int compare(Fl_Shared_Image **i0, Fl_Shared_Image **i1); + + // Use get() and release() to load/delete images in memory... + Fl_Shared_Image(); + Fl_Shared_Image(const char *n, Fl_Image *img = 0); + virtual ~Fl_Shared_Image(); + void add(); + void update(); + + public: + + const char *name() { return name_; } + int refcount() { return refcount_; } + void release(); + void reload(); + + virtual Fl_Image *copy(int W, int H); + Fl_Image *copy() { return copy(w(), h()); } + virtual void color_average(Fl_Color c, float i); + virtual void desaturate(); + virtual void draw(int X, int Y, int W, int H, int cx, int cy); + void draw(int X, int Y) { draw(X, Y, w(), h(), 0, 0); } + virtual void uncache(); + + static Fl_Shared_Image *find(const char *n, int W = 0, int H = 0); + static Fl_Shared_Image *get(const char *n, int W = 0, int H = 0); + static Fl_Shared_Image **images(); + static int num_images(); + static void add_handler(Fl_Shared_Handler f); + static void remove_handler(Fl_Shared_Handler f); +}; + +// +// The following function is provided in the fltk_images library and +// registers all of the "extra" image file formats that are not part +// of the core FLTK library... +// + +FL_EXPORT extern void fl_register_images(); + +#endif // !Fl_Shared_Image_H + +// +// End of "$Id: Fl_Shared_Image.H 4288 2005-04-16 00:13:17Z mike $" +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Simple_Counter.H b/plugins/zynaddsubfx/fltk/FL/Fl_Simple_Counter.H new file mode 100644 index 000000000..84e07c9b5 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Simple_Counter.H @@ -0,0 +1,43 @@ +// +// "$Id: Fl_Simple_Counter.H 4288 2005-04-16 00:13:17Z mike $" +// +// Simple counter header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Simple_Counter_H +#define Fl_Simple_Counter_H + +#include "Fl_Counter.H" + +class Fl_Simple_Counter : public Fl_Counter { +public: + Fl_Simple_Counter(int x,int y,int w,int h, const char *l = 0) + : Fl_Counter(x,y,w,h,l) {type(FL_SIMPLE_COUNTER);} +}; + +#endif + +// +// End of "$Id: Fl_Simple_Counter.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Single_Window.H b/plugins/zynaddsubfx/fltk/FL/Fl_Single_Window.H new file mode 100644 index 000000000..c68e66e32 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Single_Window.H @@ -0,0 +1,49 @@ +// +// "$Id: Fl_Single_Window.H 4288 2005-04-16 00:13:17Z mike $" +// +// Single-buffered window header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Single_Window_H +#define Fl_Single_Window_H + +#include "Fl_Window.H" + +class FL_EXPORT Fl_Single_Window : public Fl_Window { +public: + void show(); + void show(int a, char **b) {Fl_Window::show(a,b);} + void flush(); + Fl_Single_Window(int W, int H, const char *l=0) + : Fl_Window(W,H,l) {} + Fl_Single_Window(int X, int Y, int W, int H, const char *l=0) + : Fl_Window(X,Y,W,H,l) {} + int make_current(); +}; + +#endif + +// +// End of "$Id: Fl_Single_Window.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Slider.H b/plugins/zynaddsubfx/fltk/FL/Fl_Slider.H new file mode 100644 index 000000000..8a6b93d60 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Slider.H @@ -0,0 +1,75 @@ +// +// "$Id: Fl_Slider.H 4288 2005-04-16 00:13:17Z mike $" +// +// Slider header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Slider_H +#define Fl_Slider_H + +#ifndef Fl_Valuator_H +#include "Fl_Valuator.H" +#endif + +// values for type(), lowest bit indicate horizontal: +#define FL_VERT_SLIDER 0 +#define FL_HOR_SLIDER 1 +#define FL_VERT_FILL_SLIDER 2 +#define FL_HOR_FILL_SLIDER 3 +#define FL_VERT_NICE_SLIDER 4 +#define FL_HOR_NICE_SLIDER 5 + +class FL_EXPORT Fl_Slider : public Fl_Valuator { + + float slider_size_; + uchar slider_; + void _Fl_Slider(); + void draw_bg(int, int, int, int); + +protected: + + // these allow subclasses to put the slider in a smaller area: + void draw(int, int, int, int); + int handle(int, int, int, int, int); + +public: + + void draw(); + int handle(int); + Fl_Slider(int x,int y,int w,int h, const char *l = 0); + Fl_Slider(uchar t,int x,int y,int w,int h, const char *l); + + int scrollvalue(int windowtop,int windowsize,int first,int totalsize); + void bounds(double a, double b); + float slider_size() const {return slider_size_;} + void slider_size(double v); + Fl_Boxtype slider() const {return (Fl_Boxtype)slider_;} + void slider(Fl_Boxtype c) {slider_ = c;} +}; + +#endif + +// +// End of "$Id: Fl_Slider.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Spinner.H b/plugins/zynaddsubfx/fltk/FL/Fl_Spinner.H new file mode 100644 index 000000000..9f76ad73e --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Spinner.H @@ -0,0 +1,224 @@ +// +// "$Id$" +// +// Spinner widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2006 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Spinner_H +# define Fl_Spinner_H + +// +// Include necessary headers... +// + +# include +# include +# include +# include +# include +# include + + +// +// Fl_Spinner widget class... +// + +class Fl_Spinner : public Fl_Group +{ + double value_; // Current value + double minimum_; // Minimum value + double maximum_; // Maximum value + double step_; // Amount to add/subtract for up/down + const char *format_; // Format string + + Fl_Input input_; // Input field for the value + Fl_Repeat_Button + up_button_, // Up button + down_button_; // Down button + + + static void sb_cb(Fl_Widget *w, Fl_Spinner *sb) { + double v; // New value + + if (w == &(sb->input_)) { + // Something changed in the input field... + v = atof(sb->input_.value()); + + if (v < sb->minimum_) { + sb->value_ = sb->minimum_; + sb->update(); + } else if (v > sb->maximum_) { + sb->value_ = sb->maximum_; + sb->update(); + } else sb->value_ = v; + } else if (w == &(sb->up_button_)) { + // Up button pressed... + v = sb->value_ + sb->step_; + + if (v > sb->maximum_) sb->value_ = sb->minimum_; + else sb->value_ = v; + + sb->update(); + } else if (w == &(sb->down_button_)) { + // Down button pressed... + v = sb->value_ - sb->step_; + + if (v < sb->minimum_) sb->value_ = sb->maximum_; + else sb->value_ = v; + + sb->update(); + } + + sb->do_callback(); + } + void update() { + char s[255]; // Value string + + if (format_[0]=='%'&&format_[1]=='.'&&format_[2]=='*') { // precision argument + // this code block is a simplified version of + // Fl_Valuator::format() and works well (but looks ugly) + int c = 0; + char temp[64], *sp = temp; + sprintf(temp, "%.12f", step_); + while (*sp) sp++; + sp--; + while (sp>temp && *sp=='0') sp--; + while (sp>temp && (*sp>='0' && *sp<='9')) { sp--; c++; } + sprintf(s, format_, c, value_); + } else { + sprintf(s, format_, value_); + } + input_.value(s); + } + + public: + + Fl_Spinner(int X, int Y, int W, int H, const char *L = 0) + : Fl_Group(X, Y, W, H, L), + input_(X, Y, W - H / 2 - 2, H), + up_button_(X + W - H / 2 - 2, Y, H / 2 + 2, H / 2, "@-42<"), + down_button_(X + W - H / 2 - 2, Y + H - H / 2, + H / 2 + 2, H / 2, "@-42>") { + end(); + + value_ = 1.0; + minimum_ = 1.0; + maximum_ = 100.0; + step_ = 1.0; + format_ = "%g"; + + align(FL_ALIGN_LEFT); + + input_.value("1"); + input_.type(FL_INT_INPUT); + input_.when(FL_WHEN_ENTER_KEY | FL_WHEN_RELEASE); + input_.callback((Fl_Callback *)sb_cb, this); + + up_button_.callback((Fl_Callback *)sb_cb, this); + + down_button_.callback((Fl_Callback *)sb_cb, this); + } + + const char *format() { return (format_); } + void format(const char *f) { format_ = f; update(); } + + int handle(int event) { + switch (event) { + case FL_KEYDOWN : + case FL_SHORTCUT : + if (Fl::event_key() == FL_Up) { + up_button_.do_callback(); + return 1; + } else if (Fl::event_key() == FL_Down) { + down_button_.do_callback(); + return 1; + } else return 0; + + case FL_FOCUS : + if (input_.take_focus()) return 1; + else return 0; + } + + return Fl_Group::handle(event); + } + + // Speling mistaks retained for source compatibility... + double maxinum() const { return (maximum_); } + double maximum() const { return (maximum_); } + void maximum(double m) { maximum_ = m; } + double mininum() const { return (minimum_); } + double minimum() const { return (minimum_); } + void minimum(double m) { minimum_ = m; } + void range(double a, double b) { minimum_ = a; maximum_ = b; } + void resize(int X, int Y, int W, int H) { + Fl_Group::resize(X,Y,W,H); + + input_.resize(X, Y, W - H / 2 - 2, H); + up_button_.resize(X + W - H / 2 - 2, Y, H / 2 + 2, H / 2); + down_button_.resize(X + W - H / 2 - 2, Y + H - H / 2, + H / 2 + 2, H / 2); + } + double step() const { return (step_); } + void step(double s) { + step_ = s; + if (step_ != (int)step_) input_.type(FL_FLOAT_INPUT); + else input_.type(FL_INT_INPUT); + update(); + } + Fl_Color textcolor() const { + return (input_.textcolor()); + } + void textcolor(Fl_Color c) { + input_.textcolor(c); + } + uchar textfont() const { + return (input_.textfont()); + } + void textfont(uchar f) { + input_.textfont(f); + } + uchar textsize() const { + return (input_.textsize()); + } + void textsize(uchar s) { + input_.textsize(s); + } + uchar type() const { return (input_.type()); } + void type(uchar v) { + if (v==FL_FLOAT_INPUT) { + format("%.*f"); + } else { + format("%.0f"); + } + input_.type(v); + } + double value() const { return (value_); } + void value(double v) { value_ = v; update(); } +}; + +#endif // !Fl_Spinner_H + +// +// End of "$Id$". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Sys_Menu_Bar.H b/plugins/zynaddsubfx/fltk/FL/Fl_Sys_Menu_Bar.H new file mode 100644 index 000000000..01f4b60c9 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Sys_Menu_Bar.H @@ -0,0 +1,56 @@ +// +// "$Id: Fl_Sys_Menu_Bar.H 4546 2005-08-29 20:05:38Z matt $" +// +// MacOS system menu bar header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Sys_Menu_Bar_H +#define Fl_Sys_Menu_Bar_H + +#include "Fl_Menu_Bar.H" + +#ifdef __APPLE__ + +class FL_EXPORT Fl_Sys_Menu_Bar : public Fl_Menu_Bar { +protected: + void draw(); +public: + Fl_Sys_Menu_Bar(int x,int y,int w,int h,const char *l=0) + : Fl_Menu_Bar(x,y,w,h,l) { + deactivate(); // don't let the old area take events + } + void menu(const Fl_Menu_Item *m); +}; + +#else + +typedef Fl_Menu_Bar Fl_Sys_Menu_Bar; + +#endif + +#endif + +// +// End of "$Id: Fl_Sys_Menu_Bar.H 4546 2005-08-29 20:05:38Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Tabs.H b/plugins/zynaddsubfx/fltk/FL/Fl_Tabs.H new file mode 100644 index 000000000..c46bb2e1a --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Tabs.H @@ -0,0 +1,57 @@ +// +// "$Id: Fl_Tabs.H 5326 2006-08-17 13:43:07Z matt $" +// +// Tab header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Tabs_H +#define Fl_Tabs_H + +#include "Fl_Group.H" + +class FL_EXPORT Fl_Tabs : public Fl_Group { + Fl_Widget *value_; + Fl_Widget *push_; + int tab_positions(int*, int*); + int tab_height(); + void draw_tab(int x1, int x2, int W, int H, Fl_Widget* o, int sel=0); +protected: + void redraw_tabs(); + void draw(); + +public: + int handle(int); + Fl_Widget *value(); + int value(Fl_Widget *); + Fl_Widget *push() const {return push_;} + int push(Fl_Widget *); + Fl_Tabs(int,int,int,int,const char * = 0); + Fl_Widget *which(int event_x, int event_y); +}; + +#endif + +// +// End of "$Id: Fl_Tabs.H 5326 2006-08-17 13:43:07Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Text_Buffer.H b/plugins/zynaddsubfx/fltk/FL/Fl_Text_Buffer.H new file mode 100644 index 000000000..1c1f60547 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Text_Buffer.H @@ -0,0 +1,263 @@ +// +// "$Id: Fl_Text_Buffer.H 6010 2008-01-04 20:31:52Z matt $" +// +// Header file for Fl_Text_Buffer class. +// +// Copyright 2001-2005 by Bill Spitzak and others. +// Original code Copyright Mark Edel. Permission to distribute under +// the LGPL for the FLTK library granted by Mark Edel. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef FL_TEXT_BUFFER_H +#define FL_TEXT_BUFFER_H + +/* Maximum length in characters of a tab or control character expansion + of a single buffer character */ +#define FL_TEXT_MAX_EXP_CHAR_LEN 20 + +#include "Fl_Export.H" + +class FL_EXPORT Fl_Text_Selection { + friend class Fl_Text_Buffer; + + public: + void set(int start, int end); + void set_rectangular(int start, int end, int rectStart, int rectEnd); + void update(int pos, int nDeleted, int nInserted); + char rectangular() { return mRectangular; } + int start() { return mStart; } + int end() { return mEnd; } + int rect_start() { return mRectStart; } + int rect_end() { return mRectEnd; } + char selected() { return mSelected; } + void selected(char b) { mSelected = b; } + int includes(int pos, int lineStartPos, int dispIndex); + int position(int* start, int* end); + int position(int* start, int* end, int* isRect, int* rectStart, int* rectEnd); + + + protected: + char mSelected; + char mRectangular; + int mStart; + int mEnd; + int mRectStart; + int mRectEnd; +}; + +typedef void (*Fl_Text_Modify_Cb)(int pos, int nInserted, int nDeleted, + int nRestyled, const char* deletedText, + void* cbArg); +typedef void (*Fl_Text_Predelete_Cb)(int pos, int nDeleted, void* cbArg); + +class FL_EXPORT Fl_Text_Buffer { + public: + Fl_Text_Buffer(int requestedSize = 0); + ~Fl_Text_Buffer(); + + int length() { return mLength; } + char* text(); + void text(const char* text); + char* text_range(int start, int end); + char character(int pos); + char* text_in_rectangle(int start, int end, int rectStart, int rectEnd); + void insert(int pos, const char* text); + void append(const char* t) { insert(length(), t); } + void remove(int start, int end); + void replace(int start, int end, const char *text); + void copy(Fl_Text_Buffer* fromBuf, int fromStart, int fromEnd, int toPos); + int undo(int *cp=0); + void canUndo(char flag=1); + int insertfile(const char *file, int pos, int buflen = 128*1024); + int appendfile(const char *file, int buflen = 128*1024) + { return insertfile(file, length(), buflen); } + int loadfile(const char *file, int buflen = 128*1024) + { select(0, length()); remove_selection(); return appendfile(file, buflen); } + int outputfile(const char *file, int start, int end, int buflen = 128*1024); + int savefile(const char *file, int buflen = 128*1024) + { return outputfile(file, 0, length(), buflen); } + + void insert_column(int column, int startPos, const char* text, + int* charsInserted, int* charsDeleted); + + void replace_rectangular(int start, int end, int rectStart, int rectEnd, + const char* text); + + void overlay_rectangular(int startPos, int rectStart, int rectEnd, + const char* text, int* charsInserted, + int* charsDeleted); + + void remove_rectangular(int start, int end, int rectStart, int rectEnd); + void clear_rectangular(int start, int end, int rectStart, int rectEnd); + int tab_distance() { return mTabDist; } + void tab_distance(int tabDist); + void select(int start, int end); + int selected() { return mPrimary.selected(); } + void unselect(); + void select_rectangular(int start, int end, int rectStart, int rectEnd); + int selection_position(int* start, int* end); + + int selection_position(int* start, int* end, int* isRect, int* rectStart, + int* rectEnd); + + char* selection_text(); + void remove_selection(); + void replace_selection(const char* text); + void secondary_select(int start, int end); + int secondary_selected() { return mSecondary.selected(); } + void secondary_unselect(); + + void secondary_select_rectangular(int start, int end, int rectStart, + int rectEnd); + + int secondary_selection_position(int* start, int* end); + int secondary_selection_position(int* start, int* end, int* isRect, + int* rectStart, int* rectEnd); + + char* secondary_selection_text(); + void remove_secondary_selection(); + void replace_secondary_selection(const char* text); + void highlight(int start, int end); + int highlight() { return mHighlight.selected(); } + void unhighlight(); + void highlight_rectangular(int start, int end, int rectStart, int rectEnd); + + int highlight_position(int* start, int* end); + int highlight_position(int* start, int* end, int* isRect, int* rectStart, + int* rectEnd); + + char* highlight_text(); + void add_modify_callback(Fl_Text_Modify_Cb bufModifiedCB, void* cbArg); + void remove_modify_callback(Fl_Text_Modify_Cb bufModifiedCB, void* cbArg); + + void call_modify_callbacks() { call_modify_callbacks(0, 0, 0, 0, 0); } + + void add_predelete_callback(Fl_Text_Predelete_Cb bufPredelCB, void* cbArg); + void remove_predelete_callback(Fl_Text_Predelete_Cb predelCB, void* cbArg); + + void call_predelete_callbacks() { call_predelete_callbacks(0, 0); } + + char* line_text(int pos); + int line_start(int pos); + int line_end(int pos); + int word_start(int pos); + int word_end(int pos); + int expand_character(int pos, int indent, char *outStr); + + static int expand_character(char c, int indent, char* outStr, int tabDist, + char nullSubsChar); + + static int character_width(char c, int indent, int tabDist, char nullSubsChar); + int count_displayed_characters(int lineStartPos, int targetPos); + int skip_displayed_characters(int lineStartPos, int nChars); + int count_lines(int startPos, int endPos); + int skip_lines(int startPos, int nLines); + int rewind_lines(int startPos, int nLines); + int findchar_forward(int startPos, char searchChar, int* foundPos); + int findchar_backward(int startPos, char searchChar, int* foundPos); + int findchars_forward(int startPos, const char* searchChars, int* foundPos); + int findchars_backward(int startPos, const char* searchChars, int* foundPos); + + int search_forward(int startPos, const char* searchString, int* foundPos, + int matchCase = 0); + + int search_backward(int startPos, const char* searchString, int* foundPos, + int matchCase = 0); + + int substitute_null_characters(char* string, int length); + void unsubstitute_null_characters(char* string); + char null_substitution_character() { return mNullSubsChar; } + Fl_Text_Selection* primary_selection() { return &mPrimary; } + Fl_Text_Selection* secondary_selection() { return &mSecondary; } + Fl_Text_Selection* highlight_selection() { return &mHighlight; } + + protected: + void call_modify_callbacks(int pos, int nDeleted, int nInserted, + int nRestyled, const char* deletedText); + void call_predelete_callbacks(int pos, int nDeleted); + + int insert_(int pos, const char* text); + void remove_(int start, int end); + + void remove_rectangular_(int start, int end, int rectStart, int rectEnd, + int* replaceLen, int* endPos); + + void insert_column_(int column, int startPos, const char* insText, + int* nDeleted, int* nInserted, int* endPos); + + void overlay_rectangular_(int startPos, int rectStart, int rectEnd, + const char* insText, int* nDeleted, + int* nInserted, int* endPos); + + void redisplay_selection(Fl_Text_Selection* oldSelection, + Fl_Text_Selection* newSelection); + + void move_gap(int pos); + void reallocate_with_gap(int newGapStart, int newGapLen); + char* selection_text_(Fl_Text_Selection* sel); + void remove_selection_(Fl_Text_Selection* sel); + void replace_selection_(Fl_Text_Selection* sel, const char* text); + + void rectangular_selection_boundaries(int lineStartPos, int rectStart, + int rectEnd, int* selStart, + int* selEnd); + + void update_selections(int pos, int nDeleted, int nInserted); + + Fl_Text_Selection mPrimary; /* highlighted areas */ + Fl_Text_Selection mSecondary; + Fl_Text_Selection mHighlight; + int mLength; /* length of the text in the buffer (the length + of the buffer itself must be calculated: + gapEnd - gapStart + length) */ + char* mBuf; /* allocated memory where the text is stored */ + int mGapStart; /* points to the first character of the gap */ + int mGapEnd; /* points to the first char after the gap */ + // The hardware tab distance used by all displays for this buffer, + // and used in computing offsets for rectangular selection operations. + int mTabDist; /* equiv. number of characters in a tab */ + int mUseTabs; /* True if buffer routines are allowed to use + tabs for padding in rectangular operations */ + int mNModifyProcs; /* number of modify-redisplay procs attached */ + Fl_Text_Modify_Cb* /* procedures to call when buffer is */ + mNodifyProcs; /* modified to redisplay contents */ + void** mCbArgs; /* caller arguments for modifyProcs above */ + int mNPredeleteProcs; /* number of pre-delete procs attached */ + Fl_Text_Predelete_Cb* /* procedure to call before text is deleted */ + mPredeleteProcs; /* from the buffer; at most one is supported. */ + void **mPredeleteCbArgs; /* caller argument for pre-delete proc above */ + int mCursorPosHint; /* hint for reasonable cursor position after + a buffer modification operation */ + char mNullSubsChar; /* NEdit is based on C null-terminated strings, + so ascii-nul characters must be substituted + with something else. This is the else, but + of course, things get quite messy when you + use it */ + char mCanUndo; /* if this buffer is used for attributes, it must + not do any undo calls */ +}; + +#endif + +// +// End of "$Id: Fl_Text_Buffer.H 6010 2008-01-04 20:31:52Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Text_Display.H b/plugins/zynaddsubfx/fltk/FL/Fl_Text_Display.H new file mode 100644 index 000000000..e7ef14d3f --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Text_Display.H @@ -0,0 +1,298 @@ +// +// "$Id: Fl_Text_Display.H 4502 2005-08-10 23:11:51Z matt $" +// +// Header file for Fl_Text_Display class. +// +// Copyright 2001-2005 by Bill Spitzak and others. +// Original code Copyright Mark Edel. Permission to distribute under +// the LGPL for the FLTK library granted by Mark Edel. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef FL_TEXT_DISPLAY_H +#define FL_TEXT_DISPLAY_H + +#include "fl_draw.H" +#include "Fl_Group.H" +#include "Fl_Widget.H" +#include "Fl_Scrollbar.H" +#include "Fl_Text_Buffer.H" + +class FL_EXPORT Fl_Text_Display: public Fl_Group { + public: + enum { + NORMAL_CURSOR, CARET_CURSOR, DIM_CURSOR, + BLOCK_CURSOR, HEAVY_CURSOR + }; + + enum { + CURSOR_POS, CHARACTER_POS + }; + + // drag types- they match Fl::event_clicks() so that single clicking to + // start a collection selects by character, double clicking selects by + // word and triple clicking selects by line. + enum { + DRAG_CHAR = 0, DRAG_WORD = 1, DRAG_LINE = 2 + }; + friend void fl_text_drag_me(int pos, Fl_Text_Display* d); + + typedef void (*Unfinished_Style_Cb)(int, void *); + + // style attributes - currently not implemented! + enum { + ATTR_NONE = 0, + ATTR_UNDERLINE = 1, + ATTR_HIDDEN = 2 + }; + + struct Style_Table_Entry { + Fl_Color color; + Fl_Font font; + int size; + unsigned attr; + }; + + Fl_Text_Display(int X, int Y, int W, int H, const char *l = 0); + ~Fl_Text_Display(); + + virtual int handle(int e); + void buffer(Fl_Text_Buffer* buf); + void buffer(Fl_Text_Buffer& buf) { buffer(&buf); } + Fl_Text_Buffer* buffer() { return mBuffer; } + void redisplay_range(int start, int end); + void scroll(int topLineNum, int horizOffset); + void insert(const char* text); + void overstrike(const char* text); + void insert_position(int newPos); + int insert_position() { return mCursorPos; } + int in_selection(int x, int y); + void show_insert_position(); + int move_right(); + int move_left(); + int move_up(); + int move_down(); + int count_lines(int start, int end, bool start_pos_is_line_start); + int line_start(int pos); + int line_end(int pos, bool start_pos_is_line_start); + int skip_lines(int startPos, int nLines, bool startPosIsLineStart); + int rewind_lines(int startPos, int nLines); + void next_word(void); + void previous_word(void); + void show_cursor(int b = 1); + void hide_cursor() { show_cursor(0); } + void cursor_style(int style); + Fl_Color cursor_color() const {return mCursor_color;} + void cursor_color(Fl_Color n) {mCursor_color = n;} + int scrollbar_width() { return scrollbar_width_; } + Fl_Align scrollbar_align() { return scrollbar_align_; } + void scrollbar_width(int W) { scrollbar_width_ = W; } + void scrollbar_align(Fl_Align a) { scrollbar_align_ = a; } + int word_start(int pos) { return buffer()->word_start(pos); } + int word_end(int pos) { return buffer()->word_end(pos); } + + + void highlight_data(Fl_Text_Buffer *styleBuffer, + const Style_Table_Entry *styleTable, + int nStyles, char unfinishedStyle, + Unfinished_Style_Cb unfinishedHighlightCB, + void *cbArg); + + int position_style(int lineStartPos, int lineLen, int lineIndex, + int dispIndex); + + Fl_Font textfont() const {return (Fl_Font)textfont_;} + void textfont(uchar s) {textfont_ = s;} + uchar textsize() const {return textsize_;} + void textsize(uchar s) {textsize_ = s;} + Fl_Color textcolor() const {return (Fl_Color)textcolor_;} + void textcolor(unsigned n) {textcolor_ = n;} + + int wrapped_column(int row, int column); + int wrapped_row(int row); + void wrap_mode(int wrap, int wrap_margin); + + virtual void resize(int X, int Y, int W, int H); + + protected: + // Most (all?) of this stuff should only be called from resize() or + // draw(). + // Anything with "vline" indicates thats it deals with currently + // visible lines. + + virtual void draw(); + void draw_text(int X, int Y, int W, int H); + void draw_range(int start, int end); + void draw_cursor(int, int); + + void draw_string(int style, int x, int y, int toX, const char *string, + int nChars); + + void draw_vline(int visLineNum, int leftClip, int rightClip, + int leftCharIndex, int rightCharIndex); + + void draw_line_numbers(bool clearAll); + + void clear_rect(int style, int x, int y, int width, int height); + void display_insert(); + + void offset_line_starts(int newTopLineNum); + + void calc_line_starts(int startLine, int endLine); + + void update_line_starts(int pos, int charsInserted, int charsDeleted, + int linesInserted, int linesDeleted, int *scrolled); + + void calc_last_char(); + + int position_to_line( int pos, int* lineNum ); + int string_width(const char* string, int length, int style); + + static void scroll_timer_cb(void*); + + static void buffer_predelete_cb(int pos, int nDeleted, void* cbArg); + static void buffer_modified_cb(int pos, int nInserted, int nDeleted, + int nRestyled, const char* deletedText, + void* cbArg); + + static void h_scrollbar_cb(Fl_Scrollbar* w, Fl_Text_Display* d); + static void v_scrollbar_cb( Fl_Scrollbar* w, Fl_Text_Display* d); + void update_v_scrollbar(); + void update_h_scrollbar(); + int measure_vline(int visLineNum); + int longest_vline(); + int empty_vlines(); + int vline_length(int visLineNum); + int xy_to_position(int x, int y, int PosType = CHARACTER_POS); + + void xy_to_rowcol(int x, int y, int* row, int* column, + int PosType = CHARACTER_POS); + + int position_to_xy(int pos, int* x, int* y); + void maintain_absolute_top_line_number(int state); + int get_absolute_top_line_number(); + void absolute_top_line_number(int oldFirstChar); + int maintaining_absolute_top_line_number(); + void reset_absolute_top_line_number(); + int position_to_linecol(int pos, int* lineNum, int* column); + void scroll_(int topLineNum, int horizOffset); + + void extend_range_for_styles(int* start, int* end); + + void find_wrap_range(const char *deletedText, int pos, int nInserted, + int nDeleted, int *modRangeStart, int *modRangeEnd, + int *linesInserted, int *linesDeleted); + void measure_deleted_lines(int pos, int nDeleted); + void wrapped_line_counter(Fl_Text_Buffer *buf, int startPos, int maxPos, + int maxLines, bool startPosIsLineStart, + int styleBufOffset, int *retPos, int *retLines, + int *retLineStart, int *retLineEnd, + bool countLastLineMissingNewLine = true); + void find_line_end(int pos, bool start_pos_is_line_start, int *lineEnd, + int *nextLineStart); + int measure_proportional_character(char c, int colNum, int pos); + int wrap_uses_character(int lineEndPos); + int range_touches_selection(Fl_Text_Selection *sel, int rangeStart, + int rangeEnd); + + int damage_range1_start, damage_range1_end; + int damage_range2_start, damage_range2_end; + int mCursorPos; + int mCursorOn; + int mCursorOldY; /* Y pos. of cursor for blanking */ + int mCursorToHint; /* Tells the buffer modified callback + where to move the cursor, to reduce + the number of redraw calls */ + int mCursorStyle; /* One of enum cursorStyles above */ + int mCursorPreferredCol; /* Column for vert. cursor movement */ + int mNVisibleLines; /* # of visible (displayed) lines */ + int mNBufferLines; /* # of newlines in the buffer */ + Fl_Text_Buffer* mBuffer; /* Contains text to be displayed */ + Fl_Text_Buffer* mStyleBuffer; /* Optional parallel buffer containing + color and font information */ + int mFirstChar, mLastChar; /* Buffer positions of first and last + displayed character (lastChar points + either to a newline or one character + beyond the end of the buffer) */ + int mContinuousWrap; /* Wrap long lines when displaying */ + int mWrapMargin; /* Margin in # of char positions for + wrapping in continuousWrap mode */ + int* mLineStarts; + int mTopLineNum; /* Line number of top displayed line + of file (first line of file is 1) */ + int mAbsTopLineNum; /* In continuous wrap mode, the line + number of the top line if the text + were not wrapped (note that this is + only maintained as needed). */ + int mNeedAbsTopLineNum; /* Externally settable flag to continue + maintaining absTopLineNum even if + it isn't needed for line # display */ + int mHorizOffset; /* Horizontal scroll pos. in pixels */ + int mTopLineNumHint; /* Line number of top displayed line + of file (first line of file is 1) */ + int mHorizOffsetHint; /* Horizontal scroll pos. in pixels */ + int mNStyles; /* Number of entries in styleTable */ + const Style_Table_Entry *mStyleTable; /* Table of fonts and colors for + coloring/syntax-highlighting */ + char mUnfinishedStyle; /* Style buffer entry which triggers + on-the-fly reparsing of region */ + Unfinished_Style_Cb mUnfinishedHighlightCB; /* Callback to parse "unfinished" */ + /* regions */ + void* mHighlightCBArg; /* Arg to unfinishedHighlightCB */ + + int mMaxsize; + + int mFixedFontWidth; /* Font width if all current fonts are + fixed and match in width, else -1 */ + int mSuppressResync; /* Suppress resynchronization of line + starts during buffer updates */ + int mNLinesDeleted; /* Number of lines deleted during + buffer modification (only used + when resynchronization is suppressed) */ + int mModifyingTabDistance; /* Whether tab distance is being + modified */ + + Fl_Color mCursor_color; + + Fl_Scrollbar* mHScrollBar; + Fl_Scrollbar* mVScrollBar; + int scrollbar_width_; + Fl_Align scrollbar_align_; + int dragPos, dragType, dragging; + int display_insert_position_hint; + struct { int x, y, w, h; } text_area; + + uchar textfont_; + uchar textsize_; + unsigned textcolor_; + + // The following are not presently used from the original NEdit code, + // but are being put here so that future versions of Fl_Text_Display + // can implement line numbers without breaking binary compatibility. + int mLineNumLeft, mLineNumWidth; + /* Line number margin and width */ +}; + +#endif + +// +// End of "$Id: Fl_Text_Display.H 4502 2005-08-10 23:11:51Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Text_Editor.H b/plugins/zynaddsubfx/fltk/FL/Fl_Text_Editor.H new file mode 100644 index 000000000..81782f120 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Text_Editor.H @@ -0,0 +1,110 @@ +// +// "$Id: Fl_Text_Editor.H 4288 2005-04-16 00:13:17Z mike $" +// +// Header file for Fl_Text_Editor class. +// +// Copyright 2001-2005 by Bill Spitzak and others. +// Original code Copyright Mark Edel. Permission to distribute under +// the LGPL for the FLTK library granted by Mark Edel. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + + +#ifndef FL_TEXT_EDITOR_H +#define FL_TEXT_EDITOR_H + +#include "Fl_Text_Display.H" + +// key will match in any state +#define FL_TEXT_EDITOR_ANY_STATE (-1L) + +class FL_EXPORT Fl_Text_Editor : public Fl_Text_Display { + public: + typedef int (*Key_Func)(int key, Fl_Text_Editor* editor); + + struct Key_Binding { + int key; + int state; + Key_Func function; + Key_Binding* next; + }; + + Fl_Text_Editor(int X, int Y, int W, int H, const char* l = 0); + ~Fl_Text_Editor() { remove_all_key_bindings(); } + virtual int handle(int e); + void insert_mode(int b) { insert_mode_ = b; } + int insert_mode() { return insert_mode_; } + + void add_key_binding(int key, int state, Key_Func f, Key_Binding** list); + void add_key_binding(int key, int state, Key_Func f) + { add_key_binding(key, state, f, &key_bindings); } + void remove_key_binding(int key, int state, Key_Binding** list); + void remove_key_binding(int key, int state) + { remove_key_binding(key, state, &key_bindings); } + void remove_all_key_bindings(Key_Binding** list); + void remove_all_key_bindings() { remove_all_key_bindings(&key_bindings); } + void add_default_key_bindings(Key_Binding** list); + Key_Func bound_key_function(int key, int state, Key_Binding* list); + Key_Func bound_key_function(int key, int state) + { return bound_key_function(key, state, key_bindings); } + void default_key_function(Key_Func f) { default_key_function_ = f; } + + // functions for the built in default bindings + static int kf_default(int c, Fl_Text_Editor* e); + static int kf_ignore(int c, Fl_Text_Editor* e); + static int kf_backspace(int c, Fl_Text_Editor* e); + static int kf_enter(int c, Fl_Text_Editor* e); + static int kf_move(int c, Fl_Text_Editor* e); + static int kf_shift_move(int c, Fl_Text_Editor* e); + static int kf_ctrl_move(int c, Fl_Text_Editor* e); + static int kf_c_s_move(int c, Fl_Text_Editor* e); + static int kf_home(int, Fl_Text_Editor* e); + static int kf_end(int c, Fl_Text_Editor* e); + static int kf_left(int c, Fl_Text_Editor* e); + static int kf_up(int c, Fl_Text_Editor* e); + static int kf_right(int c, Fl_Text_Editor* e); + static int kf_down(int c, Fl_Text_Editor* e); + static int kf_page_up(int c, Fl_Text_Editor* e); + static int kf_page_down(int c, Fl_Text_Editor* e); + static int kf_insert(int c, Fl_Text_Editor* e); + static int kf_delete(int c, Fl_Text_Editor* e); + static int kf_copy(int c, Fl_Text_Editor* e); + static int kf_cut(int c, Fl_Text_Editor* e); + static int kf_paste(int c, Fl_Text_Editor* e); + static int kf_select_all(int c, Fl_Text_Editor* e); + static int kf_undo(int c, Fl_Text_Editor* e); + + protected: + int handle_key(); + void maybe_do_callback(); + + int insert_mode_; + Key_Binding* key_bindings; + static Key_Binding* global_key_bindings; + Key_Func default_key_function_; +}; + +#endif + +// +// End of "$Id: Fl_Text_Editor.H 4288 2005-04-16 00:13:17Z mike $". +// + diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Tile.H b/plugins/zynaddsubfx/fltk/FL/Fl_Tile.H new file mode 100644 index 000000000..69250f8b9 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Tile.H @@ -0,0 +1,45 @@ +// +// "$Id: Fl_Tile.H 4288 2005-04-16 00:13:17Z mike $" +// +// Tile header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Tile_H +#define Fl_Tile_H + +#include "Fl_Group.H" + +class FL_EXPORT Fl_Tile : public Fl_Group { +public: + int handle(int); + Fl_Tile(int X,int Y,int W,int H,const char*l=0) : Fl_Group(X,Y,W,H,l) {} + void resize(int, int, int, int); + void position(int, int, int, int); +}; + +#endif + +// +// End of "$Id: Fl_Tile.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Tiled_Image.H b/plugins/zynaddsubfx/fltk/FL/Fl_Tiled_Image.H new file mode 100644 index 000000000..4af8a9d85 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Tiled_Image.H @@ -0,0 +1,59 @@ +// +// "$Id: Fl_Tiled_Image.H 4288 2005-04-16 00:13:17Z mike $" +// +// Tiled image header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Tiled_Image_H +# define Fl_Tiled_Image_H + +# include "Fl_Image.H" + + +// Tiled image class. +class FL_EXPORT Fl_Tiled_Image : public Fl_Image { + protected: + + Fl_Image *image_; // The image that is shared + int alloc_image_; // Did we allocate this image? + + public: + + Fl_Tiled_Image(Fl_Image *i, int W = 0, int H = 0); + virtual ~Fl_Tiled_Image(); + + virtual Fl_Image *copy(int W, int H); + Fl_Image *copy() { return copy(w(), h()); } + virtual void color_average(Fl_Color c, float i); + virtual void desaturate(); + virtual void draw(int X, int Y, int W, int H, int cx, int cy); + void draw(int X, int Y) { draw(X, Y, w(), h(), 0, 0); } + Fl_Image *image() { return image_; } +}; + +#endif // !Fl_Tiled_Image_H + +// +// End of "$Id: Fl_Tiled_Image.H 4288 2005-04-16 00:13:17Z mike $" +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Timer.H b/plugins/zynaddsubfx/fltk/FL/Fl_Timer.H new file mode 100644 index 000000000..765afdbf8 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Timer.H @@ -0,0 +1,65 @@ +// +// "$Id: Fl_Timer.H 4288 2005-04-16 00:13:17Z mike $" +// +// Timer header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Timer_H +#define Fl_Timer_H + +#ifndef Fl_Widget_H +#include "Fl_Widget.H" +#endif + +// values for type(): +#define FL_NORMAL_TIMER 0 +#define FL_VALUE_TIMER 1 +#define FL_HIDDEN_TIMER 2 + +class FL_EXPORT Fl_Timer : public Fl_Widget { + static void stepcb(void *); + void step(); + char on, direction_; + double delay, total; + long lastsec,lastusec; +protected: + void draw(); +public: + int handle(int); + Fl_Timer(uchar t,int x,int y,int w,int h, const char *l); + ~Fl_Timer(); + void value(double); + double value() const {return delay>0.0?delay:0.0;} + char direction() const {return direction_;} + void direction(char d) {direction_ = d;} + char suspended() const {return !on;} + void suspended(char d); +}; + +#endif + +// +// End of "$Id: Fl_Timer.H 4288 2005-04-16 00:13:17Z mike $". +// + diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Toggle_Button.H b/plugins/zynaddsubfx/fltk/FL/Fl_Toggle_Button.H new file mode 100644 index 000000000..b7764c5c0 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Toggle_Button.H @@ -0,0 +1,43 @@ +// +// "$Id: Fl_Toggle_Button.H 4288 2005-04-16 00:13:17Z mike $" +// +// Toggle button header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Toggle_Button_H +#define Fl_Toggle_Button_H + +#include "Fl_Button.H" + +class Fl_Toggle_Button : public Fl_Button { +public: + Fl_Toggle_Button(int X,int Y,int W,int H,const char *l=0) + : Fl_Button(X,Y,W,H,l) {type(FL_TOGGLE_BUTTON);} +}; + +#endif + +// +// End of "$Id: Fl_Toggle_Button.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Toggle_Light_Button.H b/plugins/zynaddsubfx/fltk/FL/Fl_Toggle_Light_Button.H new file mode 100644 index 000000000..be9e8a6f2 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Toggle_Light_Button.H @@ -0,0 +1,37 @@ +// +// "$Id: Fl_Toggle_Light_Button.H 4288 2005-04-16 00:13:17Z mike $" +// +// Toggle light button header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// provided for back-compatability only + +#ifndef Fl_Toggle_Light_Button +#include "Fl_Light_Button.H" +#define Fl_Toggle_Light_Button Fl_Light_Button +#endif + +// +// End of "$Id: Fl_Toggle_Light_Button.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Toggle_Round_Button.H b/plugins/zynaddsubfx/fltk/FL/Fl_Toggle_Round_Button.H new file mode 100644 index 000000000..087ad8e5f --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Toggle_Round_Button.H @@ -0,0 +1,37 @@ +// +// "$Id: Fl_Toggle_Round_Button.H 4288 2005-04-16 00:13:17Z mike $" +// +// Toggle round button header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// provided for back-compatability only + +#ifndef Fl_Toggle_Round_Button +#include "Fl_Round_Button.H" +#define Fl_Toggle_Round_Button Fl_Round_Button +#endif + +// +// End of "$Id: Fl_Toggle_Round_Button.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Tooltip.H b/plugins/zynaddsubfx/fltk/FL/Fl_Tooltip.H new file mode 100644 index 000000000..28fb69a23 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Tooltip.H @@ -0,0 +1,77 @@ +// +// "$Id: Fl_Tooltip.H 4288 2005-04-16 00:13:17Z mike $" +// +// Tooltip header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Tooltip_H +#define Fl_Tooltip_H + +#include +#include + +class FL_EXPORT Fl_Tooltip { +public: + static float delay() { return delay_; } + static void delay(float f) { delay_ = f; } + static float hoverdelay() { return hoverdelay_; } + static void hoverdelay(float f) { hoverdelay_ = f; } + static int enabled() { return enabled_; } + static void enable(int b = 1) { enabled_ = b;} + static void disable() { enabled_ = 0; } + static void (*enter)(Fl_Widget* w); + static void enter_area(Fl_Widget* w, int X, int Y, int W, int H, const char* tip); + static void (*exit)(Fl_Widget *w); + static Fl_Widget* current() {return widget_;} + static void current(Fl_Widget*); + + static int font() { return font_; } + static int size() { return size_; } + static void font(int i) { font_ = i; } + static void size(int s) { size_ = s; } + static void color(unsigned c) { color_ = c; } + static Fl_Color color() { return (Fl_Color)color_; } + static void textcolor(unsigned c) { textcolor_ = c; } + static Fl_Color textcolor() { return (Fl_Color)textcolor_; } + + // These should not be public, but Fl_Widget::tooltip() needs them... + static void enter_(Fl_Widget* w); + static void exit_(Fl_Widget *w); + +private: + static float delay_; + static float hoverdelay_; + static int enabled_; + static unsigned color_; + static unsigned textcolor_; + static int font_; + static int size_; + static Fl_Widget* widget_; +}; + +#endif + +// +// End of "$Id: Fl_Tooltip.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Valuator.H b/plugins/zynaddsubfx/fltk/FL/Fl_Valuator.H new file mode 100644 index 000000000..b2cd60149 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Valuator.H @@ -0,0 +1,86 @@ +// +// "$Id: Fl_Valuator.H 4288 2005-04-16 00:13:17Z mike $" +// +// Valuator header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Valuator_H +#define Fl_Valuator_H + +#ifndef Fl_Widget_H +#include "Fl_Widget.H" +#endif + +// shared type() values for classes that work in both directions: +#define FL_VERTICAL 0 +#define FL_HORIZONTAL 1 + +class FL_EXPORT Fl_Valuator : public Fl_Widget { + + double value_; + double previous_value_; + double min, max; // truncates to this range *after* rounding + double A; int B; // rounds to multiples of A/B, or no rounding if A is zero + +protected: + + int horizontal() const {return type()&1;} + Fl_Valuator(int X, int Y, int W, int H, const char* L); + + double previous_value() const {return previous_value_;} + void handle_push() {previous_value_ = value_;} + double softclamp(double); + void handle_drag(double newvalue); + void handle_release(); // use drag() value + virtual void value_damage(); // cause damage() due to value() changing + void set_value(double v) {value_ = v;} + +public: + + void bounds(double a, double b) {min=a; max=b;} + double minimum() const {return min;} + void minimum(double a) {min = a;} + double maximum() const {return max;} + void maximum(double a) {max = a;} + void range(double a, double b) {min = a; max = b;} + void step(int a) {A = a; B = 1;} + void step(double a, int b) {A = a; B = b;} + void step(double s); + double step() const {return A/B;} + void precision(int); + + double value() const {return value_;} + int value(double); + + virtual int format(char*); + double round(double); // round to nearest multiple of step + double clamp(double); // keep in range + double increment(double, int); // add n*step to value +}; + +#endif + +// +// End of "$Id: Fl_Valuator.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Value_Input.H b/plugins/zynaddsubfx/fltk/FL/Fl_Value_Input.H new file mode 100644 index 000000000..78dc21115 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Value_Input.H @@ -0,0 +1,65 @@ +// +// "$Id: Fl_Value_Input.H 4288 2005-04-16 00:13:17Z mike $" +// +// Value input header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Value_Input_H +#define Fl_Value_Input_H + +#include "Fl_Valuator.H" +#include "Fl_Input.H" + +class FL_EXPORT Fl_Value_Input : public Fl_Valuator { +public: + Fl_Input input; +private: + char soft_; + static void input_cb(Fl_Widget*,void*); + virtual void value_damage(); // cause damage() due to value() changing +public: + int handle(int); + void draw(); + void resize(int,int,int,int); + Fl_Value_Input(int x,int y,int w,int h,const char *l=0); + + void soft(char s) {soft_ = s;} + char soft() const {return soft_;} + + Fl_Font textfont() const {return input.textfont();} + void textfont(uchar s) {input.textfont(s);} + uchar textsize() const {return input.textsize();} + void textsize(uchar s) {input.textsize(s);} + Fl_Color textcolor() const {return input.textcolor();} + void textcolor(unsigned n) {input.textcolor(n);} + Fl_Color cursor_color() const {return input.cursor_color();} + void cursor_color(unsigned n) {input.cursor_color(n);} + +}; + +#endif + +// +// End of "$Id: Fl_Value_Input.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Value_Output.H b/plugins/zynaddsubfx/fltk/FL/Fl_Value_Output.H new file mode 100644 index 000000000..3353e885c --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Value_Output.H @@ -0,0 +1,58 @@ +// +// "$Id: Fl_Value_Output.H 4288 2005-04-16 00:13:17Z mike $" +// +// Value output header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Value_Output_H +#define Fl_Value_Output_H + +#ifndef Fl_Valuator_H +#include "Fl_Valuator.H" +#endif + +class FL_EXPORT Fl_Value_Output : public Fl_Valuator { + uchar textfont_, textsize_, soft_; + unsigned textcolor_; +public: + int handle(int); + void draw(); + Fl_Value_Output(int x,int y,int w,int h,const char *l=0); + + void soft(uchar s) {soft_ = s;} + uchar soft() const {return soft_;} + + Fl_Font textfont() const {return (Fl_Font)textfont_;} + void textfont(uchar s) {textfont_ = s;} + uchar textsize() const {return textsize_;} + void textsize(uchar s) {textsize_ = s;} + Fl_Color textcolor() const {return (Fl_Color)textcolor_;} + void textcolor(unsigned s) {textcolor_ = s;} +}; + +#endif + +// +// End of "$Id: Fl_Value_Output.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Value_Slider.H b/plugins/zynaddsubfx/fltk/FL/Fl_Value_Slider.H new file mode 100644 index 000000000..5162e8a3f --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Value_Slider.H @@ -0,0 +1,52 @@ +// +// "$Id: Fl_Value_Slider.H 4288 2005-04-16 00:13:17Z mike $" +// +// Value slider header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Value_Slider_H +#define Fl_Value_Slider_H + +#include "Fl_Slider.H" + +class FL_EXPORT Fl_Value_Slider : public Fl_Slider { + uchar textfont_, textsize_; + unsigned textcolor_; +public: + void draw(); + int handle(int); + Fl_Value_Slider(int x,int y,int w,int h, const char *l = 0); + Fl_Font textfont() const {return (Fl_Font)textfont_;} + void textfont(uchar s) {textfont_ = s;} + uchar textsize() const {return textsize_;} + void textsize(uchar s) {textsize_ = s;} + Fl_Color textcolor() const {return (Fl_Color)textcolor_;} + void textcolor(unsigned s) {textcolor_ = s;} +}; + +#endif + +// +// End of "$Id: Fl_Value_Slider.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Widget.H b/plugins/zynaddsubfx/fltk/FL/Fl_Widget.H new file mode 100644 index 000000000..09f93eccb --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Widget.H @@ -0,0 +1,221 @@ +// +// "$Id: Fl_Widget.H 5982 2007-11-19 16:21:48Z matt $" +// +// Widget header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Widget_H +#define Fl_Widget_H + +#include "Enumerations.H" + +class Fl_Widget; +class Fl_Window; +class Fl_Group; +class Fl_Image; + +typedef void (Fl_Callback )(Fl_Widget*, void*); +typedef Fl_Callback* Fl_Callback_p; // needed for BORLAND +typedef void (Fl_Callback0)(Fl_Widget*); +typedef void (Fl_Callback1)(Fl_Widget*, long); + +struct FL_EXPORT Fl_Label { + const char* value; + Fl_Image* image; + Fl_Image* deimage; + uchar type; + uchar font; + uchar size; + unsigned color; + void draw(int,int,int,int, Fl_Align) const ; + void measure(int&, int&) const ; +}; + +class FL_EXPORT Fl_Widget { + friend class Fl_Group; + + Fl_Group* parent_; + Fl_Callback* callback_; + void* user_data_; + short x_,y_,w_,h_; + Fl_Label label_; + int flags_; + unsigned color_; + unsigned color2_; + uchar type_; + uchar damage_; + uchar box_; + uchar align_; + uchar when_; + + const char *tooltip_; + + // unimplemented copy ctor and assignment operator + Fl_Widget(const Fl_Widget &); + Fl_Widget& operator=(const Fl_Widget &); + +protected: + + Fl_Widget(int,int,int,int,const char* =0); + + void x(int v) {x_ = (short)v;} + void y(int v) {y_ = (short)v;} + void w(int v) {w_ = (short)v;} + void h(int v) {h_ = (short)v;} + + int flags() const {return flags_;} + void set_flag(int c) {flags_ |= c;} + void clear_flag(int c) {flags_ &= ~c;} + enum {INACTIVE=1, INVISIBLE=2, OUTPUT=4, SHORTCUT_LABEL=64, + CHANGED=128, VISIBLE_FOCUS=512, COPIED_LABEL = 1024}; + + void draw_box() const; + void draw_box(Fl_Boxtype, Fl_Color) const; + void draw_box(Fl_Boxtype, int,int,int,int, Fl_Color) const; + void draw_focus() {draw_focus(box(),x(),y(),w(),h());} + void draw_focus(Fl_Boxtype, int,int,int,int) const; + void draw_label() const; + void draw_label(int, int, int, int) const; + +public: + + virtual ~Fl_Widget(); + + virtual void draw() = 0; + virtual int handle(int); + Fl_Group* parent() const {return parent_;} + void parent(Fl_Group* p) {parent_ = p;} // for hacks only, Fl_Group::add() + + uchar type() const {return type_;} + void type(uchar t) {type_ = t;} + + int x() const {return x_;} + int y() const {return y_;} + int w() const {return w_;} + int h() const {return h_;} + virtual void resize(int,int,int,int); + int damage_resize(int,int,int,int); + void position(int X,int Y) {resize(X,Y,w_,h_);} + void size(int W,int H) {resize(x_,y_,W,H);} + + Fl_Align align() const {return (Fl_Align)align_;} + void align(uchar a) {align_ = a;} + Fl_Boxtype box() const {return (Fl_Boxtype)box_;} + void box(Fl_Boxtype a) {box_ = a;} + Fl_Color color() const {return (Fl_Color)color_;} + void color(unsigned a) {color_ = a;} + Fl_Color selection_color() const {return (Fl_Color)color2_;} + void selection_color(unsigned a) {color2_ = a;} + void color(unsigned a, unsigned b) {color_=a; color2_=b;} + const char* label() const {return label_.value;} + void label(const char* a); + void copy_label(const char* a); + void label(Fl_Labeltype a,const char* b) {label_.type = a; label_.value = b;} + Fl_Labeltype labeltype() const {return (Fl_Labeltype)label_.type;} + void labeltype(Fl_Labeltype a) {label_.type = a;} + Fl_Color labelcolor() const {return (Fl_Color)label_.color;} + void labelcolor(unsigned a) {label_.color=a;} + Fl_Font labelfont() const {return (Fl_Font)label_.font;} + void labelfont(uchar a) {label_.font=a;} + uchar labelsize() const {return label_.size;} + void labelsize(uchar a) {label_.size=a;} + Fl_Image* image() {return label_.image;} + void image(Fl_Image* a) {label_.image=a;} + void image(Fl_Image& a) {label_.image=&a;} + Fl_Image* deimage() {return label_.deimage;} + void deimage(Fl_Image* a) {label_.deimage=a;} + void deimage(Fl_Image& a) {label_.deimage=&a;} + const char *tooltip() const {return tooltip_;} + void tooltip(const char *t); + Fl_Callback_p callback() const {return callback_;} + void callback(Fl_Callback* c, void* p) {callback_=c; user_data_=p;} + void callback(Fl_Callback* c) {callback_=c;} + void callback(Fl_Callback0*c) {callback_=(Fl_Callback*)c;} + void callback(Fl_Callback1*c, long p=0) {callback_=(Fl_Callback*)c; user_data_=(void*)p;} + void* user_data() const {return user_data_;} + void user_data(void* v) {user_data_ = v;} + long argument() const {return (long)user_data_;} + void argument(long v) {user_data_ = (void*)v;} + Fl_When when() const {return (Fl_When)when_;} + void when(uchar i) {when_ = i;} + + int visible() const {return !(flags_&INVISIBLE);} + int visible_r() const; + void show(); + void hide(); + void set_visible() {flags_ &= ~INVISIBLE;} + void clear_visible() {flags_ |= INVISIBLE;} + int active() const {return !(flags_&INACTIVE);} + int active_r() const; + void activate(); + void deactivate(); + int output() const {return (flags_&OUTPUT);} + void set_output() {flags_ |= OUTPUT;} + void clear_output() {flags_ &= ~OUTPUT;} + int takesevents() const {return !(flags_&(INACTIVE|INVISIBLE|OUTPUT));} + int changed() const {return flags_&CHANGED;} + void set_changed() {flags_ |= CHANGED;} + void clear_changed() {flags_ &= ~CHANGED;} + int take_focus(); + void set_visible_focus() { flags_ |= VISIBLE_FOCUS; } + void clear_visible_focus() { flags_ &= ~VISIBLE_FOCUS; } + void visible_focus(int v) { if (v) set_visible_focus(); else clear_visible_focus(); } + int visible_focus() { return flags_ & VISIBLE_FOCUS; } + + static void default_callback(Fl_Widget*, void*); + void do_callback() {callback_(this,user_data_); if (callback_ != default_callback) clear_changed();} + void do_callback(Fl_Widget* o,void* arg=0) {callback_(o,arg); if (callback_ != default_callback) clear_changed();} + void do_callback(Fl_Widget* o,long arg) {callback_(o,(void*)arg); if (callback_ != default_callback) clear_changed();} + int test_shortcut(); + static char label_shortcut(const char *t); + static int test_shortcut(const char*); + int contains(const Fl_Widget*) const ; + int inside(const Fl_Widget* o) const {return o ? o->contains(this) : 0;} + + void redraw(); + void redraw_label(); + uchar damage() const {return damage_;} + void clear_damage(uchar c = 0) {damage_ = c;} + void damage(uchar c); + void damage(uchar c,int,int,int,int); + void draw_label(int, int, int, int, Fl_Align) const; + void measure_label(int& xx, int& yy) {label_.measure(xx,yy);} + + Fl_Window* window() const ; + + // back compatability only: + Fl_Color color2() const {return (Fl_Color)color2_;} + void color2(unsigned a) {color2_ = a;} +}; + +// reserved type numbers (necessary for my cheapo RTTI) start here. +// grep the header files for "RESERVED_TYPE" to find the next available +// number. +#define FL_RESERVED_TYPE 100 + +#endif + +// +// End of "$Id: Fl_Widget.H 5982 2007-11-19 16:21:48Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Window.H b/plugins/zynaddsubfx/fltk/FL/Fl_Window.H new file mode 100644 index 000000000..16a02259e --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Window.H @@ -0,0 +1,135 @@ +// +// "$Id: Fl_Window.H 4421 2005-07-15 09:34:53Z matt $" +// +// Window header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_Window_H +#define Fl_Window_H + +#include "Fl_Group.H" + +#define FL_WINDOW 0xF0 // all subclasses have type() >= this +#define FL_DOUBLE_WINDOW 0xF1 + +class Fl_X; + +class FL_EXPORT Fl_Window : public Fl_Group { + + friend class Fl_X; + Fl_X *i; // points at the system-specific stuff + + const char* iconlabel_; + const char* xclass_; + const void* icon_; + // size_range stuff: + short minw, minh, maxw, maxh; + uchar dw, dh, aspect, size_range_set; + // cursor stuff + Fl_Cursor cursor_default; + Fl_Color cursor_fg, cursor_bg; + void size_range_(); + // values for flags(): + enum { + FL_MODAL = 64, + FL_NOBORDER = 8, + FL_FORCE_POSITION = 16, + FL_NON_MODAL = 32, + FL_OVERRIDE = 256 + }; + void _Fl_Window(); // constructor innards + + // unimplemented copy ctor and assignment operator + Fl_Window(const Fl_Window&); + Fl_Window& operator=(const Fl_Window&); + +protected: + + static Fl_Window *current_; + virtual void draw(); + virtual void flush(); + +public: + + Fl_Window(int,int,int,int, const char* = 0); + Fl_Window(int,int, const char* = 0); + virtual ~Fl_Window(); + + virtual int handle(int); + + virtual void resize(int,int,int,int); + void border(int b); + void clear_border() {set_flag(FL_NOBORDER);} + int border() const {return !(flags() & FL_NOBORDER);} + void set_override() {set_flag(FL_NOBORDER|FL_OVERRIDE);} + int override() const { return flags()&FL_OVERRIDE; } + void set_modal() {set_flag(FL_MODAL);} + int modal() const {return flags() & FL_MODAL;} + void set_non_modal() {set_flag(FL_NON_MODAL);} + int non_modal() const {return flags() & (FL_NON_MODAL|FL_MODAL);} + + void hotspot(int x, int y, int offscreen = 0); + void hotspot(const Fl_Widget*, int offscreen = 0); + void hotspot(const Fl_Widget& p, int offscreen = 0) {hotspot(&p,offscreen);} + void free_position() {clear_flag(FL_FORCE_POSITION);} + void size_range(int a, int b, int c=0, int d=0, int e=0, int f=0, int g=0) { + minw=(short)a; minh=(short)b; maxw=(short)c; maxh=(short)d; dw=(uchar)e; dh=(uchar)f; aspect=(uchar)g; size_range_();} + + const char* label() const {return Fl_Widget::label();} + const char* iconlabel() const {return iconlabel_;} + void label(const char*); + void iconlabel(const char*); + void label(const char* label, const char* iconlabel); + void copy_label(const char* a); + const char* xclass() const {return xclass_;} + void xclass(const char* c) {xclass_ = c;} + const void* icon() const {return icon_;} + void icon(const void * ic) {icon_ = ic;} + + int shown() {return i != 0;} + virtual void show(); + virtual void hide(); + void show(int, char**); + void fullscreen(); + void fullscreen_off(int,int,int,int); + void iconize(); + + int x_root() const ; + int y_root() const ; + + static Fl_Window *current(); + void make_current(); + + // for back-compatability only: + void cursor(Fl_Cursor, Fl_Color=FL_BLACK, Fl_Color=FL_WHITE); + void default_cursor(Fl_Cursor, Fl_Color=FL_BLACK, Fl_Color=FL_WHITE); + static void default_callback(Fl_Window*, void* v); + +}; + +#endif + +// +// End of "$Id: Fl_Window.H 4421 2005-07-15 09:34:53Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_Wizard.H b/plugins/zynaddsubfx/fltk/FL/Fl_Wizard.H new file mode 100644 index 000000000..4c39b7ec5 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_Wizard.H @@ -0,0 +1,62 @@ +// +// "$Id: Fl_Wizard.H 4288 2005-04-16 00:13:17Z mike $" +// +// Fl_Wizard widget definitions. +// +// Copyright 1999-2005 by Easy Software Products. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// +// Include necessary header files... +// + +#ifndef _Fl_Wizard_H_ +# define _Fl_Wizard_H_ + +# include + + +// +// Fl_Wizard class... +// + +class FL_EXPORT Fl_Wizard : public Fl_Group +{ + Fl_Widget *value_; + + void draw(); + + public: + + Fl_Wizard(int, int, int, int, const char * = 0); + + void next(); + void prev(); + Fl_Widget *value(); + void value(Fl_Widget *); +}; + +#endif // !_Fl_Wizard_H_ + +// +// End of "$Id: Fl_Wizard.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_XBM_Image.H b/plugins/zynaddsubfx/fltk/FL/Fl_XBM_Image.H new file mode 100644 index 000000000..90f94ab9f --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_XBM_Image.H @@ -0,0 +1,43 @@ +// +// "$Id: Fl_XBM_Image.H 4288 2005-04-16 00:13:17Z mike $" +// +// XBM image header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_XBM_Image_H +#define Fl_XBM_Image_H +# include "Fl_Bitmap.H" + +class FL_EXPORT Fl_XBM_Image : public Fl_Bitmap { + + public: + + Fl_XBM_Image(const char* filename); +}; + +#endif // !Fl_XBM_Image_H + +// +// End of "$Id: Fl_XBM_Image.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/Fl_XPM_Image.H b/plugins/zynaddsubfx/fltk/FL/Fl_XPM_Image.H new file mode 100644 index 000000000..9ffb1c108 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/Fl_XPM_Image.H @@ -0,0 +1,43 @@ +// +// "$Id: Fl_XPM_Image.H 4288 2005-04-16 00:13:17Z mike $" +// +// XPM image header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef Fl_XPM_Image_H +#define Fl_XPM_Image_H +# include "Fl_Pixmap.H" + +class FL_EXPORT Fl_XPM_Image : public Fl_Pixmap { + + public: + + Fl_XPM_Image(const char* filename); +}; + +#endif // !Fl_XPM_Image + +// +// End of "$Id: Fl_XPM_Image.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/dirent.h b/plugins/zynaddsubfx/fltk/FL/dirent.h new file mode 100644 index 000000000..59a925cc3 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/dirent.h @@ -0,0 +1,33 @@ +// +// "$Id: dirent.h 4288 2005-04-16 00:13:17Z mike $" +// +// Directory header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// this file is for back-compatability only +#include "filename.H" + +// +// End of "$Id: dirent.h 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/filename.H b/plugins/zynaddsubfx/fltk/FL/filename.H new file mode 100644 index 000000000..daf5e32b2 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/filename.H @@ -0,0 +1,156 @@ +/* + * "$Id: filename.H 5635 2007-01-23 15:02:00Z mike $" + * + * Filename header file for the Fast Light Tool Kit (FLTK). + * + * Copyright 1998-2005 by Bill Spitzak and others. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems on the following page: + * + * http://www.fltk.org/str.php + */ + +#ifndef FL_FILENAME_H +# define FL_FILENAME_H + +# include "Fl_Export.H" + +# define FL_PATH_MAX 256 /* all buffers are this length */ + +FL_EXPORT const char *fl_filename_name(const char *); +FL_EXPORT const char *fl_filename_ext(const char *); +FL_EXPORT char *fl_filename_setext(char *to, int tolen, const char *ext); +FL_EXPORT int fl_filename_expand(char *to, int tolen, const char *from); +FL_EXPORT int fl_filename_absolute(char *to, int tolen, const char *from); +FL_EXPORT int fl_filename_relative(char *to, int tolen, const char *from); +FL_EXPORT int fl_filename_match(const char *name, const char *pattern); +FL_EXPORT int fl_filename_isdir(const char *name); + +# ifdef __cplusplus +/* + * Under WIN32, we include filename.H from numericsort.c; this should probably change... + */ + +inline char *fl_filename_setext(char *to, const char *ext) { return fl_filename_setext(to, FL_PATH_MAX, ext); } +inline int fl_filename_expand(char *to, const char *from) { return fl_filename_expand(to, FL_PATH_MAX, from); } +inline int fl_filename_absolute(char *to, const char *from) { return fl_filename_absolute(to, FL_PATH_MAX, from); } +inline int fl_filename_relative(char *to, const char *from) { return fl_filename_relative(to, FL_PATH_MAX, from); } +# endif /* __cplusplus */ + + +# if defined(WIN32) && !defined(__CYGWIN__) && !defined(__WATCOMC__) + +struct dirent {char d_name[1];}; + +# elif defined(__APPLE__) && defined(__PROJECTBUILDER__) + +/* Apple's ProjectBuilder has the nasty habit of including recursively + * down the file tree. To avoid re-including we must + * directly include the systems math file. (Plus, I could not find a + * predefined macro for ProjectBuilder builds, so we have to define it + * in the project) + */ +# include +# include "/usr/include/dirent.h" + +# elif defined(__WATCOMC__) +# include +# include + +# else +/* + * WARNING: on some systems (very few nowadays?) may not exist. + * The correct information is in one of these files: + * + * #include + * #include + * #include + * + * plus you must do the following #define: + * + * #define dirent direct + * + * It would be best to create a file that does this... + */ +# include +# include +# endif + +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ + +FL_EXPORT int fl_alphasort(struct dirent **, struct dirent **); +FL_EXPORT int fl_casealphasort(struct dirent **, struct dirent **); +FL_EXPORT int fl_casenumericsort(struct dirent **, struct dirent **); +FL_EXPORT int fl_numericsort(struct dirent **, struct dirent **); + +typedef int (Fl_File_Sort_F)(struct dirent **, struct dirent **); + +# ifdef __cplusplus +} + +/* + * Portable "scandir" function. Ugly but necessary... + */ + +FL_EXPORT int fl_filename_list(const char *d, struct dirent ***l, + Fl_File_Sort_F *s = fl_numericsort); + +/* + * Generic function to open a Uniform Resource Identifier (URI) using a + * system-defined program (added in FLTK 1.1.8) + */ + +FL_EXPORT int fl_open_uri(const char *uri, char *msg = (char *)0, + int msglen = 0); + +/* + * _fl_filename_isdir_quick() is a private function that checks for a + * trailing slash and assumes that the passed name is a directory if + * it finds one. This function is used by Fl_File_Browser and + * Fl_File_Chooser to avoid extra stat() calls, but is not supported + * outside of FLTK... + */ +int _fl_filename_isdir_quick(const char *name); + +# endif /* __cplusplus */ + +/* + * FLTK 1.0.x compatibility definitions... + */ + +# ifdef FLTK_1_0_COMPAT +# define filename_absolute fl_filename_absolute +# define filename_expand fl_filename_expand +# define filename_ext fl_filename_ext +# define filename_isdir fl_filename_isdir +# define filename_list fl_filename_list +# define filename_match fl_filename_match +# define filename_name fl_filename_name +# define filename_relative fl_filename_relative +# define filename_setext fl_filename_setext +# define numericsort fl_numericsort +# endif /* FLTK_1_0_COMPAT */ + + +#endif /* FL_FILENAME_H */ + +/* + * End of "$Id: filename.H 5635 2007-01-23 15:02:00Z mike $". + */ diff --git a/plugins/zynaddsubfx/fltk/FL/fl_ask.H b/plugins/zynaddsubfx/fltk/FL/fl_ask.H new file mode 100644 index 000000000..f237af11d --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/fl_ask.H @@ -0,0 +1,81 @@ +// +// "$Id: fl_ask.H 4279 2005-04-13 19:35:28Z mike $" +// +// Standard dialog header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef fl_ask_H +# define fl_ask_H + +# include "Enumerations.H" + +class Fl_Widget; + +enum { + FL_BEEP_DEFAULT = 0, + FL_BEEP_MESSAGE, + FL_BEEP_ERROR, + FL_BEEP_QUESTION, + FL_BEEP_PASSWORD, + FL_BEEP_NOTIFICATION +}; + +# ifdef __GNUC__ +# define __fl_attr(x) __attribute__ (x) +# if __GNUC__ < 3 +# define __deprecated__ +# endif // __GNUC__ < 3 +# else +# define __fl_attr(x) +# endif // __GNUC__ + +FL_EXPORT void fl_beep(int type = FL_BEEP_DEFAULT); +FL_EXPORT void fl_message(const char *,...) __fl_attr((__format__ (__printf__, 1, 2))); +FL_EXPORT void fl_alert(const char *,...) __fl_attr((__format__ (__printf__, 1, 2))); +// fl_ask() is deprecated since it uses "Yes" and "No" for the buttons, +// which does not conform to the current FLTK Human Interface Guidelines. +// Use fl_choice() instead with the appropriate verbs instead. +FL_EXPORT int fl_ask(const char *,...) __fl_attr((__format__ (__printf__, 1, 2), __deprecated__)); +FL_EXPORT int fl_choice(const char *q,const char *b0,const char *b1,const char *b2,...) __fl_attr((__format__ (__printf__, 1, 5))); +FL_EXPORT const char *fl_input(const char *label, const char *deflt = 0, ...) __fl_attr((__format__ (__printf__, 1, 3))); +FL_EXPORT const char *fl_password(const char *label, const char *deflt = 0, ...) __fl_attr((__format__ (__printf__, 1, 3))); + +FL_EXPORT Fl_Widget *fl_message_icon(); +extern FL_EXPORT Fl_Font fl_message_font_; +extern FL_EXPORT unsigned char fl_message_size_; +inline void fl_message_font(unsigned char f,unsigned char s) { + fl_message_font_ = (Fl_Font)f; fl_message_size_ = s;} + +// pointers you can use to change FLTK to a foreign language: +extern FL_EXPORT const char* fl_no; +extern FL_EXPORT const char* fl_yes; +extern FL_EXPORT const char* fl_ok; +extern FL_EXPORT const char* fl_cancel; +extern FL_EXPORT const char* fl_close; + +#endif // !fl_ask_H + +// +// End of "$Id: fl_ask.H 4279 2005-04-13 19:35:28Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/fl_draw.H b/plugins/zynaddsubfx/fltk/FL/fl_draw.H new file mode 100644 index 000000000..c752795c5 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/fl_draw.H @@ -0,0 +1,207 @@ +// +// "$Id: fl_draw.H 5430 2006-09-15 15:35:16Z matt $" +// +// Portable drawing function header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef fl_draw_H +#define fl_draw_H + +#include "Enumerations.H" // for the color names + +// Image class... +class Fl_Image; + +// Label flags... +FL_EXPORT extern char fl_draw_shortcut; + +// Colors: +FL_EXPORT void fl_color(Fl_Color); // select indexed color +inline void fl_color(int c) {fl_color((Fl_Color)c);} // for back compatability +FL_EXPORT void fl_color(uchar, uchar, uchar); // select actual color +extern FL_EXPORT Fl_Color fl_color_; +inline Fl_Color fl_color() {return fl_color_;} + +// clip: +FL_EXPORT void fl_push_clip(int x, int y, int w, int h); +#define fl_clip fl_push_clip +FL_EXPORT void fl_push_no_clip(); +FL_EXPORT void fl_pop_clip(); +FL_EXPORT int fl_not_clipped(int x, int y, int w, int h); +FL_EXPORT int fl_clip_box(int, int, int, int, int& x, int& y, int& w, int& h); + +// points: +FL_EXPORT void fl_point(int x, int y); + +// line type: +FL_EXPORT void fl_line_style(int style, int width=0, char* dashes=0); +enum { + FL_SOLID = 0, + FL_DASH = 1, + FL_DOT = 2, + FL_DASHDOT = 3, + FL_DASHDOTDOT = 4, + + FL_CAP_FLAT = 0x100, + FL_CAP_ROUND = 0x200, + FL_CAP_SQUARE = 0x300, + + FL_JOIN_MITER = 0x1000, + FL_JOIN_ROUND = 0x2000, + FL_JOIN_BEVEL = 0x3000 +}; + +// rectangles tweaked to exactly fill the pixel rectangle: +FL_EXPORT void fl_rect(int x, int y, int w, int h); +inline void fl_rect(int x, int y, int w, int h, Fl_Color c) {fl_color(c); fl_rect(x,y,w,h);} +FL_EXPORT void fl_rectf(int x, int y, int w, int h); +inline void fl_rectf(int x, int y, int w, int h, Fl_Color c) {fl_color(c); fl_rectf(x,y,w,h);} + +// line segments: +FL_EXPORT void fl_line(int,int, int,int); +FL_EXPORT void fl_line(int,int, int,int, int,int); + +// closed line segments: +FL_EXPORT void fl_loop(int,int, int,int, int,int); +FL_EXPORT void fl_loop(int,int, int,int, int,int, int,int); + +// filled polygons +FL_EXPORT void fl_polygon(int,int, int,int, int,int); +FL_EXPORT void fl_polygon(int,int, int,int, int,int, int,int); + +// draw rectilinear lines, horizontal segment first: +FL_EXPORT void fl_xyline(int x, int y, int x1); +FL_EXPORT void fl_xyline(int x, int y, int x1, int y2); +FL_EXPORT void fl_xyline(int x, int y, int x1, int y2, int x3); + +// draw rectilinear lines, vertical segment first: +FL_EXPORT void fl_yxline(int x, int y, int y1); +FL_EXPORT void fl_yxline(int x, int y, int y1, int x2); +FL_EXPORT void fl_yxline(int x, int y, int y1, int x2, int y3); + +// circular lines and pie slices (code in fl_arci.C): +FL_EXPORT void fl_arc(int x, int y, int w, int h, double a1, double a2); +FL_EXPORT void fl_pie(int x, int y, int w, int h, double a1, double a2); +FL_EXPORT void fl_chord(int x, int y, int w, int h, double a1, double a2); // nyi + +// scalable drawing code (code in fl_vertex.C and fl_arc.C): +FL_EXPORT void fl_push_matrix(); +FL_EXPORT void fl_pop_matrix(); +FL_EXPORT void fl_scale(double x, double y); +FL_EXPORT void fl_scale(double x); +FL_EXPORT void fl_translate(double x, double y); +FL_EXPORT void fl_rotate(double d); +FL_EXPORT void fl_mult_matrix(double a, double b, double c, double d, double x,double y); +FL_EXPORT void fl_begin_points(); +FL_EXPORT void fl_begin_line(); +FL_EXPORT void fl_begin_loop(); +FL_EXPORT void fl_begin_polygon(); +FL_EXPORT void fl_vertex(double x, double y); +FL_EXPORT void fl_curve(double, double, double, double, double, double, double, double); +FL_EXPORT void fl_arc(double x, double y, double r, double start, double a); +FL_EXPORT void fl_circle(double x, double y, double r); +FL_EXPORT void fl_end_points(); +FL_EXPORT void fl_end_line(); +FL_EXPORT void fl_end_loop(); +FL_EXPORT void fl_end_polygon(); +FL_EXPORT void fl_begin_complex_polygon(); +FL_EXPORT void fl_gap(); +FL_EXPORT void fl_end_complex_polygon(); +// get and use transformed positions: +FL_EXPORT double fl_transform_x(double x, double y); +FL_EXPORT double fl_transform_y(double x, double y); +FL_EXPORT double fl_transform_dx(double x, double y); +FL_EXPORT double fl_transform_dy(double x, double y); +FL_EXPORT void fl_transformed_vertex(double x, double y); + +// current font: +FL_EXPORT void fl_font(int face, int size); +extern FL_EXPORT int fl_font_; +inline int fl_font() {return fl_font_;} +extern FL_EXPORT int fl_size_; +inline int fl_size() {return fl_size_;} + +// information you can get about the current font: +FL_EXPORT int fl_height(); // using "size" should work ok +inline int fl_height(int, int size) {return size;} +FL_EXPORT int fl_descent(); +FL_EXPORT double fl_width(const char*); +FL_EXPORT double fl_width(const char*, int n); +FL_EXPORT double fl_width(uchar); + +// draw using current font: +FL_EXPORT void fl_draw(const char*, int x, int y); +FL_EXPORT void fl_draw(const char*, int n, int x, int y); +FL_EXPORT void fl_measure(const char*, int& x, int& y, int draw_symbols = 1); +FL_EXPORT void fl_draw(const char*, int,int,int,int, Fl_Align, Fl_Image* img=0, + int draw_symbols = 1); +FL_EXPORT void fl_draw(const char*, int,int,int,int, Fl_Align, + void (*callthis)(const char *, int n, int x, int y), + Fl_Image* img=0, int draw_symbols = 1); + +// font encoding: +FL_EXPORT const char *fl_latin1_to_local(const char *, int n=-1); +FL_EXPORT const char *fl_local_to_latin1(const char *, int n=-1); +FL_EXPORT const char *fl_mac_roman_to_local(const char *, int n=-1); +FL_EXPORT const char *fl_local_to_mac_roman(const char *, int n=-1); + +// boxtypes: +FL_EXPORT void fl_frame(const char* s, int x, int y, int w, int h); +FL_EXPORT void fl_frame2(const char* s, int x, int y, int w, int h); +FL_EXPORT void fl_draw_box(Fl_Boxtype, int x, int y, int w, int h, Fl_Color); + +// images: +FL_EXPORT void fl_draw_image(const uchar*, int,int,int,int, int delta=3, int ldelta=0); +FL_EXPORT void fl_draw_image_mono(const uchar*, int,int,int,int, int delta=1, int ld=0); +typedef void (*Fl_Draw_Image_Cb)(void*,int,int,int,uchar*); +FL_EXPORT void fl_draw_image(Fl_Draw_Image_Cb, void*, int,int,int,int, int delta=3); +FL_EXPORT void fl_draw_image_mono(Fl_Draw_Image_Cb, void*, int,int,int,int, int delta=1); +FL_EXPORT void fl_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b); +FL_EXPORT char fl_can_do_alpha_blending(); + +FL_EXPORT uchar *fl_read_image(uchar *p, int x,int y, int w, int h, int alpha=0); + +// pixmaps: +FL_EXPORT int fl_draw_pixmap(/*const*/ char* const* data, int x,int y,Fl_Color=FL_GRAY); +FL_EXPORT int fl_measure_pixmap(/*const*/ char* const* data, int &w, int &h); +FL_EXPORT int fl_draw_pixmap(const char* const* data, int x,int y,Fl_Color=FL_GRAY); +FL_EXPORT int fl_measure_pixmap(const char* const* data, int &w, int &h); + +// other: +FL_EXPORT void fl_scroll(int X, int Y, int W, int H, int dx, int dy, + void (*draw_area)(void*, int,int,int,int), void* data); +FL_EXPORT const char* fl_shortcut_label(int); +FL_EXPORT void fl_overlay_rect(int,int,int,int); +FL_EXPORT void fl_overlay_clear(); +FL_EXPORT void fl_cursor(Fl_Cursor, Fl_Color=FL_BLACK, Fl_Color=FL_WHITE); + +// XForms symbols: +FL_EXPORT int fl_draw_symbol(const char* label,int x,int y,int w,int h, Fl_Color); +FL_EXPORT int fl_add_symbol(const char* name, void (*drawit)(Fl_Color), int scalable); + +#endif + +// +// End of "$Id: fl_draw.H 5430 2006-09-15 15:35:16Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/fl_message.H b/plugins/zynaddsubfx/fltk/FL/fl_message.H new file mode 100644 index 000000000..dd66272ee --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/fl_message.H @@ -0,0 +1,32 @@ +// +// "$Id: fl_message.H 4288 2005-04-16 00:13:17Z mike $" +// +// Standard message header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include "fl_ask.H" + +// +// End of "$Id: fl_message.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/fl_show_colormap.H b/plugins/zynaddsubfx/fltk/FL/fl_show_colormap.H new file mode 100644 index 000000000..baaa2b708 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/fl_show_colormap.H @@ -0,0 +1,37 @@ +// +// "$Id: fl_show_colormap.H 4288 2005-04-16 00:13:17Z mike $" +// +// Colormap picker header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef fl_show_colormap_H +#define fl_show_colormap_H + +FL_EXPORT Fl_Color fl_show_colormap(Fl_Color oldcol); + +#endif + +// +// End of "$Id: fl_show_colormap.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/fl_show_input.H b/plugins/zynaddsubfx/fltk/FL/fl_show_input.H new file mode 100644 index 000000000..3773f99ac --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/fl_show_input.H @@ -0,0 +1,32 @@ +// +// "$Id: fl_show_input.H 4288 2005-04-16 00:13:17Z mike $" +// +// Standard input dialog header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include "fl_ask.H" + +// +// End of "$Id: fl_show_input.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/mac.H b/plugins/zynaddsubfx/fltk/FL/mac.H new file mode 100644 index 000000000..0af94a089 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/mac.H @@ -0,0 +1,136 @@ +// +// "$Id: mac.H 5379 2006-08-29 11:03:05Z matt $" +// +// Mac header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Do not directly include this file, instead use . It will +// include this file if "__APPLE__" is defined. This is to encourage +// portability of even the system-specific code... + +#ifndef Fl_X_H +# error "Never use directly; include instead." +#endif // !Fl_X_H + +// Standard MacOS Carbon API includes... +#include + +// Now make some fixes to the headers... +#undef check // Dunno where this comes from... + +// Some random X equivalents +typedef WindowPtr Window; +struct XPoint { int x, y; }; +struct XRectangle {int x, y, width, height;}; +typedef RgnHandle Fl_Region; +void fl_clip_region(Fl_Region); +inline Fl_Region XRectangleRegion(int x, int y, int w, int h) { + Fl_Region R = NewRgn(); + SetRectRgn(R, x, y, x+w, y+h); + return R; +} +inline void XDestroyRegion(Fl_Region r) { + DisposeRgn(r); +} + +# include "Fl_Window.H" + +// This object contains all mac-specific stuff about a window: +// WARNING: this object is highly subject to change! +class Fl_X +{ +public: + Window xid; // Mac WindowPtr + GWorldPtr other_xid; // pointer for offscreen bitmaps (doublebuffer) + Fl_Window *w; // FLTK window for + Fl_Region region; + Fl_Region subRegion; // region for this specific subwindow + Fl_X *next; // linked tree to support subwindows + Fl_X *xidChildren, *xidNext; // more subwindow tree + int wait_for_expose; + CursHandle cursor; + static Fl_X* first; + static Fl_X* i(const Fl_Window* w) {return w->i;} + static int fake_X_wm(const Fl_Window*,int&,int&,int&,int&,int&); + static void make(Fl_Window*); + void flush(); + // Quartz additions: + CGContextRef gc; // graphics context (NULL when using QD) + static ATSUTextLayout atsu_layout; // windows share a global font + static ATSUStyle atsu_style; + static void q_fill_context(); // fill a Quartz context with current FLTK state + static void q_clear_clipping(); // remove all clipping from a Quartz context + static void q_release_context(Fl_X *x=0); // free all resources associated with fl_gc + static void q_begin_image(CGRect&, int x, int y, int w, int h); + static void q_end_image(); +}; + +extern void MacDestroyWindow(Fl_Window*,WindowPtr); +extern void MacMapWindow(Fl_Window*,WindowPtr); +extern void MacUnmapWindow(Fl_Window*,WindowPtr); +extern int MacUnlinkWindow(Fl_X*,Fl_X*start=0L); + +inline Window fl_xid(const Fl_Window*w) +{ + return Fl_X::i(w)->xid; +} + +extern CursHandle fl_default_cursor; + +extern struct Fl_XMap { + RGBColor rgb; + ulong pen; +} *fl_current_xmap; + +extern FL_EXPORT void *fl_display; +extern FL_EXPORT Window fl_window; +extern FL_EXPORT CGContextRef fl_gc; +extern FL_EXPORT Handle fl_system_menu; +extern FL_EXPORT class Fl_Sys_Menu_Bar *fl_sys_menu_bar; + +typedef GWorldPtr Fl_Offscreen; + +extern Fl_Offscreen fl_create_offscreen(int w, int h); +extern void fl_copy_offscreen(int x,int y,int w,int h, Fl_Offscreen gWorld, int srcx,int srcy); +extern void fl_delete_offscreen(Fl_Offscreen gWorld); +extern void fl_begin_offscreen(Fl_Offscreen gWorld); +extern void fl_end_offscreen(); + +typedef GWorldPtr Fl_Bitmask; // Carbon requires a 1-bit GWorld instead of a BitMap + +extern FL_EXPORT Fl_Bitmask fl_create_bitmask(int w, int h, const uchar *data); +extern FL_EXPORT Fl_Bitmask fl_create_alphamask(int w, int h, int d, int ld, const uchar *data); +extern FL_EXPORT void fl_delete_bitmask(Fl_Bitmask bm); + +extern void fl_open_display(); + +// Register a function for opening files via the finder... +extern void fl_open_callback(void (*cb)(const char *)); + +extern FL_EXPORT int fl_parse_color(const char* p, uchar& r, uchar& g, uchar& b); + +// +// End of "$Id: mac.H 5379 2006-08-29 11:03:05Z matt $". +// + diff --git a/plugins/zynaddsubfx/fltk/FL/mac.r b/plugins/zynaddsubfx/fltk/FL/mac.r new file mode 100644 index 000000000..3d71f2ebb --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/mac.r @@ -0,0 +1,13 @@ +data 'MBAR' (128) { + $"0001 0080" /* ...€ */ +}; + +data 'MENU' (128, "Apple") { + $"0080 0000 0000 0000 0000 FFFF FFFB 0114" /* .€........ÿÿÿû.. */ + $"0A41 626F 7574 2046 4C54 4B00 0000 0001" /* ÂAbout FLTK..... */ + $"2D00 0000 0000" /* -..... */ +}; + +data 'carb' (0) { +}; + diff --git a/plugins/zynaddsubfx/fltk/FL/math.h b/plugins/zynaddsubfx/fltk/FL/math.h new file mode 100644 index 000000000..b20af65f7 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/math.h @@ -0,0 +1,72 @@ +// +// "$Id: math.h 4288 2005-04-16 00:13:17Z mike $" +// +// Math header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifndef fl_math_h +# define fl_math_h + +// Apple's ProjectBuilder has the nasty habit of including recursively +// down the file tree. To avoid re-including we must +// directly include the systems math file. (Plus, I could not find a +// predefined macro for ProjectBuilder builds, so we have to define it +// in the project) +# if defined(__APPLE__) && defined(__PROJECTBUILDER__) +# include "/usr/include/math.h" +# else +# include +# endif + +# ifdef __EMX__ +# include +# endif + + +# ifndef M_PI +# define M_PI 3.14159265358979323846 +# define M_PI_2 1.57079632679489661923 +# define M_PI_4 0.78539816339744830962 +# define M_1_PI 0.31830988618379067154 +# define M_2_PI 0.63661977236758134308 +# endif // !M_PI + +# ifndef M_SQRT2 +# define M_SQRT2 1.41421356237309504880 +# define M_SQRT1_2 0.70710678118654752440 +# endif // !M_SQRT2 + +# if (defined(WIN32) || defined(CRAY)) && !defined(__MINGW32__) && !defined(__MWERKS__) + +inline double rint(double v) {return floor(v+.5);} +inline double copysign(double a, double b) {return b<0 ? -a : a;} + +# endif // (WIN32 || CRAY) && !__MINGW32__ && !__MWERKS__ + +#endif // !fl_math_h + + +// +// End of "$Id: math.h 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/names.h b/plugins/zynaddsubfx/fltk/FL/names.h new file mode 100644 index 000000000..39238dac2 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/names.h @@ -0,0 +1,85 @@ +// +// "$Id:$" +// +// Event names header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2007 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Thanks to Greg Ercolano for this addition. + +#ifndef FL_NAMES_H +#define FL_NAMES_H + +char *fl_eventnames[] = +{ + "FL_NO_EVENT", + "FL_PUSH", + "FL_RELEASE", + "FL_ENTER", + "FL_LEAVE", + "FL_DRAG", + "FL_FOCUS", + "FL_UNFOCUS", + "FL_KEYDOWN", + "FL_KEYUP", + "FL_CLOSE", + "FL_MOVE", + "FL_SHORTCUT", + "FL_DEACTIVATE", + "FL_ACTIVATE", + "FL_HIDE", + "FL_SHOW", + "FL_PASTE", + "FL_SELECTIONCLEAR", + "FL_MOUSEWHEEL", + "FL_DND_ENTER", + "FL_DND_DRAG", + "FL_DND_LEAVE", + "FL_DND_RELEASE", +}; + +char *fl_fontnames[] = +{ + "FL_HELVETICA", + "FL_HELVETICA_BOLD", + "FL_HELVETICA_ITALIC", + "FL_HELVETICA_BOLD_ITALIC", + "FL_COURIER", + "FL_COURIER_BOLD", + "FL_COURIER_ITALIC", + "FL_COURIER_BOLD_ITALIC", + "FL_TIMES", + "FL_TIMES_BOLD", + "FL_TIMES_ITALIC", + "FL_TIMES_BOLD_ITALIC", + "FL_SYMBOL", + "FL_SCREEN", + "FL_SCREEN_BOLD", + "FL_ZAPF_DINGBATS", +}; + +#endif /* FL_NAMES_H */ + +// +// End of "$Id:$". +// diff --git a/plugins/zynaddsubfx/fltk/FL/win32.H b/plugins/zynaddsubfx/fltk/FL/win32.H new file mode 100644 index 000000000..7122ab15e --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/win32.H @@ -0,0 +1,152 @@ +// +// "$Id: win32.H 5436 2006-09-16 16:02:00Z matt $" +// +// WIN32 header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Do not directly include this file, instead use . It will +// include this file if WIN32 is defined. This is to encourage +// portability of even the system-specific code... + +#ifndef Fl_X_H +# error "Never use directly; include instead." +#endif // !Fl_X_H + +#include +// In some of the distributions, the gcc header files are missing some stuff: +#ifndef LPMINMAXINFO +#define LPMINMAXINFO MINMAXINFO* +#endif +#ifndef VK_LWIN +#define VK_LWIN 0x5B +#define VK_RWIN 0x5C +#define VK_APPS 0x5D +#endif + +// some random X equivalents +typedef HWND Window; +typedef POINT XPoint; +struct XRectangle {int x, y, width, height;}; +typedef HRGN Fl_Region; +FL_EXPORT void fl_clip_region(Fl_Region); +inline Fl_Region XRectangleRegion(int x, int y, int w, int h) { + return CreateRectRgn(x,y,x+w,y+h); +} +inline void XDestroyRegion(Fl_Region r) {DeleteObject(r);} +inline void XClipBox(Fl_Region r,XRectangle* rect) { + RECT win_rect; GetRgnBox(r,&win_rect); + rect->x=win_rect.left; + rect->y=win_rect.top; + rect->width=win_rect.right-win_rect.left; + rect->height=win_rect.bottom-win_rect.top; +} +#define XDestroyWindow(a,b) DestroyWindow(b) +#define XMapWindow(a,b) ShowWindow(b, SW_RESTORE) +#define XUnmapWindow(a,b) ShowWindow(b, SW_HIDE) + +#include "Fl_Window.H" +// this object contains all win32-specific stuff about a window: +// Warning: this object is highly subject to change! +class FL_EXPORT Fl_X { +public: + // member variables - add new variables only at the end of this block + Window xid; + HBITMAP other_xid; // for double-buffered windows + Fl_Window* w; + Fl_Region region; + Fl_X *next; + int wait_for_expose; + HDC private_dc; // used for OpenGL + HCURSOR cursor; + HDC saved_hdc; // saves the handle of the DC currently loaded + // static variables, static functions and member functions + static Fl_X* first; + static Fl_X* i(const Fl_Window* w) {return w->i;} + static int fake_X_wm(const Fl_Window* w,int &X, int &Y, + int &bt,int &bx,int &by); + void setwindow(Fl_Window* wi) {w=wi; wi->i=this;} + void flush() {w->flush();} + void set_minmax(LPMINMAXINFO minmax); + void mapraise(); + static Fl_X* make(Fl_Window*); +}; +extern FL_EXPORT HCURSOR fl_default_cursor; +extern FL_EXPORT UINT fl_wake_msg; +inline Window fl_xid(const Fl_Window*w) {Fl_X *temp = Fl_X::i(w); return temp ? temp->xid : 0;} +FL_EXPORT Fl_Window* fl_find(Window xid); +extern FL_EXPORT char fl_override_redirect; // hack into Fl_Window::make_xid() +extern FL_EXPORT int fl_background_pixel; // hack into Fl_Window::make_xid() + +// most recent fl_color() or fl_rgbcolor() points at one of these: +extern FL_EXPORT struct Fl_XMap { + COLORREF rgb; // this should be the type the RGB() macro returns + HPEN pen; // pen, 0 if none created yet + int brush; // ref to solid brush, 0 if none created yet +} *fl_current_xmap; +inline COLORREF fl_RGB() {return fl_current_xmap->rgb;} +inline HPEN fl_pen() {return fl_current_xmap->pen;} +FL_EXPORT HBRUSH fl_brush(); // allocates a brush if necessary +FL_EXPORT HBRUSH fl_brush_action(int); // now does the real work + +extern FL_EXPORT HINSTANCE fl_display; +extern FL_EXPORT Window fl_window; +extern FL_EXPORT HDC fl_gc; +extern FL_EXPORT HPALETTE fl_palette; // non-zero only on 8-bit displays! +extern FL_EXPORT HDC fl_GetDC(Window); +extern FL_EXPORT MSG fl_msg; +extern FL_EXPORT void fl_release_dc(HWND w, HDC dc); +extern FL_EXPORT void fl_save_dc( HWND w, HDC dc); + +// off-screen pixmaps: create, destroy, draw into, copy to window +typedef HBITMAP Fl_Offscreen; +#define fl_create_offscreen(w, h) CreateCompatibleBitmap(fl_gc, w, h) + +extern FL_EXPORT HDC fl_makeDC(HBITMAP); + +#define fl_begin_offscreen(b) \ + HDC _sgc=fl_gc; Window _sw=fl_window; \ + fl_gc=fl_makeDC(b); int _savedc = SaveDC(fl_gc); fl_window=(HWND)b; fl_push_no_clip() + +#define fl_end_offscreen() \ + fl_pop_clip(); RestoreDC(fl_gc, _savedc); DeleteDC(fl_gc); fl_window=_sw; fl_gc = _sgc + +FL_EXPORT void fl_copy_offscreen(int x,int y,int w,int h,HBITMAP pixmap,int srcx,int srcy); +FL_EXPORT void fl_copy_offscreen_with_alpha(int x,int y,int w,int h,HBITMAP pixmap,int srcx,int srcy); +#define fl_delete_offscreen(bitmap) DeleteObject(bitmap); + +// Bitmap masks +typedef HBITMAP Fl_Bitmask; + +extern FL_EXPORT Fl_Bitmask fl_create_bitmask(int w, int h, const uchar *data); +extern FL_EXPORT Fl_Bitmask fl_create_alphamask(int w, int h, int d, int ld, const uchar *data); +extern FL_EXPORT void fl_delete_bitmask(Fl_Bitmask bm); + +// Dummy function to register a function for opening files via the window manager... +inline void fl_open_callback(void (*)(const char *)) {} + +extern FL_EXPORT int fl_parse_color(const char* p, uchar& r, uchar& g, uchar& b); + +// +// End of "$Id: win32.H 5436 2006-09-16 16:02:00Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/FL/x.H b/plugins/zynaddsubfx/fltk/FL/x.H new file mode 100644 index 000000000..3a3139317 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/FL/x.H @@ -0,0 +1,172 @@ +// +// "$Id: x.H 5262 2006-07-18 11:23:20Z matt $" +// +// X11 header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// These are internal fltk symbols that are necessary or useful for +// calling Xlib. You should include this file if (and ONLY if) you +// need to call Xlib directly. These symbols may not exist on non-X +// systems. + +#ifndef Fl_X_H +# define Fl_X_H + +# include "Enumerations.H" + +# ifdef WIN32 +# include "win32.H" +# elif defined(__APPLE__) +# include "mac.H" +# else +# if defined(_ABIN32) || defined(_ABI64) // fix for broken SGI Irix X .h files +# pragma set woff 3322 +# endif +# include +# include +# if defined(_ABIN32) || defined(_ABI64) +# pragma reset woff 3322 +# endif +# include +# include "Fl_Window.H" + +// Mirror X definition of Region to Fl_Region, for portability... +typedef Region Fl_Region; + +FL_EXPORT void fl_open_display(); +FL_EXPORT void fl_open_display(Display*); +FL_EXPORT void fl_close_display(); + +// constant info about the X server connection: +extern FL_EXPORT Display *fl_display; +extern FL_EXPORT Window fl_message_window; +extern FL_EXPORT int fl_screen; +extern FL_EXPORT XVisualInfo *fl_visual; +extern FL_EXPORT Colormap fl_colormap; + +#if USE_XFT +// access to core fonts +FL_EXPORT XFontStruct* fl_xxfont(); +class Fl_XFont_On_Demand +{ +public: + Fl_XFont_On_Demand(XFontStruct* p = NULL) : ptr(p) { } + Fl_XFont_On_Demand& operator=(const Fl_XFont_On_Demand& x) + { ptr = x.ptr; return *this; } + Fl_XFont_On_Demand& operator=(XFontStruct* p) + { ptr = p; return *this; } + XFontStruct* value() { if (!ptr) { ptr = fl_xxfont(); } return ptr; } + operator XFontStruct*() { return value(); } + XFontStruct& operator*() { return *value(); } + XFontStruct* operator->() { return value(); } + bool operator==(const Fl_XFont_On_Demand& x) { return ptr == x.ptr; } + bool operator!=(const Fl_XFont_On_Demand& x) { return ptr != x.ptr; } +private: + XFontStruct* ptr; +}; +extern FL_EXPORT Fl_XFont_On_Demand fl_xfont; +#else +extern FL_EXPORT XFontStruct* fl_xfont; +#endif + +// drawing functions: +extern FL_EXPORT GC fl_gc; +extern FL_EXPORT Window fl_window; +extern FL_EXPORT void *fl_xftfont; +FL_EXPORT ulong fl_xpixel(Fl_Color i); +FL_EXPORT ulong fl_xpixel(uchar r, uchar g, uchar b); +FL_EXPORT void fl_clip_region(Fl_Region); +FL_EXPORT Fl_Region fl_clip_region(); +FL_EXPORT Fl_Region XRectangleRegion(int x, int y, int w, int h); // in fl_rect.cxx + +// feed events into fltk: +FL_EXPORT int fl_handle(const XEvent&); + +// you can use these in Fl::add_handler() to look at events: +extern FL_EXPORT const XEvent* fl_xevent; +extern FL_EXPORT ulong fl_event_time; + +// off-screen pixmaps: create, destroy, draw into, copy to window: +typedef ulong Fl_Offscreen; +#define fl_create_offscreen(w,h) \ + XCreatePixmap(fl_display, fl_window, w, h, fl_visual->depth) +// begin/end are macros that save the old state in local variables: +# define fl_begin_offscreen(pixmap) \ + Window _sw=fl_window; fl_window=pixmap; fl_push_no_clip() +# define fl_end_offscreen() \ + fl_pop_clip(); fl_window = _sw + +# define fl_copy_offscreen(x,y,w,h,pixmap,srcx,srcy) \ + XCopyArea(fl_display, pixmap, fl_window, fl_gc, srcx, srcy, w, h, x, y) +# define fl_delete_offscreen(pixmap) XFreePixmap(fl_display, pixmap) + +// Bitmap masks +typedef ulong Fl_Bitmask; + +extern FL_EXPORT Fl_Bitmask fl_create_bitmask(int w, int h, const uchar *data); +extern FL_EXPORT Fl_Bitmask fl_create_alphamask(int w, int h, int d, int ld, const uchar *data); +extern FL_EXPORT void fl_delete_bitmask(Fl_Bitmask bm); + +// this object contains all X-specific stuff about a window: +// Warning: this object is highly subject to change! It's definition +// is only here so that fl_xid can be declared inline: +class FL_EXPORT Fl_X { +public: + Window xid; + Window other_xid; + Fl_Window *w; + Fl_Region region; + Fl_X *next; + char wait_for_expose; + char backbuffer_bad; // used for XDBE + static Fl_X* first; + static Fl_X* i(const Fl_Window* wi) {return wi->i;} + void setwindow(Fl_Window* wi) {w=wi; wi->i=this;} + void sendxjunk(); + static void make_xid(Fl_Window*,XVisualInfo* =fl_visual, Colormap=fl_colormap); + static Fl_X* set_xid(Fl_Window*, Window); + // kludges to get around protection: + void flush() {w->flush();} + static void x(Fl_Window* wi, int X) {wi->x(X);} + static void y(Fl_Window* wi, int Y) {wi->y(Y);} +}; + +// convert xid <-> Fl_Window: +inline Window fl_xid(const Fl_Window*w) {return Fl_X::i(w)->xid;} +FL_EXPORT Fl_Window* fl_find(Window xid); + +extern FL_EXPORT char fl_override_redirect; // hack into Fl_X::make_xid() +extern FL_EXPORT int fl_background_pixel; // hack into Fl_X::make_xid() + +// Dummy function to register a function for opening files via the window manager... +inline void fl_open_callback(void (*)(const char *)) {} + +extern FL_EXPORT int fl_parse_color(const char* p, uchar& r, uchar& g, uchar& b); + +# endif +#endif + +// +// End of "$Id: x.H 5262 2006-07-18 11:23:20Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/README b/plugins/zynaddsubfx/fltk/README new file mode 100644 index 000000000..80edbe936 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/README @@ -0,0 +1,197 @@ +README - Fast Light Tool Kit (FLTK) Version 1.1.9 +------------------------------------------------- + +WHAT IS FLTK? + + The Fast Light Tool Kit ("FLTK", pronounced "fulltick") is a + a cross-platform C++ GUI toolkit for UNIX(r)/Linux(r) (X11), + Microsoft(r) Windows(r), and MacOS(r) X. FLTK provides + modern GUI functionality without the bloat and supports 3D + graphics via OpenGL(r) and its built-in GLUT emulation. It + was originally developed by Mr. Bill Spitzak and is + currently maintained by a small group of developers across + the world with a central repository in the US. + + +LICENSING + + FLTK comes with complete free source code. FLTK is available + under the terms of the GNU Library General Public License. + Contrary to popular belief, it can be used in commercial + software! (Even Bill Gates could use it.) + + +ON-LINE DOCUMENTATION + + All of the documentation is in HTML in the subdirectory + "documentation". The "index.html" file should be your + starting point. PostScript(tm) and PDF versions of this + documentation is also available from the FLTK web site at: + + http://www.fltk.org/documentation.php + + +BUILDING AND INSTALLING FLTK UNDER UNIX AND MacOS X + + In most cases you can just type "make". This will run + configure with the default (no) options and then compile + everything. + + FLTK uses GNU autoconf to configure itself for your UNIX + platform. The main things that the configure script will + look for are the X11, OpenGL (or Mesa), and JPEG header and + library files. Make sure that they are in the standard + include/library locations. If they aren't you need to + define the CFLAGS, CXXFLAGS, and LDFLAGS environment + variables. + + If you aren't using "gcc", "g++", "c++", or "CC" for your + C++ compiler, you'll also need to set the CXX environment + variable. Similarly, if you aren't using "gcc" or "cc" for + your C compiler you'll need to set the CC environment + variable. + + You can run configure yourself to get the exact setup you + need. Type "./configure ". Options include: + + --enable-cygwin - Enable the Cygwin libraries (WIN32) + --enable-debug - Enable debugging code & symbols + --disable-gl - Disable OpenGL support + --enable-shared - Enable generation of shared libraries + --enable-threads - Enable multithreading support + --enable-xdbe - Enable the X double-buffer extension + --enable-xft - Enable the Xft library (anti-aliased fonts) + + --bindir=/path - Set the location for executables + [default = /usr/local/bin] + --libdir=/path - Set the location for libraries + [default = /usr/local/lib] + --includedir=/path - Set the location for include files. + [default = /usr/local/include] + --prefix=/dir - Set the directory prefix for files + [default = /usr/local] + + When the configure script is done you can just run the + "make" command. This will build the library, FLUID tool, and + all of the test programs. + + To install the library, become root and type "make + install". This will copy the "fluid" executable to + "bindir", the header files to "includedir", and the library + files to "libdir". + + +BUILDING FLTK UNDER MICROSOFT WINDOWS + + There are two ways to build FLTK under Microsoft Windows. + The first is to use the VC++ 6.0 project files under the + "visualc" directory. Just open (or double-click on) the + "fltk.dsw" file to get the whole shebang. + + The second method is to use a GNU-based development tool + with the files in the "makefiles" directory. To build + with the CygWin tools, use the supplied configure script + as specified in the UNIX section above: + + sh configure ...options... + + To build using other tools simply copy the appropriate + makeinclude and config files to the main directory and do a + make: + + copy makefiles\Makefile. Makefile + make + + +BUILDING FLTK UNDER OS/2 + + The current OS/2 build requires XFree86 for OS/2 to work. A + native Presentation Manager version has not been implemented + yet (volunteers are welcome!). + + To build the XFree86 version of FLTK for OS/2, copy the + appropriate makeinclude and config files to the main + directory and do a make: + + copy makefiles\Makefile.os2x Makefile + make + + +INTERNET RESOURCES + + FLTK is available on the 'net in a bunch of locations: + + - WWW: http://www.fltk.org/ + http://www.fltk.org/str.php [for reporting bugs] + http://www.fltk.org/software.php [source code] + + - FTP: http://ftp.easysw.com/pub/fltk + ftp://ftp.easysw.com/pub/fltk + ftp://ftp2.easysw.com/pub/fltk + ftp://ftp.funet.fi/pub/mirrors/ftp.easysw.com/pub/fltk + ftp://linux.mathematik.tu-darmstadt.de/pub/linux/mirrors/misc/fltk + ftp://gd.tuwien.ac.at/hci/fltk + + - EMail: fltk@fltk.org [see instructions below] + + To send a message to the FLTK mailing list ("fltk@fltk.org") + you must first join the list. Non-member submissions are + blocked to avoid problems with SPAM. + + To join the FLTK mailing list, go the following web page: + + http://lists.easysw.com/listinfo/fltk + + +REPORTING BUGS + + To report a bug in FLTK, use the form at: + + http://www.fltk.org/str.php + + For general support and questions, please use the FLTK + mailing list at "fltk@fltk.org". + + +TRADEMARKS + + Microsoft and Windows are registered trademarks of Microsoft + Corporation. UNIX is a registered trademark of the X/Open + Group, Inc. OpenGL is a registered trademark of Silicon + Graphics, Inc. MacOS is a registered trademark of Apple + Computers, Inc. + + +COPYRIGHT + + FLTK is copyright 1998-2008 by Bill Spitzak + (spitzak@users.sourceforge.net) and others, including: + + Craig P. Earls + Curtis Edwards (trilex@users.sourceforge.net) + Gustavo Hime (hime@users.sourceforge.net) + Talbot Hughes + Robert Kesterson (robertk@users.sourceforge.net) + Matthias Melcher (matthiaswm@users.sourceforge.net) + James Dean Palmer (jamespalmer@users.sourceforge.net) + Vincent Penne (vincentp@users.sourceforge.net) + Michael Sweet (easysw@users.sourceforge.net) + Carl Thompson (clip@users.sourceforge.net) + Nafees Bin Zafar (nafees@users.sourceforge.net) + + This library is free software; you can redistribute it + and/or modify it under the terms of the GNU Library General + Public License as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any + later version. + + This library 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 Library General Public License for + more details. + + You should have received a copy of the GNU Library General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA. diff --git a/plugins/zynaddsubfx/fltk/README.mac b/plugins/zynaddsubfx/fltk/README.mac new file mode 100644 index 000000000..ab042c427 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/README.mac @@ -0,0 +1,87 @@ +README.mac - 2007-02-06 - Building FLTK under MacOS X +----------------------------------------------------- + +CONTENTS + + - Introduction + - How to Build Using GCC (MacOS X) + - Scripts + - Known MacFLTK bugs + - Test suite status + - Other stuff + - FLTK 1.0.x for Mac + + +INTRODUCTION + + FLTK currently supports the following development + environments on the MacOS X platform: + + - GCC + - Metrowerks CodeWarrior + - (Apple Project Builder - future releases) + - (MPW - future releases) + + +HOW TO BUILD USING GCC (MacOS X) + + Since the MacOS X command line build environment is based on + BSD UNIX, the normal UNIX build procedure as described in + 'README' applies. + + +KNOWN MacFLTK BUGS + + The following FLTK things are not implemented or don't work + at present: + + - Line styles are not fully implemented. + - Sub-sub-subwindow not tested. + - The 'shiny' demo needs work (flush/aglFlush). + + +TEST SUITE STATUS + + OS X: + + CubeView(++), adjuster(++), arc(++), ask(++), bitmap(++), + boxtype(++), browser(++), button(++), buttons(++), + checkers(++), clock(++), colbrowser(++), color_chooser(++), + cube(++), cursor(++), curve(++), demo(++), doublebuffer(++), + editor(++), fast_slow(++), file_chooser(++), fonts(++), + forms(++), fractals(++), fullscreen(++), gl_overlay(++), + glpuzzle(++), hello(++), help(++), iconize(++), image(+), + inactive(++), input(++), keyboard(++), label(++), + line_style(+), mandelbrot(++), menubar(++), message(++), + minimum(++), navigation(++), output(++), overlay(++), + pack(++), pixmap(++), pixmap_browser(++), radio(++), + resizebox(++), scroll(++), shape(++), shiny(-), + subwindow(++), symbols(++), tabs(++), tile(++), + tiled_image(++), valuators(++), fluid(++) + + (o)=minor bugs, (+)=usable, (++)=running perfectly, + (-)=major bugs, (--)=crashes + + +OTHER STUFF + + The creator ID's 'FLTK', 'Fltk', 'FLID', and 'Flid' are + officially registered with Apple Computers, Inc. and can be + used for FLTK applications ('FLTK') and FLUID files + ('Flid'). + + Under MacOS X, all windows are double-buffered. Using + Fl_Window has the same effect as using Fl_Double_Window on + other operating systems. Fl_Overlay_Window however uses one + additional buffer for the overlay plane. + + +FLTK 1.0.X FOR MAC + + FLTK 1.0.6 for MacOS 8.x and OS 9.x is in beta stage and can + be downloaded from http://www.matthiasm.com/flMac.html . + The archive contains build files for Metrowerks CodeWarrior + 5 and 6. + + FLTK 1.0.6 for Mac is not supported by the FLTK team and + will not be further developed by the author. diff --git a/plugins/zynaddsubfx/fltk/README.win32 b/plugins/zynaddsubfx/fltk/README.win32 new file mode 100644 index 000000000..f4039f769 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/README.win32 @@ -0,0 +1,206 @@ +README.win32 - Building FLTK under Windows +------------------------------------------ +Last Update: May 2007 for release 1.1.8 + +INTRODUCTION + + This document is split into two main sections. The first + describes several possible build environments, while the + second describes some of the issues associated with using + the GNU-like build configurations in the "makefiles" + subdirectory. + + FLTK currently supports the following development + environments on the Windows platform: + + - Microsoft Visual C++ 6.0, VC2005 and VC.NET using the + supplied workspace and project files. Be sure to get + your service packs! + + - Borland C++ Builder 5 and 6 using the supplied IDE + files. These files are not as actively maintained as + the VC and GNU versions, so may not work for you. + + - Watcom. There is a partial solution for the Watcom + toolchain. It is no longer actively maintained. + + - GNU toolsets (Cygwin or MinGW) hosted on Windows + 9x/2000/NT/XP. + + This remainder of this document gives a brief overview of + compiling and using FLTK with the Cygwin and MinGW compiler + toolkits. Both toolkits provide a build environment based + around the GNU C/C++ compiler. Further information is + available from the FLTK website at http://www.fltk.org, such + as this Howto note: http://www.fltk.org/articles.php?L598 + + The Cygwin build environment supplies a library (the Cygwin + DLL) that is primarily intended to provide a number of + Unix-like POSIX facilities for programs being ported to the + Windows environment (Win32 or WinNT). Cygwin also supplies + a very Unix-like build environment for Windows, including + the "BASH" Bourne-compatible shell and all of the standard + Unix file utilities (ls, cat, grep, etc.). + + Cygwin is developed by Cygnus (now part of RedHat, Inc). + Although provided for free download under the GPL, + distributing programs that require the Cygwin DLL under a + license other than the GPL requires a commercial license for + the Cygwin DLL. Native Windows programs that do not require + the Cygwin DLL (compiled and linked with the "-mno-cygwin" + option) may be released under any license freely. + + The MinGW distribution (Minimalist GNU for Windows) provides + a similar toolset but geared solely towards native Windows + development without the Unix-like POSIX library. The lack of + any libraries under the GPL or any other restrictive license + means that programs built with the MinGW environment may + always be released under any license freely. MinGW also + supplies a Unix-like build environment for Windows, + including MSYS (a Bourne-compatible shell) and the standard + Unix file utilities (ls, cat, grep, etc.) + + If you are not familiar with these GNU-like toolkits please + refer to the links section later in this note. In particular, + check out their license conditions carefully before use. + + +THE TOOLS + + There are currently three main configurations supported by + FLTK with the GNU tools: + + 1. Cygwin: Built using the Cygwin toolset and using the + Unix-like POSIX compatibility layer provided by the + Cygwin DLL. + + 2. Cygwin using the "-mno-cygwin" option: Built using + the Cygwin toolset but not using the Cygwin DLL. + + 3. MinGW: Built using the MinGW utilities, compiler and + tools. This is, in many aspects, analogous to the + Cygwin "-mno-cygwin" option. + + +RECOMMENDED BUILD ENVIRONMENTS + + Our recommendation is to: + + 1. Get the current Cygwin toolset. + + This can either produce executables that do or do not + rely on the Cygwin DLL (check licensing) at your + choice. + + 2. Get the latest MinGW toolset. It is recommended that + you also get the MSYS shell and the msysDTK developer + toolset. + + This will only produce normal Windows native + executables without any Unix or POSIX compatibility + layer. + + + See the links section below for more information. + + Either option can generate windows-native executables and + option 1 can provide a Unix-like POSIX portability layer that + is reliant on a GPLed library. + + See the later sections for detailed information about using + one of these configurations. + +LINKS + + The following links may be of use: + + 1. Main Cygwin homepage: + + http://www.cygwin.com/ + + 2. Main Mingw homepage: + + http://www.mingw.org/ + + In particular look for the MinGW FAQ at this link for + a lot of useful Mingw-native development + documentation. + + + 3. Check out the FLTK newsgroups at the FLTK homepage: + + http://www.fltk.org/ + + Its archival search facilities are EXTREMELY useful + to check back through previous problems with this + sort of configuration before posting new questions. + + 4. Carl Thompson (member of the core team responsible + for FLTK): + + http://www.carlthompson.net/ + + A pre-bundled development toolset tailored for use + with an earlier version of FLTK may be found at: + + http://www.carlthompson.net/cygwin/ + + However, this has not been actively maintained since + the Cygwin and MinGW offerings are now more complete + these days. + + 5. GNU Compiler Collection (GCC) compiler homepage: + + http://gcc.gnu.org/ + + 6. OpenGL page - for OpenGL and GLUT libs + + http://www.opengl.org/ + + +BUILDING FLTK WITH CYGWIN OR MINGW + + Please read chapter 1 of the FLTK Programmers Manual for + compilation instructions. + + +WHY DOES A CONSOLE WINDOW APPEAR WHEN I RUN MY PROGRAM + + Windows has a flag that determines whether an application + runs in the foreground with a console or in the background + without a console. Use the "-mwindows" option to make your + application run in the background and "-mconsole" to run in + the foreground. + + Keep in mind that a windows application cannot send output + to stdout, even if you run it from an existing console + application. + (Note: A special case of this exists if running a MinGW + application from the command line of an MSYS shell, when an + application is able to write to stdout, even if compiled with + "-mwindows".) + + +HOW DO I GET OPENGL TO WORK? + + Both builds should automatically support OpenGL. + + The configuration file config.h has a number of settings + which control compile-time compilation. One such setting is + "HAVE_GL". This may be set to 0 to disable Open GL operation. + Changing the line in config.h to + + #define HAVE_GL 1 + + will change this to compile and link in OpenGL. + + + + + + + + + + + diff --git a/plugins/zynaddsubfx/fltk/configh.cmake.in b/plugins/zynaddsubfx/fltk/configh.cmake.in new file mode 100644 index 000000000..e3ffc70fb --- /dev/null +++ b/plugins/zynaddsubfx/fltk/configh.cmake.in @@ -0,0 +1,269 @@ +/* + * "$Id: configh.cmake.in 6106 2008-04-21 21:10:47Z matt $" + * + * Configuration file for the Fast Light Tool Kit (FLTK). + * @configure_input@ + * + * Copyright 1998-2008 by Bill Spitzak and others. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems to "fltk-bugs@fltk.org". + */ + +/* + * Where to find files... + */ + +#define FLTK_DATADIR "@FLTK_DATADIR@" +#define FLTK_DOCDIR "@FLTK_DOCDIR@" + +/* + * BORDER_WIDTH: + * + * Thickness of FL_UP_BOX and FL_DOWN_BOX. Current 1,2, and 3 are + * supported. + * + * 3 is the historic FLTK look. + * 2 is the default and looks like Microsoft Windows, KDE, and Qt. + * 1 is a plausible future evolution... + * + * Note that this may be simulated at runtime by redefining the boxtypes + * using Fl::set_boxtype(). + */ + +#define BORDER_WIDTH 2 + +/* + * HAVE_GL: + * + * Do you have OpenGL? Set this to 0 if you don't have or plan to use + * OpenGL, and FLTK will be smaller. + */ + +#define HAVE_GL @HAVE_GL@ + +/* + * HAVE_GL_GLU_H: + * + * Do you have the OpenGL Utility Library header file? + * (many broken Mesa RPMs do not...) + */ + +#cmakedefine HAVE_GL_GLU_H @HAVE_GL_GLU_H@ + +/* + * USE_COLORMAP: + * + * Setting this to zero will save a good deal of code (especially for + * fl_draw_image), but FLTK will only work on TrueColor visuals. + */ + +#define USE_COLORMAP 1 + +/* + * USE_XFT + * + * Use the new Xft library to draw anti-aliased text. + */ + +#cmakedefine FOUND_XFT +#ifdef FOUND_XFT +#define USE_XFT 1 +#else +#define USE_XFT 0 +#endif +/* + * HAVE_XDBE: + * + * Do we have the X double-buffer extension? + */ + +#define HAVE_XDBE 0 + +/* + * USE_XDBE: + * + * Actually try to use the double-buffer extension? + */ + +#define USE_XDBE HAVE_XDBE + +/* + * USE_QUARTZ: + * + * Use Quartz instead of Quickdraw on Apple Mac OS X machines. + * FLTK was originally ported to Quickdraw which is no longer + * supported by Apple. If USE_QUARTZ is defined, FLTK will be + * compiled using Quartz instead. This flag has no meaning on + * other operating systems. + */ + +#cmakedefine FLTK_APPLE +#ifdef FLTK_APPLE + #cmakedefine FLTK_QUARTZ + #ifdef FLTK_QUARTZ + #define USE_QUARTZ 1 + #define __APPLE_QUARTZ__ + #undef __APPLE_QD__ + #else + #define USE_QUARTZ 0 + #undef __APPLE_QUARTZ__ + #define __APPLE_QD__ + #endif +#endif + +/* + * HAVE_OVERLAY: + * + * Use the X overlay extension? FLTK will try to use an overlay + * visual for Fl_Overlay_Window, the Gl_Window overlay, and for the + * menus. Setting this to zero will remove a substantial amount of + * code from FLTK. Overlays have only been tested on SGI servers! + */ + +#define HAVE_OVERLAY 0 + +/* + * HAVE_GL_OVERLAY: + * + * It is possible your GL has an overlay even if X does not. If so, + * set this to 1. + */ + +#define HAVE_GL_OVERLAY HAVE_OVERLAY + +/* + * WORDS_BIGENDIAN: + * + * Byte order of your machine: 1 = big-endian, 0 = little-endian. + */ + +#define WORDS_BIGENDIAN 0 + +/* + * U16, U32, U64: + * + * Types used by fl_draw_image. One of U32 or U64 must be defined. + * U16 is optional but FLTK will work better with it! + */ + +#cmakedefine U16 @U16@ +#cmakedefine U32 @U32@ +#cmakedefine U64 @U64@ + +/* + * HAVE_DIRENT_H, HAVE_SYS_NDIR_H, HAVE_SYS_DIR_H, HAVE_NDIR_H, HAVE_SCANDIR: + * + * Where is (used only by fl_file_chooser and scandir). + */ + +#cmakedefine HAVE_DIRENT_H @HAVE_DIRENT_H@ +#cmakedefine HAVE_SYS_NDIR_H @HAVE_SYS_NDIR_H@ +#cmakedefine HAVE_SYS_DIR_H @HAVE_SYS_DIR_H@ +#cmakedefine HAVE_NDIR_H @HAVE_NDIR_H@ +#cmakedefine HAVE_SCANDIR @HAVE_SCANDIR@ + +/* + * Possibly missing sprintf-style functions: + */ + +#cmakedefine HAVE_VSNPRINTF @HAVE_VSNPRINTF@ +#cmakedefine HAVE_SNPRINTF @HAVE_SNPRINTF@ + +/* + * String functions and headers... + */ + +#cmakedefine HAVE_STRINGS_H @HAVE_STRINGS_H@ +#cmakedefine HAVE_STRCASECMP @HAVE_STRCASECMP@ +#cmakedefine HAVE_STRLCAT @HAVE_STRLCAT@ +#cmakedefine HAVE_STRLCPY @HAVE_STRLCPY@ + +/* + * 'locale' functions + */ + +#cmakedefine HAVE_LOCALE_H @HAVE_LOCALE_H@ +#cmakedefine HAVE_LOCALECONV @HAVE_LOCALECONV@ + +/* + * HAVE_SYS_SELECT_H: + * + * Whether or not select() call has its own header file. + */ + +#cmakedefine HAVE_SYS_SELECT_H @HAVE_SYS_SELECT_H@ + +/* + * HAVE_SYS_STDTYPES_H: + * + * Whether or not we have the header file. + */ + +#cmakedefine HAVE_SYS_STDTYPES_H @HAVE_SYS_STDTYPES_H@ + +/* + * USE_POLL: + * + * Use the poll() call provided on Linux and Irix instead of select() + */ + +#define USE_POLL 0 + +/* + * Do we have various image libraries? + */ + +#cmakedefine HAVE_LIBPNG @HAVE_LIBPNG@ +#cmakedefine HAVE_LIBZ @HAVE_LIBZ@ +#cmakedefine HAVE_LIBJPEG @HAVE_LIBJPEG@ + +/* + * Which header file do we include for libpng? + */ + +#cmakedefine HAVE_PNG_H @HAVE_PNG_H@ +#cmakedefine HAVE_LIBPNG_PNG_H @HAVE_LIBPNG_PNG_H@ + +/* + * Do we have the png_xyz() functions? + */ + +#cmakedefine HAVE_PNG_GET_VALID @HAVE_PNG_GET_VALID@ +#cmakedefine HAVE_PNG_SET_TRNS_TO_ALPHA @HAVE_PNG_SET_TRNS_TO_ALPHA@ + +/* + * Do we have POSIX threading? + */ + +#cmakedefine CMAKE_USE_PTHREADS +#ifdef CMAKE_USE_PTHREADS +#define HAVE_PTHREAD 1 +#else +#define HAVE_PTHREAD 0 +#endif + +#cmakedefine CMAKE_HAVE_PTHREAD_H +#ifdef CMAKE_HAVE_PTHREAD_H +#define HAVE_PTHREAD_H 1 +#else +#define HAVE_PTHREAD_H 0 +#endif + +/* + * End of "$Id: configh.cmake.in 6106 2008-04-21 21:10:47Z matt $". + */ diff --git a/plugins/zynaddsubfx/fltk/fltk-config.in b/plugins/zynaddsubfx/fltk/fltk-config.in new file mode 100644 index 000000000..0794f6826 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/fltk-config.in @@ -0,0 +1,344 @@ +#!/bin/sh +# +# "$Id: fltk-config.in 6032 2008-02-20 18:10:13Z matt $" +# +# FLTK configuration utility. +# +# Copyright 2000-2007 by Bill Spitzak and others. +# Original version Copyright 2000 by James Dean Palmer +# Adapted by Vincent Penne and Michael Sweet +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library 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 +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA. +# +# Please report all bugs and problems on the following page: +# +# http://www.fltk.org/str.php +# + +MAJOR_VERSION=@FL_MAJOR_VERSION@ +MINOR_VERSION=@FL_MINOR_VERSION@ +PATCH_VERSION=@FL_PATCH_VERSION@ +VERSION="$MAJOR_VERSION.$MINOR_VERSION.$PATCH_VERSION" +APIVERSION="$MAJOR_VERSION.$MINOR_VERSION" + +### BEGIN fltk-config +selfdir=`dirname $0` + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +exec_prefix_set=no +bindir=@bindir@ +includedir=@includedir@ +libdir=@libdir@ +srcdir=@srcdir@ + +# compiler names +CC="@CC@" +CXX="@CXX@" + +# post-process command (only needed for MacOS) +POSTBUILD="@POSTBUILD@" + +# flags for C++ compiler: +ARCHFLAGS="@ARCHFLAGS@" +CFLAGS="@CFLAGS@ @LARGEFILE@ @PTHREAD_FLAGS@" +CXXFLAGS="@CXXFLAGS@ @LARGEFILE@ @PTHREAD_FLAGS@" +LDFLAGS="@LDFLAGS@" +LDLIBS="@LIBS@" +OPTIM="@OPTIM@" + +# Check for local invocation, and update paths accordingly... +if test -f "$selfdir/FL/Fl_Window.H"; then + bindir="$selfdir/fluid" + includedir="$selfdir" + libdir="$selfdir/lib" + + if test -f "$libdir/libfltk_jpeg.a"; then + CFLAGS="-I$includedir/jpeg $CFLAGS" + CXXFLAGS="-I$includedir/jpeg $CXXFLAGS" + fi + + if test -f "$libdir/libfltk_z.a"; then + CFLAGS="-I$includedir/zlib $CFLAGS" + CXXFLAGS="-I$includedir/zlib $CXXFLAGS" + fi + + if test -f "$libdir/libfltk_png.a"; then + CFLAGS="-I$includedir/png $CFLAGS" + CXXFLAGS="-I$includedir/png $CXXFLAGS" + fi +fi + +if test -d $includedir/FL/images; then + CFLAGS="-I$includedir/FL/images $CFLAGS" + CXXFLAGS="-I$includedir/FL/images $CXXFLAGS" +fi + +# libraries to link with: +LIBNAME="@LIBNAME@" +DSONAME="@DSONAME@" +DSOLINK="@DSOLINK@" +IMAGELIBS="@IMAGELIBS@" +SHAREDSUFFIX="@SHAREDSUFFIX@" + +usage () +{ + echo "Usage: fltk-config [OPTIONS] +Options: + [--version] + [--api-version] + +Options telling what we are doing: + [--use-gl] use GL + [--use-images] use extra image formats (PNG, JPEG) + [--use-glut] use glut compatibility layer + [--use-forms] use forms compatibility layer + +Options telling what information we request: + [--cc] return C compiler used to compile FLTK + [--cxx] return C++ compiler used to compile FLTK + [--optim] return compiler optimization used to compile FLTK + [--cflags] return flags to compile C using FLTK + [--cxxflags] return flags to compile C++ using FLTK + [--ldflags] return flags to link against FLTK + [--ldstaticflags] return flags to link against static FLTK library + even if there are DSOs installed + [--libs] return FLTK libraries full path for dependencies + +Option to compile and link an application: + [-g] compile the program with debugging information + [-Dname[=value]] compile the program with the given define + [--compile program.cxx] + [--post program] +" + exit $1 +} + +if test $# -eq 0; then + usage 1 +fi + +no_plugins=no +compile= +post= +debug= + +# Parse command line options +while test $# -gt 0 +do + case "$1" in + -*=*) + optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` + ;; + *) + optarg= + ;; + esac + + case $1 in + --version) + echo $VERSION + ;; + --api-version) + echo $APIVERSION + ;; + --cc) + echo $CC + ;; + --cxx) + echo $CXX + ;; + --optim) + echo_optim=yes + ;; + --use-gl | --use-glut) + use_gl=yes + ;; + --use-forms) + use_forms=yes + ;; + --use-images) + use_images=yes + ;; + --cflags) + echo_cflags=yes + ;; + --cxxflags) + echo_cxxflags=yes + ;; + --ldflags) + echo_ldflags=yes + ;; + --ldstaticflags) + echo_ldstaticflags=yes + ;; + --libs) + echo_libs=yes + ;; + -g) + debug=-g + ;; + -D*) + CXXFLAGS="$CXXFLAGS $1" + ;; + --compile) + compile=$2 + post=$2 + shift + ;; + --post) + post=$2 + shift + ;; + *) + echo_help=yes + ;; + esac + shift +done + +if test "$includedir" != /usr/include; then + includes=-I$includedir +else + includes= +fi + +if test "$libdir" != /usr/lib -a "$libdir" != /usr/lib32; then + libs=-L$libdir +else + libs= +fi + +# Calculate needed libraries +LDSTATIC="$libdir/libfltk.a $LDLIBS" +LDLIBS="-lfltk$SHAREDSUFFIX" + +if test x$use_forms = xyes; then + LDLIBS="-lfltk_forms$SHAREDSUFFIX $LDLIBS" + LDSTATIC="$libdir/libfltk_forms.a $LDSTATIC" +fi +if test x$use_gl = xyes; then + LDLIBS="-lfltk_gl$SHAREDSUFFIX $LDLIBS" + LDSTATIC="$libdir/libfltk_gl.a @GLLIB@ $LDSTATIC" +fi +if test x$use_images = xyes; then + LDLIBS="-lfltk_images$SHAREDSUFFIX $LDLIBS" + LDSTATIC="$libdir/libfltk_images.a $IMAGELIBS $LDSTATIC" +fi + +LDLIBS="$DSOLINK $LDFLAGS $libs $LDLIBS" +LDSTATIC="$LDFLAGS $LDSTATIC" + +# Answer to user requests +if test -n "$echo_help"; then + usage 1 +fi + +if test -n "$compile"; then + case $compile in + *.cxx) + prog=`basename $compile .cxx` + ;; + *.cpp) + prog=`basename $compile .cpp` + ;; + *.cc) + prog=`basename $compile .cc` + ;; + *.C) + prog=`basename $compile .C` + ;; + *) + echo "ERROR: Unknown/bad C++ source file extension on \"$compile\"!" + exit 1 + ;; + esac + + post=$prog + + echo $CXX $ARCHFLAGS $includes $CXXFLAGS $debug -o $prog $compile $LDLIBS + $CXX $ARCHFLAGS $includes $CXXFLAGS $debug -o $prog $compile $LDLIBS + + # stop after compilation in case of errors + err=$? + if test $err != 0; then + exit $err + fi +fi + +if test -n "$post" -a "$POSTBUILD" != ":"; then + echo $POSTBUILD $post $includedir/FL/mac.r + $POSTBUILD $post $includedir/FL/mac.r +fi + +if test "$echo_cflags" = "yes"; then + echo $includes $CFLAGS +fi + +if test "$echo_cxxflags" = "yes"; then + echo $includes $CXXFLAGS +fi + +if test "$echo_optim" = "yes"; then + echo $OPTIM +fi + +if test "$echo_ldflags" = "yes"; then + my_libs= + libdirs=$libs + + for i in $LDLIBS ; do + if test $i != -L$libdir ; then + if test -z "$my_libs" ; then + my_libs="$i" + else + my_libs="$my_libs $i" + fi + fi + done + echo $libdirs $my_libs +fi + +if test "$echo_ldstaticflags" = "yes"; then + echo $LDSTATIC +fi + +if test "$echo_libs" = "yes"; then + echo -n $libdir/libfltk.a + + if test x$use_forms = xyes; then + echo -n " $libdir/libfltk_forms.a" + fi + + if test x$use_gl = xyes; then + echo -n " $libdir/libfltk_gl.a" + fi + + if test x$use_images = xyes; then + echo -n " $libdir/libfltk_images.a" + + for lib in fltk_jpeg fltk_png fltk_z; do + if test -f $libdir/lib$lib.a; then + echo -n " $libdir/lib$lib.a" + fi + done + fi + echo +fi + +# +# End of "$Id: fltk-config.in 6032 2008-02-20 18:10:13Z matt $". +# diff --git a/plugins/zynaddsubfx/fltk/fltk.list.in b/plugins/zynaddsubfx/fltk/fltk.list.in new file mode 100644 index 000000000..681d8c9e6 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/fltk.list.in @@ -0,0 +1,412 @@ +# +# "$Id: fltk.list.in 6059 2008-02-28 16:50:07Z mike $" +# +# EPM product list file for the Fast Light Tool Kit (FLTK). +# +# (EPM can be found at http://www.epmhome.org/) +# +# Copyright 1998-2008 by Bill Spitzak and others. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library 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 +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA. +# +# Please report all bugs and problems on the following page: +# +# http://www.fltk.org/str.php +# + +%product Fast Light Tool Kit (FLTK) +%copyright 1998-2008 by Bill Spitzak and others. +%vendor FLTK Development Team +%license COPYING +%readme README +%version @FL_MAJOR_VERSION@.@FL_MINOR_VERSION@.@FL_PATCH_VERSION@ +%description The Fast Light Tool Kit ("FLTK", pronounced "fulltick") is a +%description cross-platform C++ GUI toolkit for UNIX(r)/Linux(r) (X11), +%description Microsoft(r) Windows(r), and MacOS(r) X. FLTK provides modern +%description GUI functionality without the bloat and supports 3D graphics via +%description OpenGL(r) and its built-in GLUT emulation. + +$prefix=@prefix@ +$exec_prefix=@exec_prefix@ +$bindir=@bindir@ +$datarootdir=@datarootdir@ +$datadir=@datadir@ +$includedir=@includedir@ +$libdir=@libdir@ +$mandir=@mandir@ +$docdir=${datadir}/doc/fltk + +$CAT1EXT=@CAT1EXT@ +$CAT3EXT=@CAT3EXT@ +$CAT6EXT=@CAT6EXT@ + +$DSONAME=@DSONAME@ +$FLDSONAME=@FLDSONAME@ +$FLLIBNAME=@FLLIBNAME@ +$GLDSONAME=@GLDSONAME@ +$GLLIBNAME=@GLLIBNAME@ +$FLUID=@FLUID@ +$JPEG=@JPEG@ +$PNG=@PNG@ +$ZLIB=@ZLIB@ + +%if DSONAME +%system aix +f 0555 root sys $libdir/libfltk_s.a src/libfltk_s.a nostrip() +%system hpux +f 0555 root sys $libdir/libfltk.sl.@FL_API_VERSION@ src/libfltk.sl.@FL_API_VERSION@ nostrip() +%system darwin +f 0555 root sys $libdir/libfltk.@FL_API_VERSION@.dylib src/libfltk.@FL_API_VERSION@.dylib nostrip() +%system !aix !darwin !hpux +f 0555 root sys $libdir/libfltk.so.@FL_API_VERSION@ src/libfltk.so.@FL_API_VERSION@ nostrip() +%system all + +%system aix +f 0555 root sys $libdir/libfltk_forms_s.a src/libfltk_forms_s.a nostrip() +%system hpux +f 0555 root sys $libdir/libfltk_forms.sl.@FL_API_VERSION@ src/libfltk_forms.sl.@FL_API_VERSION@ nostrip() +%system darwin +f 0555 root sys $libdir/libfltk_forms.@FL_API_VERSION@.dylib src/libfltk_forms.@FL_API_VERSION@.dylib nostrip() +%system !aix !darwin !hpux +f 0555 root sys $libdir/libfltk_forms.so.@FL_API_VERSION@ src/libfltk_forms.so.@FL_API_VERSION@ nostrip() +%system all + +%system aix +f 0555 root sys $libdir/libfltk_images_s.a src/libfltk_images_s.a nostrip() +%system hpux +f 0555 root sys $libdir/libfltk_images.sl.@FL_API_VERSION@ src/libfltk_images.sl.@FL_API_VERSION@ nostrip() +%system darwin +f 0555 root sys $libdir/libfltk_images.@FL_API_VERSION@.dylib src/libfltk_images.@FL_API_VERSION@.dylib nostrip() +%system !aix !darwin !hpux +f 0555 root sys $libdir/libfltk_images.so.@FL_API_VERSION@ src/libfltk_images.so.@FL_API_VERSION@ nostrip() +%system all +%endif + +%if GLDSONAME +%system aix +f 0555 root sys $libdir/libfltk_gl_s.a src/libfltk_gl_s.a nostrip() +%system hpux +f 0555 root sys $libdir/libfltk_gl.sl.@FL_API_VERSION@ src/libfltk_gl.sl.@FL_API_VERSION@ nostrip() +%system darwin +f 0555 root sys $libdir/libfltk_gl.@FL_API_VERSION@.dylib src/libfltk_gl.@FL_API_VERSION@.dylib nostrip() +%system !aix !darwin !hpux +f 0555 root sys $libdir/libfltk_gl.so.@FL_API_VERSION@ src/libfltk_gl.so.@FL_API_VERSION@ nostrip() +%system all +%endif + + +%subpackage devel +%description FLTK Development Environment +%description Install fltk-devel if you need to develop FLTK applications. +%description You'll need to install the fltk package if you plan to run +%description dynamically linked applications. + +%system darwin +l 0444 root sys /usr/include/gcc/darwin/3.1/g++-v3/FL $includedir/FL + +d 0555 root sys /Applications/fluid.app - +d 0555 root sys /Applications/fluid.app/Contents - +f 0444 root sys /Applications/fluid.app/Contents/Info.plist fluid/fluid.app/Contents/Info.plist +f 0444 root sys /Applications/fluid.app/Contents/PkgInfo fluid/fluid.app/Contents/PkgInfo +d 0555 root sys /Applications/fluid.app/Contents/MacOS - +l 0555 root sys /Applications/fluid.app/Contents/MacOS/fluid $bindir/fluid +d 0555 root sys /Applications/fluid.app/Contents/Resources - +f 0444 root sys /Applications/fluid.app/Contents/Resources/fluid.icns fluid/fluid.app/Contents/Resources/fluid.icns +%postinstall $bindir/fltk-config --post $bindir/fluid +%postremove /bin/rm -rf /Applications/fluid.app + +%system !darwin +f 0444 root sys /usr/share/applications/fluid.desktop fluid/fluid.desktop +f 0444 root sys /usr/share/icons/hicolor/16x16/apps/fluid.png fluid/icons/fluid-16.png +f 0444 root sys /usr/share/icons/hicolor/32x32/apps/fluid.png fluid/icons/fluid-32.png +f 0444 root sys /usr/share/icons/hicolor/48x48/apps/fluid.png fluid/icons/fluid-48.png +f 0444 root sys /usr/share/icons/hicolor/64x64/apps/fluid.png fluid/icons/fluid-64.png +f 0444 root sys /usr/share/icons/hicolor/128x128/apps/fluid.png fluid/icons/fluid-128.png +f 0444 root sys /usr/share/mimelnk/application/x-fluid.desktop fluid/x-fluid.desktop + +%system all + +# FLUID +f 0555 root sys $bindir/fluid fluid/$FLUID +f 0555 root sys $bindir/fltk-config fltk-config + +# Man pages +f 0444 root sys $mandir/cat1/fluid.$CAT1EXT documentation/fluid.$CAT1EXT +f 0444 root sys $mandir/cat1/fltk-config.$CAT1EXT documentation/fltk-config.$CAT1EXT +f 0444 root sys $mandir/cat3/fltk.$CAT3EXT documentation/fltk.$CAT3EXT +f 0444 root sys $mandir/man1/fluid.1 documentation/fluid.man +f 0444 root sys $mandir/man1/fltk-config.1 documentation/fltk-config.man +f 0444 root sys $mandir/man3/fltk.3 documentation/fltk.man + +# Library files +f 0444 root sys $libdir/libfltk.a lib/libfltk.a +f 0444 root sys $libdir/libfltk_forms.a lib/libfltk_forms.a +f 0444 root sys $libdir/libfltk_images.a lib/libfltk_images.a +%if GLLIBNAME +f 0444 root sys $libdir/libfltk_gl.a lib/libfltk_gl.a +%endif + +%if JPEG +f 0444 root sys $libdir/libfltk_jpeg.a lib/libfltk_jpeg.a +%endif + +%if PNG +f 0444 root sys $libdir/libfltk_png.a lib/libfltk_png.a +%endif + +%if ZLIB +f 0444 root sys $libdir/libfltk_z.a lib/libfltk_z.a +%endif + +%if DSONAME +%system hpux +l 0000 root sys $libdir/libfltk.sl libfltk.sl.@FL_API_VERSION@ +%system darwin +l 0000 root sys $libdir/libfltk.dylib libfltk.@FL_API_VERSION@.dylib +%system !aix !darwin !hpux +l 0000 root sys $libdir/libfltk.so libfltk.so.@FL_API_VERSION@ +%system all + +%system hpux +l 0000 root sys $libdir/libfltk_forms.sl libfltk_forms.sl.@FL_API_VERSION@ +%system darwin +l 0000 root sys $libdir/libfltk_forms.dylib libfltk_forms.@FL_API_VERSION@.dylib +%system !aix !darwin !hpux +l 0000 root sys $libdir/libfltk_forms.so libfltk_forms.so.@FL_API_VERSION@ +%system all + +%system hpux +l 0000 root sys $libdir/libfltk_images.sl libfltk_images.sl.@FL_API_VERSION@ +%system darwin +l 0000 root sys $libdir/libfltk_images.dylib libfltk_images.@FL_API_VERSION@.dylib +%system !aix !darwin !hpux +l 0000 root sys $libdir/libfltk_images.so libfltk_images.so.@FL_API_VERSION@ +%system all +%endif + +%if GLDSONAME +%system hpux +l 0000 root sys $libdir/libfltk_gl.sl libfltk_gl.sl.@FL_API_VERSION@ +%system darwin +l 0000 root sys $libdir/libfltk_gl.dylib libfltk_gl.@FL_API_VERSION@.dylib +%system !aix !darwin !hpux +l 0000 root sys $libdir/libfltk_gl.so libfltk_gl.so.@FL_API_VERSION@ +%system all +%endif + +# Header files +f 0444 root sys $includedir/FL/ FL/*.[hH] + +%if JPEG +f 0444 root sys $includedir/FL/images/jconfig.h jpeg/jconfig.h +f 0444 root sys $includedir/FL/images/jerror.h jpeg/jerror.h +f 0444 root sys $includedir/FL/images/jmorecfg.h jpeg/jmorecfg.h +f 0444 root sys $includedir/FL/images/jpeglib.h jpeg/jpeglib.h +%endif + +%if PNG +f 0444 root sys $includedir/FL/images/png.h png/png.h +f 0444 root sys $includedir/FL/images/pngconf.h png/pngconf.h +%endif + +%if ZLIB +f 0444 root sys $includedir/FL/images/zconf.h zlib/zconf.h +f 0444 root sys $includedir/FL/images/zlib.h zlib/zlib.h +f 0444 root sys $includedir/FL/images/zutil.h zlib/zutil.h +%endif + +%system !darwin +# Symlinks to handle common case problems... +l 0000 root sys $includedir/Fl FL +l 0000 root sys $includedir/FL/Enumerations.h Enumerations.H +l 0000 root sys $includedir/FL/Fl.h Fl.H +l 0000 root sys $includedir/FL/Fl_Adjuster.h Fl_Adjuster.H +l 0000 root sys $includedir/FL/Fl_Bitmap.h Fl_Bitmap.H +l 0000 root sys $includedir/FL/Fl_Box.h Fl_Box.H +l 0000 root sys $includedir/FL/Fl_Browser.h Fl_Browser.H +l 0000 root sys $includedir/FL/Fl_Browser_.h Fl_Browser_.H +l 0000 root sys $includedir/FL/Fl_Button.h Fl_Button.H +l 0000 root sys $includedir/FL/Fl_Chart.h Fl_Chart.H +l 0000 root sys $includedir/FL/Fl_Check_Browser.h Fl_Check_Browser.H +l 0000 root sys $includedir/FL/Fl_Check_Button.h Fl_Check_Button.H +l 0000 root sys $includedir/FL/Fl_Choice.h Fl_Choice.H +l 0000 root sys $includedir/FL/Fl_Clock.h Fl_Clock.H +l 0000 root sys $includedir/FL/Fl_Color_Chooser.h Fl_Color_Chooser.H +l 0000 root sys $includedir/FL/Fl_Counter.h Fl_Counter.H +l 0000 root sys $includedir/FL/Fl_Dial.h Fl_Dial.H +l 0000 root sys $includedir/FL/Fl_Double_Window.h Fl_Double_Window.H +l 0000 root sys $includedir/FL/Fl_File_Browser.h Fl_File_Browser.H +l 0000 root sys $includedir/FL/Fl_File_Chooser.h Fl_File_Chooser.H +l 0000 root sys $includedir/FL/Fl_File_Icon.h Fl_File_Icon.H +l 0000 root sys $includedir/FL/Fl_Fill_Dial.h Fl_Fill_Dial.H +l 0000 root sys $includedir/FL/Fl_Fill_Slider.h Fl_Fill_Slider.H +l 0000 root sys $includedir/FL/Fl_Float_Input.h Fl_Float_Input.H +l 0000 root sys $includedir/FL/Fl_FormsBitmap.h Fl_FormsBitmap.H +l 0000 root sys $includedir/FL/Fl_FormsPixmap.h Fl_FormsPixmap.H +l 0000 root sys $includedir/FL/Fl_Free.h Fl_Free.H +l 0000 root sys $includedir/FL/Fl_Group.h Fl_Group.H +l 0000 root sys $includedir/FL/Fl_Help_Dialog.h Fl_Help_Dialog.H +l 0000 root sys $includedir/FL/Fl_Help_View.h Fl_Help_View.H +l 0000 root sys $includedir/FL/Fl_Hold_Browser.h Fl_Hold_Browser.H +l 0000 root sys $includedir/FL/Fl_Hor_Fill_Slider.h Fl_Hor_Fill_Slider.H +l 0000 root sys $includedir/FL/Fl_Hor_Nice_Slider.h Fl_Hor_Nice_Slider.H +l 0000 root sys $includedir/FL/Fl_Hor_Slider.h Fl_Hor_Slider.H +l 0000 root sys $includedir/FL/Fl_Hor_Value_Slider.h Fl_Hor_Value_Slider.H +l 0000 root sys $includedir/FL/Fl_Image.h Fl_Image.H +l 0000 root sys $includedir/FL/Fl_Input.h Fl_Input.H +l 0000 root sys $includedir/FL/Fl_Input_.h Fl_Input_.H +l 0000 root sys $includedir/FL/Fl_Input_Choice.h Fl_Input_Choice.H +l 0000 root sys $includedir/FL/Fl_Int_Input.h Fl_Int_Input.H +l 0000 root sys $includedir/FL/Fl_Light_Button.h Fl_Light_Button.H +l 0000 root sys $includedir/FL/Fl_Line_Dial.h Fl_Line_Dial.H +l 0000 root sys $includedir/FL/Fl_Menu.h Fl_Menu.H +l 0000 root sys $includedir/FL/Fl_Menu_.h Fl_Menu_.H +l 0000 root sys $includedir/FL/Fl_Menu_Bar.h Fl_Menu_Bar.H +l 0000 root sys $includedir/FL/Fl_Menu_Button.h Fl_Menu_Button.H +l 0000 root sys $includedir/FL/Fl_Menu_Item.h Fl_Menu_Item.H +l 0000 root sys $includedir/FL/Fl_Menu_Window.h Fl_Menu_Window.H +l 0000 root sys $includedir/FL/Fl_Multi_Browser.h Fl_Multi_Browser.H +l 0000 root sys $includedir/FL/Fl_Multi_Label.h Fl_Multi_Label.H +l 0000 root sys $includedir/FL/Fl_Multiline_Input.h Fl_Multiline_Input.H +l 0000 root sys $includedir/FL/Fl_Multiline_Output.h Fl_Multiline_Output.H +l 0000 root sys $includedir/FL/Fl_Nice_Slider.h Fl_Nice_Slider.H +l 0000 root sys $includedir/FL/Fl_Object.h Fl_Object.H +l 0000 root sys $includedir/FL/Fl_Output.h Fl_Output.H +l 0000 root sys $includedir/FL/Fl_Overlay_Window.h Fl_Overlay_Window.H +l 0000 root sys $includedir/FL/Fl_Pack.h Fl_Pack.H +l 0000 root sys $includedir/FL/Fl_Pixmap.h Fl_Pixmap.H +l 0000 root sys $includedir/FL/Fl_Positioner.h Fl_Positioner.H +l 0000 root sys $includedir/FL/Fl_Progress.h Fl_Progress.H +l 0000 root sys $includedir/FL/Fl_Radio_Button.h Fl_Radio_Button.H +l 0000 root sys $includedir/FL/Fl_Radio_Light_Button.h Fl_Radio_Light_Button.H +l 0000 root sys $includedir/FL/Fl_Radio_Round_Button.h Fl_Radio_Round_Button.H +l 0000 root sys $includedir/FL/Fl_Repeat_Button.h Fl_Repeat_Button.H +l 0000 root sys $includedir/FL/Fl_Return_Button.h Fl_Return_Button.H +l 0000 root sys $includedir/FL/Fl_Roller.h Fl_Roller.H +l 0000 root sys $includedir/FL/Fl_Round_Button.h Fl_Round_Button.H +l 0000 root sys $includedir/FL/Fl_Round_Clock.h Fl_Round_Clock.H +l 0000 root sys $includedir/FL/Fl_Scroll.h Fl_Scroll.H +l 0000 root sys $includedir/FL/Fl_Scrollbar.h Fl_Scrollbar.H +l 0000 root sys $includedir/FL/Fl_Secret_Input.h Fl_Secret_Input.H +l 0000 root sys $includedir/FL/Fl_Select_Browser.h Fl_Select_Browser.H +l 0000 root sys $includedir/FL/Fl_Simple_Counter.h Fl_Simple_Counter.H +l 0000 root sys $includedir/FL/Fl_Single_Window.h Fl_Single_Window.H +l 0000 root sys $includedir/FL/Fl_Slider.h Fl_Slider.H +l 0000 root sys $includedir/FL/Fl_Spinner.h Fl_Spinner.H +l 0000 root sys $includedir/FL/Fl_Tabs.h Fl_Tabs.H +l 0000 root sys $includedir/FL/Fl_Tile.h Fl_Tile.H +l 0000 root sys $includedir/FL/Fl_Timer.h Fl_Timer.H +l 0000 root sys $includedir/FL/Fl_Toggle_Button.h Fl_Toggle_Button.H +l 0000 root sys $includedir/FL/Fl_Toggle_Light_Button.h Fl_Toggle_Light_Button.H +l 0000 root sys $includedir/FL/Fl_Toggle_Round_Button.h Fl_Toggle_Round_Button.H +l 0000 root sys $includedir/FL/Fl_Tooltip.h Fl_Tooltip.H +l 0000 root sys $includedir/FL/Fl_Valuator.h Fl_Valuator.H +l 0000 root sys $includedir/FL/Fl_Value_Input.h Fl_Value_Input.H +l 0000 root sys $includedir/FL/Fl_Value_Output.h Fl_Value_Output.H +l 0000 root sys $includedir/FL/Fl_Value_Slider.h Fl_Value_Slider.H +l 0000 root sys $includedir/FL/Fl_Widget.h Fl_Widget.H +l 0000 root sys $includedir/FL/Fl_Window.h Fl_Window.H +l 0000 root sys $includedir/FL/Fl_XBM_Image.h Fl_XBM_Image.H +l 0000 root sys $includedir/FL/Fl_XPM_Image.h Fl_XPM_Image.H +l 0000 root sys $includedir/FL/filename.h filename.H +l 0000 root sys $includedir/FL/fl_ask.h fl_ask.H +l 0000 root sys $includedir/FL/fl_draw.h fl_draw.H +l 0000 root sys $includedir/FL/fl_file_chooser.h Fl_File_Chooser.H +l 0000 root sys $includedir/FL/fl_file_chooser.H Fl_File_Chooser.H +l 0000 root sys $includedir/FL/fl_message.h fl_message.H +l 0000 root sys $includedir/FL/fl_show_colormap.h fl_show_colormap.H +l 0000 root sys $includedir/FL/fl_show_input.h fl_show_input.H +l 0000 root sys $includedir/FL/win32.h win32.H +l 0000 root sys $includedir/FL/x.h x.H +%system all + +# Documentation +d 0555 root sys $docdir - +f 0444 root sys $docdir/ documentation/*.gif +f 0444 root sys $docdir/ documentation/*.html +f 0444 root sys $docdir/ documentation/*.jpg +f 0444 root sys $docdir/COPYING COPYING +f 0444 root sys $docdir/CHANGES CHANGES + +# Examples +d 0555 root sys $docdir/examples +f 0444 root sys $docdir/examples/config.h config.h +f 0444 root sys $docdir/examples/ test/*.cxx +f 0444 root sys $docdir/examples/ test/*.fl +f 0444 root sys $docdir/examples/ test/*.h + +%subpackage games +%description FLTK Games +%description Install fltk-games to play Block Attack!, checkers, or Sudoku on your computer. + +%system darwin +d 0555 root sys /Applications/blocks.app - +d 0555 root sys /Applications/blocks.app/Contents - +f 0444 root sys /Applications/blocks.app/Contents/Info.plist test/blocks.app/Contents/Info.plist +f 0444 root sys /Applications/blocks.app/Contents/PkgInfo test/blocks.app/Contents/PkgInfo +d 0555 root sys /Applications/blocks.app/Contents/MacOS - +f 0555 root sys /Applications/blocks.app/Contents/MacOS/blocks test/blocks +d 0555 root sys /Applications/blocks.app/Contents/Resources - +f 0444 root sys /Applications/blocks.app/Contents/Resources/blocks.icns test/blocks.app/Contents/Resources/blocks.icns +%postremove /bin/rm -rf /Applications/blocks.app + +d 0555 root sys /Applications/checkers.app - +d 0555 root sys /Applications/checkers.app/Contents - +f 0444 root sys /Applications/checkers.app/Contents/Info.plist test/checkers.app/Contents/Info.plist +f 0444 root sys /Applications/checkers.app/Contents/PkgInfo test/checkers.app/Contents/PkgInfo +d 0555 root sys /Applications/checkers.app/Contents/MacOS - +f 0555 root sys /Applications/checkers.app/Contents/MacOS/checkers test/checkers +d 0555 root sys /Applications/checkers.app/Contents/Resources - +f 0444 root sys /Applications/checkers.app/Contents/Resources/checkers.icns test/checkers.app/Contents/Resources/checkers.icns +%postremove /bin/rm -rf /Applications/checkers.app + +d 0555 root sys /Applications/sudoku.app - +d 0555 root sys /Applications/sudoku.app/Contents - +f 0444 root sys /Applications/sudoku.app/Contents/Info.plist test/sudoku.app/Contents/Info.plist +f 0444 root sys /Applications/sudoku.app/Contents/PkgInfo test/sudoku.app/Contents/PkgInfo +d 0555 root sys /Applications/sudoku.app/Contents/MacOS - +f 0555 root sys /Applications/sudoku.app/Contents/MacOS/sudoku test/sudoku +d 0555 root sys /Applications/sudoku.app/Contents/Resources - +f 0444 root sys /Applications/sudoku.app/Contents/Resources/sudoku.icns test/sudoku.app/Contents/Resources/sudoku.icns +%postremove /bin/rm -rf /Applications/sudoku.app + +%system !darwin +f 0555 root sys $bindir/blocks test/blocks +f 0444 root sys /usr/share/applications/blocks.desktop test/desktop/blocks.desktop +f 0444 root sys /usr/share/icons/hicolor/32x32/apps/blocks.png test/desktop/blocks-32.png +f 0444 root sys /usr/share/icons/hicolor/128x128/apps/blocks.png test/desktop/blocks-128.png + +f 0555 root sys $bindir/checkers test/checkers +f 0444 root sys /usr/share/applications/checkers.desktop test/desktop/checkers.desktop +f 0444 root sys /usr/share/icons/hicolor/32x32/apps/checkers.png test/desktop/checkers-32.png +f 0444 root sys /usr/share/icons/hicolor/128x128/apps/checkers.png test/desktop/checkers-128.png + +f 0555 root sys $bindir/sudoku test/sudoku +f 0444 root sys /usr/share/applications/sudoku.desktop test/desktop/sudoku.desktop +f 0444 root sys /usr/share/icons/hicolor/32x32/apps/sudoku.png test/desktop/sudoku-32.png +f 0444 root sys /usr/share/icons/hicolor/128x128/apps/sudoku.png test/desktop/sudoku-128.png + +%system all +f 0444 root sys $mandir/cat6/blocks.$CAT6EXT documentation/blocks.$CAT6EXT +f 0444 root sys $mandir/cat6/checkers.$CAT6EXT documentation/checkers.$CAT6EXT +f 0444 root sys $mandir/cat6/sudoku.$CAT6EXT documentation/sudoku.$CAT6EXT +f 0444 root sys $mandir/man6/blocks.6 documentation/blocks.man +f 0444 root sys $mandir/man6/checkers.6 documentation/checkers.man +f 0444 root sys $mandir/man6/sudoku.6 documentation/sudoku.man + +# +# End of "$Id: fltk.list.in 6059 2008-02-28 16:50:07Z mike $". +# diff --git a/plugins/zynaddsubfx/fltk/fltk.spec.in b/plugins/zynaddsubfx/fltk/fltk.spec.in new file mode 100644 index 000000000..28fed04cc --- /dev/null +++ b/plugins/zynaddsubfx/fltk/fltk.spec.in @@ -0,0 +1,145 @@ +# +# "$Id: fltk.spec.in 6059 2008-02-28 16:50:07Z mike $" +# +# RPM spec file for FLTK. +# +# Copyright 1998-2008 by Bill Spitzak and others. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Library General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library 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 +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA. +# +# Please report all bugs and problems on the following page: +# +# http://www.fltk.org/str.php +# + +%define version @FL_MAJOR_VERSION@.@FL_MINOR_VERSION@.@FL_PATCH_VERSION@ +%define release 1 +%define prefix /usr + +Summary: Fast Light Tool Kit (FLTK) +Name: fltk +Version: %{version} +Release: %{release} +License: LGPL +Group: System Environment/Libraries +Source: ftp://ftp.fltk.org/pub/fltk/%{version}/fltk-%{version}-source.tar.gz +URL: http://www.fltk.org/ +Packager: FLTK Developer +# use BuildRoot so as not to disturb the version already installed +BuildRoot: /var/tmp/fltk-%{PACKAGE_VERSION} + +%description +The Fast Light Tool Kit ("FLTK", pronounced "fulltick") is a +cross-platform C++ GUI toolkit for UNIX(r)/Linux(r) (X11), +Microsoft(r) Windows(r), and MacOS(r) X. FLTK provides modern +GUI functionality without the bloat and supports 3D graphics via +OpenGL(r) and its built-in GLUT emulation. + +%package devel +Summary: FLTK Development Environment +Group: Development/Libraries + +%description devel +Install fltk-devel if you need to develop FLTK applications. +You'll need to install the fltk package if you plan to run +dynamically linked applications. + +%package games +Summary: FLTK Games +Group: Games + +%description games +Install fltk-games to play Block Attack!, Checkers, or Sudoku on your computer. + +%prep +%setup + +%build +CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_FLAGS" LDFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{prefix} --mandir=%{_mandir} --enable-largefile --enable-shared --enable-threads --enable-xft --enable-xdbe --enable-xinerama + +# If we got this far, all prerequisite libraries must be here. +make + +%install +# these lines just make sure the directory structure in the +# RPM_BUILD_ROOT exists +rm -rf $RPM_BUILD_ROOT +mkdir -p $RPM_BUILD_ROOT + +make -e DESTDIR=$RPM_BUILD_ROOT install install-desktop + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%defattr(-,root,root) +%dir %{prefix}/lib +%{prefix}/lib/libfltk*.so.* + +%files devel +%defattr(-,root,root) + +%dir %{prefix}/bin +%{prefix}/bin/fltk-config +%{prefix}/bin/fluid + +%dir %{prefix}/include/FL +%{prefix}/include/FL/* +%{prefix}/include/Fl + +%dir %{prefix}/lib +%{prefix}/lib/libfltk*.so +%{prefix}/lib/libfltk*.a + +%dir %{_mandir} +%{_mandir}/cat1/* +%{_mandir}/cat3/* +%{_mandir}/man1/* +%{_mandir}/man3/* + +%dir %{prefix}/share/doc/fltk +%{prefix}/share/doc/fltk/* + +%dir %{prefix}/share/applications +%{prefix}/share/applications/* + +%dir %{prefix}/share/icons +%{prefix}/share/icons/hicolor/*/apps/fluid.png + +%dir %{prefix}/share/mimelnk +%{prefix}/share/mimelnk/* + +%files games +%dir %{prefix}/bin +%{prefix}/bin/blocks +%{prefix}/bin/checkers +%{prefix}/bin/sudoku + +%dir %{_mandir} +%{_mandir}/cat6/* +%{_mandir}/man6/* + +%dir %{prefix}/share/applications +%{prefix}/share/applications/* + +%dir %{prefix}/share/icons +%{prefix}/share/icons/hicolor/*/apps/blocks.png +%{prefix}/share/icons/hicolor/*/apps/checkers.png +%{prefix}/share/icons/hicolor/*/apps/sudoku.png + +# +# End of "$Id: fltk.spec.in 6059 2008-02-28 16:50:07Z mike $". +# diff --git a/plugins/zynaddsubfx/fltk/src/CMakeLists.txt b/plugins/zynaddsubfx/fltk/src/CMakeLists.txt new file mode 100644 index 000000000..d63f61b0d --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/CMakeLists.txt @@ -0,0 +1,208 @@ +SET(CPPFILES + Fl.cxx + Fl_Adjuster.cxx + Fl_Bitmap.cxx + Fl_Browser.cxx + Fl_Browser_.cxx + Fl_Browser_load.cxx + Fl_Box.cxx + Fl_Button.cxx + Fl_Chart.cxx + Fl_Check_Browser.cxx + Fl_Check_Button.cxx + Fl_Choice.cxx + Fl_Clock.cxx + Fl_Color_Chooser.cxx + Fl_Counter.cxx + Fl_Dial.cxx + Fl_Double_Window.cxx + Fl_File_Browser.cxx + Fl_File_Chooser.cxx + Fl_File_Chooser2.cxx + Fl_File_Icon.cxx + Fl_File_Input.cxx + Fl_Group.cxx + Fl_Help_View.cxx + Fl_Image.cxx + Fl_Input.cxx + Fl_Input_.cxx + Fl_Light_Button.cxx + Fl_Menu.cxx + Fl_Menu_.cxx + Fl_Menu_Bar.cxx + Fl_Sys_Menu_Bar.cxx + Fl_Menu_Button.cxx + Fl_Menu_Window.cxx + Fl_Menu_add.cxx + Fl_Menu_global.cxx + Fl_Multi_Label.cxx + Fl_Overlay_Window.cxx + Fl_Pack.cxx + Fl_Pixmap.cxx + Fl_Positioner.cxx + Fl_Preferences.cxx + Fl_Progress.cxx + Fl_Repeat_Button.cxx + Fl_Return_Button.cxx + Fl_Roller.cxx + Fl_Round_Button.cxx + Fl_Scroll.cxx + Fl_Scrollbar.cxx + Fl_Shared_Image.cxx + Fl_Single_Window.cxx + Fl_Slider.cxx + Fl_Tabs.cxx + Fl_Text_Buffer.cxx + Fl_Text_Display.cxx + Fl_Text_Editor.cxx + Fl_Tile.cxx + Fl_Tiled_Image.cxx + Fl_Tooltip.cxx + Fl_Valuator.cxx + Fl_Value_Input.cxx + Fl_Value_Output.cxx + Fl_Value_Slider.cxx + Fl_Widget.cxx + Fl_Window.cxx + Fl_Window_fullscreen.cxx + Fl_Window_hotspot.cxx + Fl_Window_iconize.cxx + Fl_Wizard.cxx + Fl_XBM_Image.cxx + Fl_XPM_Image.cxx + Fl_abort.cxx + Fl_add_idle.cxx + Fl_arg.cxx + Fl_compose.cxx + Fl_display.cxx + Fl_get_key.cxx + Fl_get_system_colors.cxx + Fl_grab.cxx + Fl_lock.cxx + Fl_own_colormap.cxx + Fl_visual.cxx + Fl_x.cxx + filename_absolute.cxx + filename_expand.cxx + filename_ext.cxx + filename_isdir.cxx + filename_list.cxx + filename_match.cxx + filename_setext.cxx + fl_arc.cxx + fl_arci.cxx + fl_ask.cxx + fl_boxtype.cxx + fl_color.cxx + fl_cursor.cxx + fl_curve.cxx + fl_diamond_box.cxx + fl_dnd.cxx + fl_draw.cxx + fl_draw_image.cxx + fl_draw_pixmap.cxx + fl_engraved_label.cxx + fl_file_dir.cxx + fl_font.cxx + fl_gtk.cxx + fl_labeltype.cxx + fl_line_style.cxx + fl_open_uri.cxx + fl_oval_box.cxx + fl_overlay.cxx + fl_overlay_visual.cxx + fl_plastic.cxx + fl_read_image.cxx + fl_rect.cxx + fl_round_box.cxx + fl_rounded_box.cxx + fl_set_font.cxx + fl_set_fonts.cxx + fl_scroll_area.cxx + fl_shadow_box.cxx + fl_shortcut.cxx + fl_show_colormap.cxx + fl_symbols.cxx + fl_vertex.cxx + screen_xywh.cxx + ) +SET(FLCPPFILES + forms_compatability.cxx + forms_bitmap.cxx + forms_free.cxx + forms_fselect.cxx + forms_pixmap.cxx + forms_timer.cxx + ) +SET(GLCPPFILES + Fl_Gl_Choice.cxx + Fl_Gl_Overlay.cxx + Fl_Gl_Window.cxx + freeglut_geometry.cxx + freeglut_stroke_mono_roman.cxx + freeglut_stroke_roman.cxx + freeglut_teapot.cxx + gl_draw.cxx + gl_start.cxx + glut_compatability.cxx + glut_font.cxx + ) +SET(IMGCPPFILES + fl_images_core.cxx + Fl_BMP_Image.cxx + Fl_File_Icon2.cxx + Fl_GIF_Image.cxx + Fl_Help_Dialog.cxx + Fl_JPEG_Image.cxx + Fl_PNG_Image.cxx + Fl_PNM_Image.cxx + ) + +SET(CFILES + fl_call_main.c + flstring.c + scandir.c + numericsort.c + vsnprintf.c + ) + +ADD_LIBRARY(fltk ${CPPFILES} ${CFILES}) +INSTALL_TARGETS(/lib fltk) +SET_TARGET_PROPERTIES(fltk + PROPERTIES + VERSION ${FLTK_VERSION_MAJOR}.${FLTK_VERSION_MINOR} + SOVERSION ${FLTK_VERSION_PATCH}) + +TARGET_LINK_LIBRARIES(fltk ${FLTK_PLATFORM_DEPENDENT_LIBS} ${CMAKE_THREAD_LIBS_INIT}) + +IF(X11_FOUND) + TARGET_LINK_LIBRARIES(fltk ${X11_LIBRARIES}) +ENDIF(X11_FOUND) + +#IF(OPENGL_FOUND) +# ADD_LIBRARY(fltk_gl ${GLCPPFILES}) +# INSTALL_TARGETS(/lib fltk_gl) +# TARGET_LINK_LIBRARIES(fltk_gl fltk ${OPENGL_LIBRARIES}) +# SET_TARGET_PROPERTIES(fltk_gl +# PROPERTIES +# VERSION ${FLTK_VERSION_MAJOR}.${FLTK_VERSION_MINOR} +# SOVERSION ${FLTK_VERSION_PATCH}) +#ENDIF(OPENGL_FOUND) + +#ADD_LIBRARY(fltk_forms ${FLCPPFILES}) +#INSTALL_TARGETS(/lib fltk_forms) +#TARGET_LINK_LIBRARIES(fltk_forms fltk) +#SET_TARGET_PROPERTIES(fltk_forms +# PROPERTIES +# VERSION ${FLTK_VERSION_MAJOR}.${FLTK_VERSION_MINOR} +# SOVERSION ${FLTK_VERSION_PATCH}) +# +#ADD_LIBRARY(fltk_images ${IMGCPPFILES}) +#INSTALL_TARGETS(/lib fltk_images) +#TARGET_LINK_LIBRARIES(fltk_images fltk ${FLTK_PNG_LIBRARIES} +# ${FLTK_JPEG_LIBRARIES} ${FLTK_ZLIB_LIBRARIES}) +#SET_TARGET_PROPERTIES(fltk_images +# PROPERTIES +# VERSION ${FLTK_VERSION_MAJOR}.${FLTK_VERSION_MINOR} +# SOVERSION ${FLTK_VERSION_PATCH}) +# diff --git a/plugins/zynaddsubfx/fltk/src/Fl.cxx b/plugins/zynaddsubfx/fltk/src/Fl.cxx new file mode 100644 index 000000000..0ea325bfb --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl.cxx @@ -0,0 +1,1307 @@ +// +// "$Id: Fl.cxx 5654 2007-02-02 13:52:37Z matt $" +// +// Main event handling code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2006 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// warning: the Apple Quartz version still uses some Quickdraw calls, +// mostly to get around the single active context in QD and +// to implement clipping. This should be changed into pure +// Quartz calls in the near future. + +#include +#include +#include +#include +#include +#include +#include +#include "flstring.h" + +#ifdef DEBUG +# include +#endif // DEBUG + +#ifdef WIN32 +# include +void fl_free_fonts(void); +HBRUSH fl_brush_action(int action); +void fl_cleanup_pens(void); +void fl_release_dc(HWND,HDC); +void fl_cleanup_dc_list(void); +#endif // WIN32 + +// +// Globals... +// + +Fl_Widget *Fl::belowmouse_, + *Fl::pushed_, + *Fl::focus_, + *Fl::selection_owner_; +int Fl::damage_, + Fl::e_number, + Fl::e_x, + Fl::e_y, + Fl::e_x_root, + Fl::e_y_root, + Fl::e_dx, + Fl::e_dy, + Fl::e_state, + Fl::e_clicks, + Fl::e_is_click, + Fl::e_keysym, + Fl::e_original_keysym; +char *Fl::e_text = (char *)""; +int Fl::e_length; +int Fl::visible_focus_ = 1, + Fl::dnd_text_ops_ = 1; + + +Fl_Window *fl_xfocus; // which window X thinks has focus +Fl_Window *fl_xmousewin;// which window X thinks has FL_ENTER +Fl_Window *Fl::grab_; // most recent Fl::grab() +Fl_Window *Fl::modal_; // topmost modal() window + +// +// 'Fl::version()' - Return the API version number... +// + +double +Fl::version() { + return FL_VERSION; +} + + +// +// 'Fl:event_inside()' - Return whether or not the mouse event is inside +// the given rectangle. +// + +int Fl::event_inside(int xx,int yy,int ww,int hh) /*const*/ { + int mx = e_x - xx; + int my = e_y - yy; + return (mx >= 0 && mx < ww && my >= 0 && my < hh); +} + +int Fl::event_inside(const Fl_Widget *o) /*const*/ { + int mx = e_x - o->x(); + int my = e_y - o->y(); + return (mx >= 0 && mx < o->w() && my >= 0 && my < o->h()); +} + +// +// +// timer support +// + +#ifdef WIN32 + +/// implementation in Fl_win32.cxx + +#elif defined(__APPLE__) + +/// implementation in Fl_mac.cxx + +#else + +// +// X11 timers +// + + +//////////////////////////////////////////////////////////////// +// Timeouts are stored in a sorted list, so only the first one needs +// to be checked to see if any should be called. + +struct Timeout { + double time; + void (*cb)(void*); + void* arg; + Timeout* next; +}; +static Timeout* first_timeout, *free_timeout; +static int first_timeout_count, free_timeout_count; + +#include + +// I avoid the overhead of getting the current time when we have no +// timeouts by setting this flag instead of getting the time. +// In this case calling elapse_timeouts() does nothing, but records +// the current time, and the next call will actualy elapse time. +static char reset_clock = 1; + +static void elapse_timeouts() { + static struct timeval prevclock; + struct timeval newclock; + gettimeofday(&newclock, NULL); + double elapsed = newclock.tv_sec - prevclock.tv_sec + + (newclock.tv_usec - prevclock.tv_usec)/1000000.0; + prevclock.tv_sec = newclock.tv_sec; + prevclock.tv_usec = newclock.tv_usec; + if (reset_clock) { + reset_clock = 0; + } else if (elapsed > 0) { + for (Timeout* t = first_timeout; t; t = t->next) t->time -= elapsed; + } +} + +// Continuously-adjusted error value, this is a number <= 0 for how late +// we were at calling the last timeout. This appears to make repeat_timeout +// very accurate even when processing takes a significant portion of the +// time interval: +static double missed_timeout_by; + +void Fl::add_timeout(double time, Fl_Timeout_Handler cb, void *argp) { + elapse_timeouts(); + repeat_timeout(time, cb, argp); +} + +void Fl::repeat_timeout(double time, Fl_Timeout_Handler cb, void *argp) { + time += missed_timeout_by; if (time < -.05) time = 0; + Timeout* t = free_timeout; + if (t) { + free_timeout = t->next; + --free_timeout_count; + } else { + t = new Timeout; + } + t->time = time; + t->cb = cb; + t->arg = argp; + // insert-sort the new timeout: + Timeout** p = &first_timeout; + while (*p && (*p)->time <= time) p = &((*p)->next); + t->next = *p; + *p = t; +} + +int Fl::has_timeout(Fl_Timeout_Handler cb, void *argp) { + for (Timeout* t = first_timeout; t; t = t->next) + if (t->cb == cb && t->arg == argp) return 1; + return 0; +} + +void Fl::remove_timeout(Fl_Timeout_Handler cb, void *argp) { + // This version removes all matching timeouts, not just the first one. + // This may change in the future. + for (Timeout** p = &first_timeout; *p;) { + Timeout* t = *p; + if (t->cb == cb && (t->arg == argp || !argp)) { + *p = t->next; + t->next = free_timeout; + free_timeout = t; + } else { + p = &(t->next); + } + } +} + +#endif + +//////////////////////////////////////////////////////////////// +// Checks are just stored in a list. They are called in the reverse +// order that they were added (this may change in the future). +// This is a bit messy because I want to allow checks to be added, +// removed, and have wait() called from inside them, to do this +// next_check points at the next unprocessed one for the outermost +// call to Fl::wait(). + +struct Check { + void (*cb)(void*); + void* arg; + Check* next; +}; +static Check *first_check, *next_check, *free_check; + +void Fl::add_check(Fl_Timeout_Handler cb, void *argp) { + Check* t = free_check; + if (t) free_check = t->next; + else t = new Check; + t->cb = cb; + t->arg = argp; + t->next = first_check; + if (next_check == first_check) next_check = t; + first_check = t; +} + +void Fl::remove_check(Fl_Timeout_Handler cb, void *argp) { + for (Check** p = &first_check; *p;) { + Check* t = *p; + if (t->cb == cb && t->arg == argp) { + if (next_check == t) next_check = t->next; + *p = t->next; + t->next = free_check; + free_check = t; + } else { + p = &(t->next); + } + } +} + +/** + * Return 1, if a check with the same handler and data pointer + * is pending, 0 otherwise. + */ +int Fl::has_check(Fl_Timeout_Handler cb, void *argp) { + for (Check** p = &first_check; *p;) { + Check* t = *p; + if (t->cb == cb && t->arg == argp) { + return 1; + } else { + p = &(t->next); + } + } + return 0; +} + +static void run_checks() +{ + // checks are a bit messy so that add/remove and wait may be called + // from inside them without causing an infinite loop: + if (next_check == first_check) { + while (next_check) { + Check* checkp = next_check; + next_check = checkp->next; + (checkp->cb)(checkp->arg); + } + next_check = first_check; + } +} + +#ifndef WIN32 +static char in_idle; +#endif + +//////////////////////////////////////////////////////////////// +// wait/run/check/ready: + +void (*Fl::idle)(); // see Fl_add_idle.cxx for the add/remove functions + +extern int fl_ready(); // in Fl_.cxx +extern int fl_wait(double time); // in Fl_.cxx + +double Fl::wait(double time_to_wait) { + // delete all widgets that were listed during callbacks + do_widget_deletion(); + +#ifdef WIN32 + + return fl_wait(time_to_wait); + +#elif defined(__APPLE__) + + run_checks(); + if (idle) { + if (!in_idle) { + in_idle = 1; + idle(); + in_idle = 0; + } + // the idle function may turn off idle, we can then wait: + if (idle) time_to_wait = 0.0; + } + flush(); + return fl_wait(time_to_wait); + +#else + + if (first_timeout) { + elapse_timeouts(); + Timeout *t; + while ((t = first_timeout)) { + if (t->time > 0) break; + // The first timeout in the array has expired. + missed_timeout_by = t->time; + // We must remove timeout from array before doing the callback: + void (*cb)(void*) = t->cb; + void *argp = t->arg; + first_timeout = t->next; + t->next = free_timeout; + free_timeout = t; + ++free_timeout_count; + --first_timeout_count; + // Now it is safe for the callback to do add_timeout: + cb(argp); + } + } else { + reset_clock = 1; // we are not going to check the clock + } + run_checks(); +// if (idle && !fl_ready()) { + if (idle) { + if (!in_idle) { + in_idle = 1; + idle(); + in_idle = 0; + } + // the idle function may turn off idle, we can then wait: + if (idle) time_to_wait = 0.0; + } + if (first_timeout && first_timeout->time < time_to_wait) + time_to_wait = first_timeout->time; + if (time_to_wait <= 0.0) { + // do flush second so that the results of events are visible: + int ret = fl_wait(0.0); + flush(); + return ret; + } else { + // do flush first so that user sees the display: + flush(); + return fl_wait(time_to_wait); + } +#endif +} + +#define FOREVER 1e20 + +int Fl::run() { + while (Fl_X::first) wait(FOREVER); + return 0; +} + +#ifdef WIN32 +class Fl_Win32_At_Exit { +public: + Fl_Win32_At_Exit() { } + ~Fl_Win32_At_Exit() { + fl_free_fonts(); // do some WIN32 cleanup + fl_cleanup_pens(); + OleUninitialize(); + fl_brush_action(1); + fl_cleanup_dc_list(); + } +}; +static Fl_Win32_At_Exit win32_at_exit; +#endif + + + +int Fl::wait() { + if (!Fl_X::first) return 0; + wait(FOREVER); + return Fl_X::first != 0; // return true if there is a window +} + +int Fl::check() { + wait(0.0); + return Fl_X::first != 0; // return true if there is a window +} + +int Fl::ready() { +#if ! defined( WIN32 ) && ! defined(__APPLE__) + if (first_timeout) { + elapse_timeouts(); + if (first_timeout->time <= 0) return 1; + } else { + reset_clock = 1; + } +#endif + return fl_ready(); +} + +//////////////////////////////////////////////////////////////// +// Window list management: + +Fl_X* Fl_X::first; + +Fl_Window* fl_find(Window xid) { + Fl_X *window; + for (Fl_X **pp = &Fl_X::first; (window = *pp); pp = &window->next) +#ifdef __APPLE_QD__ + if (window->xid == xid && !window->w->window()) { +#elif defined(__APPLE_QUARTZ__) + if (window->xid == xid && !window->w->window()) { +#else + if (window->xid == xid) { +#endif // __APPLE__ + if (window != Fl_X::first && !Fl::modal()) { + // make this window be first to speed up searches + // this is not done if modal is true to avoid messing up modal stack + *pp = window->next; + window->next = Fl_X::first; + Fl_X::first = window; + } + return window->w; + } + return 0; +} + +Fl_Window* Fl::first_window() { + Fl_X* i = Fl_X::first; + return i ? i->w : 0; +} + +Fl_Window* Fl::next_window(const Fl_Window* window) { + Fl_X* i = Fl_X::i(window)->next; + return i ? i->w : 0; +} + +void Fl::first_window(Fl_Window* window) { + if (!window || !window->shown()) return; + fl_find(fl_xid(window)); +} + +void Fl::redraw() { + for (Fl_X* i = Fl_X::first; i; i = i->next) i->w->redraw(); +} + +void Fl::flush() { + if (damage()) { + damage_ = 0; + for (Fl_X* i = Fl_X::first; i; i = i->next) { + if (i->wait_for_expose) {damage_ = 1; continue;} + Fl_Window* wi = i->w; + if (!wi->visible_r()) continue; + if (wi->damage()) {i->flush(); wi->clear_damage();} + // destroy damage regions for windows that don't use them: + if (i->region) {XDestroyRegion(i->region); i->region = 0;} + } + } + +#ifdef WIN32 + GdiFlush(); +#elif defined(__APPLE_QD__) + GrafPtr port; + GetPort( &port ); + if ( port ) + QDFlushPortBuffer( port, 0 ); +#elif defined (__APPLE_QUARTZ__) + if (fl_gc) + CGContextFlush(fl_gc); +#else + if (fl_display) XFlush(fl_display); +#endif +} + +//////////////////////////////////////////////////////////////// +// Event handlers: + +struct handler_link { + int (*handle)(int); + handler_link *next; +}; + +static handler_link *handlers = 0; + +void Fl::add_handler(int (*ha)(int)) { + handler_link *l = new handler_link; + l->handle = ha; + l->next = handlers; + handlers = l; +} + +void Fl::remove_handler(int (*ha)(int)) { + handler_link *l, *p; + + // Search for the handler in the list... + for (l = handlers, p = 0; l && l->handle != ha; p = l, l = l->next); + + if (l) { + // Found it, so remove it from the list... + if (p) p->next = l->next; + else handlers = l->next; + + // And free the record... + delete l; + } +} + +int (*fl_local_grab)(int); // used by fl_dnd.cxx + +static int send_handlers(int e) { + for (const handler_link *hl = handlers; hl; hl = hl->next) + if (hl->handle(e)) return 1; + return 0; +} + +//////////////////////////////////////////////////////////////// + +Fl_Widget* fl_oldfocus; // kludge for Fl_Group... + +void Fl::focus(Fl_Widget *o) { + if (o && !o->visible_focus()) return; + if (grab()) return; // don't do anything while grab is on + Fl_Widget *p = focus_; + if (o != p) { + Fl::compose_reset(); + focus_ = o; + // make sure that fl_xfocus is set to the top level window + // of this widget, or fl_fix_focus will clear our focus again + if (o) { + Fl_Window *win = 0, *w1 = o->window(); + while (w1) { win=w1; w1=win->window(); } + if (win) fl_xfocus = win; + } + // take focus from the old focused window + fl_oldfocus = 0; + int old_event = e_number; + e_number = FL_UNFOCUS; + for (; p; p = p->parent()) { + p->handle(FL_UNFOCUS); + fl_oldfocus = p; + } + e_number = old_event; + } +} + +static char dnd_flag = 0; // make 'belowmouse' send DND_LEAVE instead of LEAVE + +void Fl::belowmouse(Fl_Widget *o) { + if (grab()) return; // don't do anything while grab is on + Fl_Widget *p = belowmouse_; + if (o != p) { + belowmouse_ = o; + int old_event = e_number; + e_number = dnd_flag ? FL_DND_LEAVE : FL_LEAVE; + for (; p && !p->contains(o); p = p->parent()) { + p->handle(e_number); + } + e_number = old_event; + } +} + +void Fl::pushed(Fl_Widget *o) { + pushed_ = o; +} + +static void nothing(Fl_Widget *) {} +void (*Fl_Tooltip::enter)(Fl_Widget *) = nothing; +void (*Fl_Tooltip::exit)(Fl_Widget *) = nothing; + +// Update modal(), focus() and other state according to system state, +// and send FL_ENTER, FL_LEAVE, FL_FOCUS, and/or FL_UNFOCUS events. +// This is the only function that produces these events in response +// to system activity. +// This is called whenever a window is added or hidden, and whenever +// X says the focus or mouse window have changed. + +void fl_fix_focus() { +#ifdef DEBUG + puts("fl_fix_focus();"); +#endif // DEBUG + + if (Fl::grab()) return; // don't do anything while grab is on. + + // set focus based on Fl::modal() and fl_xfocus + Fl_Widget* w = fl_xfocus; + if (w) { + int saved = Fl::e_keysym; + if (Fl::e_keysym < (FL_Button + FL_LEFT_MOUSE) || + Fl::e_keysym > (FL_Button + FL_RIGHT_MOUSE)) + Fl::e_keysym = 0; // make sure widgets don't think a keystroke moved focus + while (w->parent()) w = w->parent(); + if (Fl::modal()) w = Fl::modal(); + if (!w->contains(Fl::focus())) + if (!w->take_focus()) Fl::focus(w); + Fl::e_keysym = saved; + } else + Fl::focus(0); + +// MRS: Originally we checked the button state, but a user reported that it +// broke click-to-focus in FLWM?!? +// if (!(Fl::event_state() & 0x7f00000 /*FL_BUTTONS*/)) { + if (!Fl::pushed()) { + // set belowmouse based on Fl::modal() and fl_xmousewin: + w = fl_xmousewin; + if (w) { + if (Fl::modal()) w = Fl::modal(); + if (!w->contains(Fl::belowmouse())) { + int old_event = Fl::e_number; + w->handle(Fl::e_number = FL_ENTER); + Fl::e_number = old_event; + if (!w->contains(Fl::belowmouse())) Fl::belowmouse(w); + } else { + // send a FL_MOVE event so the enter/leave state is up to date + Fl::e_x = Fl::e_x_root-fl_xmousewin->x(); + Fl::e_y = Fl::e_y_root-fl_xmousewin->y(); + int old_event = Fl::e_number; + w->handle(Fl::e_number = FL_MOVE); + Fl::e_number = old_event; + } + } else { + Fl::belowmouse(0); + Fl_Tooltip::enter(0); + } + } +} + +#ifndef WIN32 +extern Fl_Widget *fl_selection_requestor; // from Fl_x.cxx +#endif + +// This function is called by ~Fl_Widget() and by Fl_Widget::deactivate +// and by Fl_Widget::hide(). It indicates that the widget does not want +// to receive any more events, and also removes all global variables that +// point at the widget. +// I changed this from the 1.0.1 behavior, the older version could send +// FL_LEAVE or FL_UNFOCUS events to the widget. This appears to not be +// desirable behavior and caused flwm to crash. + +void fl_throw_focus(Fl_Widget *o) { +#ifdef DEBUG + printf("fl_throw_focus(o=%p)\n", o); +#endif // DEBUG + + if (o->contains(Fl::pushed())) Fl::pushed_ = 0; +#ifndef WIN32 + if (o->contains(fl_selection_requestor)) fl_selection_requestor = 0; +#endif + if (o->contains(Fl::belowmouse())) Fl::belowmouse_ = 0; + if (o->contains(Fl::focus())) Fl::focus_ = 0; + if (o == fl_xfocus) fl_xfocus = 0; + if (o == Fl_Tooltip::current()) Fl_Tooltip::current(0); + if (o == fl_xmousewin) fl_xmousewin = 0; + Fl_Tooltip::exit(o); + fl_fix_focus(); +} + +//////////////////////////////////////////////////////////////// + +// Call to->handle but first replace the mouse x/y with the correct +// values to account for nested X windows. 'window' is the outermost +// window the event was posted to by X: +static int send(int event, Fl_Widget* to, Fl_Window* window) { + int dx, dy; + int old_event = Fl::e_number; + if (window) { + dx = window->x(); + dy = window->y(); + } else { + dx = dy = 0; + } + for (const Fl_Widget* w = to; w; w = w->parent()) + if (w->type()>=FL_WINDOW) {dx -= w->x(); dy -= w->y();} + int save_x = Fl::e_x; Fl::e_x += dx; + int save_y = Fl::e_y; Fl::e_y += dy; + int ret = to->handle(Fl::e_number = event); + Fl::e_number = old_event; + Fl::e_y = save_y; + Fl::e_x = save_x; + return ret; +} + +int Fl::handle(int e, Fl_Window* window) +{ + e_number = e; + if (fl_local_grab) return fl_local_grab(e); + + Fl_Widget* wi = window; + + switch (e) { + + case FL_CLOSE: + if (grab() || modal() && window != modal()) return 0; + wi->do_callback(); + return 1; + + case FL_SHOW: + wi->show(); // this calls Fl_Widget::show(), not Fl_Window::show() + return 1; + + case FL_HIDE: + wi->hide(); // this calls Fl_Widget::hide(), not Fl_Window::hide() + return 1; + + case FL_PUSH: +#ifdef DEBUG + printf("Fl::handle(e=%d, window=%p);\n", e, window); +#endif // DEBUG + + if (grab()) wi = grab(); + else if (modal() && wi != modal()) return 0; + pushed_ = wi; + Fl_Tooltip::current(wi); + if (send(e, wi, window)) return 1; + // raise windows that are clicked on: + window->show(); + return 1; + + case FL_DND_ENTER: + case FL_DND_DRAG: + dnd_flag = 1; + break; + + case FL_DND_LEAVE: + dnd_flag = 1; + belowmouse(0); + dnd_flag = 0; + return 1; + + case FL_DND_RELEASE: + wi = belowmouse(); + break; + + case FL_MOVE: + case FL_DRAG: + fl_xmousewin = window; // this should already be set, but just in case. + if (pushed()) { + wi = pushed(); + if (grab()) wi = grab(); + e_number = e = FL_DRAG; + break; + } + if (modal() && wi != modal()) wi = 0; + if (grab()) wi = grab(); + {Fl_Widget* pbm = belowmouse(); + int ret = (wi && send(e, wi, window)); + if (pbm != belowmouse()) { +#ifdef DEBUG + printf("Fl::handle(e=%d, window=%p);\n", e, window); +#endif // DEBUG + Fl_Tooltip::enter(belowmouse()); + } + return ret;} + + case FL_RELEASE: { +// printf("FL_RELEASE: window=%p, pushed() = %p, grab() = %p, modal() = %p\n", +// window, pushed(), grab(), modal()); + + if (grab()) { + wi = grab(); + pushed_ = 0; // must be zero before callback is done! + } else if (pushed()) { + wi = pushed(); + pushed_ = 0; // must be zero before callback is done! + } else if (modal() && wi != modal()) return 0; + int r = send(e, wi, window); + fl_fix_focus(); + return r;} + + case FL_UNFOCUS: + window = 0; + case FL_FOCUS: + fl_xfocus = window; + fl_fix_focus(); + return 1; + + case FL_KEYUP: + // Send the key-up to the current focus. This is not + // always the same widget that received the corresponding + // FL_KEYBOARD event because focus may have changed. + // Sending the KEYUP to the right KEYDOWN is possible, but + // would require that we track the KEYDOWN for every possible + // key stroke (users may hold down multiple keys!) and then + // make sure that the widget still exists before sending + // a KEYUP there. I believe that the current solution is + // "close enough". + for (wi = grab() ? grab() : focus(); wi; wi = wi->parent()) + if (send(FL_KEYUP, wi, window)) return 1; + return 0; + + case FL_KEYBOARD: +#ifdef DEBUG + printf("Fl::handle(e=%d, window=%p);\n", e, window); +#endif // DEBUG + + Fl_Tooltip::enter((Fl_Widget*)0); + + fl_xfocus = window; // this should not happen! But maybe it does: + + // Try it as keystroke, sending it to focus and all parents: + for (wi = grab() ? grab() : focus(); wi; wi = wi->parent()) + if (send(FL_KEYBOARD, wi, window)) return 1; + + // recursive call to try shortcut: + if (handle(FL_SHORTCUT, window)) return 1; + + // and then try a shortcut with the case of the text swapped, by + // changing the text and falling through to FL_SHORTCUT case: + {unsigned char* c = (unsigned char*)event_text(); // cast away const + if (!isalpha(*c)) return 0; + *c = isupper(*c) ? tolower(*c) : toupper(*c);} + e_number = e = FL_SHORTCUT; + + case FL_SHORTCUT: + if (grab()) {wi = grab(); break;} // send it to grab window + + // Try it as shortcut, sending to mouse widget and all parents: + wi = belowmouse(); + if (!wi) { + wi = modal(); + if (!wi) wi = window; + } else if (wi->window() != first_window()) { + if (send(FL_SHORTCUT, first_window(), first_window())) return 1; + } + + for (; wi; wi = wi->parent()) { + if (send(FL_SHORTCUT, wi, wi->window())) return 1; + } + + // try using add_handle() functions: + if (send_handlers(FL_SHORTCUT)) return 1; + + // make Escape key close windows: + if (event_key()==FL_Escape) { + wi = modal(); if (!wi) wi = window; + wi->do_callback(); + return 1; + } + + return 0; + + case FL_ENTER: +#ifdef DEBUG + printf("Fl::handle(e=%d, window=%p);\n", e, window); +#endif // DEBUG + + fl_xmousewin = window; + fl_fix_focus(); + Fl_Tooltip::enter(belowmouse()); + return 1; + + case FL_LEAVE: +#ifdef DEBUG + printf("Fl::handle(e=%d, window=%p);\n", e, window); +#endif // DEBUG + + if (!pushed_) { + belowmouse(0); + Fl_Tooltip::enter(0); + } + if (window == fl_xmousewin) {fl_xmousewin = 0; fl_fix_focus();} + return 1; + + case FL_MOUSEWHEEL: + fl_xfocus = window; // this should not happen! But maybe it does: + + // Try sending it to the "grab" first + if (grab() && grab()!=modal() && grab()!=window) { + if (send(FL_MOUSEWHEEL, grab(), window)) return 1; + } + // Now try sending it to the "modal" window + if (modal()) { + send(FL_MOUSEWHEEL, modal(), window); + return 1; + } + // Finally try sending it to the window, the event occured in + if (send(FL_MOUSEWHEEL, window, window)) return 1; + default: + break; + } + if (wi && send(e, wi, window)) { + dnd_flag = 0; + return 1; + } + dnd_flag = 0; + return send_handlers(e); +} + +//////////////////////////////////////////////////////////////// +// hide() destroys the X window, it does not do unmap! + +#if !defined(WIN32) && USE_XFT +extern void fl_destroy_xft_draw(Window); +#endif + +void Fl_Window::hide() { + clear_visible(); + + if (!shown()) return; + + // remove from the list of windows: + Fl_X* ip = i; + Fl_X** pp = &Fl_X::first; + for (; *pp != ip; pp = &(*pp)->next) if (!*pp) return; + *pp = ip->next; +#ifdef __APPLE__ + MacUnlinkWindow(ip); + // MacOS X manages a single pointer per application. Make sure that hiding + // a toplevel window will not leave us with some random pointer shape, or + // worst case, an invisible pointer + if (!parent()) cursor(FL_CURSOR_DEFAULT); +#endif + i = 0; + + // recursively remove any subwindows: + for (Fl_X *wi = Fl_X::first; wi;) { + Fl_Window* W = wi->w; + if (W->window() == this) { + W->hide(); + W->set_visible(); + wi = Fl_X::first; + } else wi = wi->next; + } + + if (this == Fl::modal_) { // we are closing the modal window, find next one: + Fl_Window* W; + for (W = Fl::first_window(); W; W = Fl::next_window(W)) + if (W->modal()) break; + Fl::modal_ = W; + } + + // Make sure no events are sent to this window: + fl_throw_focus(this); + handle(FL_HIDE); + +#ifdef WIN32 + // this little trick keeps the current clipboard alive, even if we are about + // to destroy the window that owns the selection. + if (GetClipboardOwner()==ip->xid) { + Fl_Window *w1 = Fl::first_window(); + if (w1 && OpenClipboard(fl_xid(w1))) { + EmptyClipboard(); + SetClipboardData(CF_TEXT, NULL); + CloseClipboard(); + } + } + // Send a message to myself so that I'll get out of the event loop... + PostMessage(ip->xid, WM_APP, 0, 0); + if (ip->private_dc) fl_release_dc(ip->xid, ip->private_dc); + if (ip->xid == fl_window && fl_gc) { + fl_release_dc(fl_window, fl_gc); + fl_window = (HWND)-1; + fl_gc = 0; + } +#elif defined(__APPLE_QD__) + if ( ip->xid == fl_window && !parent() ) + fl_window = 0; +#elif defined(__APPLE_QUARTZ__) + Fl_X::q_release_context(ip); + if ( ip->xid == fl_window && !parent() ) + fl_window = 0; +#endif + + if (ip->region) XDestroyRegion(ip->region); + +#ifdef WIN32 + // this little trickery seems to avoid the popup window stacking problem + HWND p = GetForegroundWindow(); + if (p==GetParent(ip->xid)) { + ShowWindow(ip->xid, SW_HIDE); + ShowWindow(p, SW_SHOWNA); + } + XDestroyWindow(fl_display, ip->xid); +#elif defined(__APPLE_QD__) + MacDestroyWindow(this, ip->xid); +#elif defined(__APPLE_QUARTZ__) + MacDestroyWindow(this, ip->xid); +#else +# if USE_XFT + fl_destroy_xft_draw(ip->xid); +# endif + XDestroyWindow(fl_display, ip->xid); +#endif + +#ifdef WIN32 + // Try to stop the annoying "raise another program" behavior + if (non_modal() && Fl::first_window() && Fl::first_window()->shown()) + Fl::first_window()->show(); +#endif + delete ip; +} + +Fl_Window::~Fl_Window() { + hide(); +} + +// FL_SHOW and FL_HIDE are called whenever the visibility of this widget +// or any parent changes. We must correctly map/unmap the system's window. + +// For top-level windows it is assummed the window has already been +// mapped or unmapped!!! This is because this should only happen when +// Fl_Window::show() or Fl_Window::hide() is called, or in response to +// iconize/deiconize events from the system. + +int Fl_Window::handle(int ev) +{ + if (parent()) { + switch (ev) { + case FL_SHOW: + if (!shown()) show(); + else { +#ifdef __APPLE_QD__ + MacMapWindow(this, fl_xid(this)); +#elif defined(__APPLE_QUARTZ__) + MacMapWindow(this, fl_xid(this)); +#else + XMapWindow(fl_display, fl_xid(this)); // extra map calls are harmless +#endif // __APPLE__ + } + break; + case FL_HIDE: + if (shown()) { + // Find what really turned invisible, if is was a parent window + // we do nothing. We need to avoid unnecessary unmap calls + // because they cause the display to blink when the parent is + // remapped. However if this or any intermediate non-window + // widget has really had hide() called directly on it, we must + // unmap because when the parent window is remapped we don't + // want to reappear. + if (visible()) { + Fl_Widget* p = parent(); for (;p->visible();p = p->parent()) {} + if (p->type() >= FL_WINDOW) break; // don't do the unmap + } +#ifdef __APPLE_QD__ + MacUnmapWindow(this, fl_xid(this)); +#elif defined(__APPLE_QUARTZ__) + MacUnmapWindow(this, fl_xid(this)); +#else + XUnmapWindow(fl_display, fl_xid(this)); +#endif // __APPLE__ + } + break; + } +// } else if (ev == FL_FOCUS || ev == FL_UNFOCUS) { +// Fl_Tooltip::exit(Fl_Tooltip::current()); + } + + return Fl_Group::handle(ev); +} + +//////////////////////////////////////////////////////////////// +// Back compatability cut & paste functions for fltk 1.1 only: + +void Fl::selection_owner(Fl_Widget *owner) {selection_owner_ = owner;} + +void Fl::selection(Fl_Widget &owner, const char* text, int len) { + selection_owner_ = &owner; + Fl::copy(text, len, 0); +} + +void Fl::paste(Fl_Widget &receiver) { + Fl::paste(receiver, 0); +} + +//////////////////////////////////////////////////////////////// + +#include + +void Fl_Widget::redraw() { + damage(FL_DAMAGE_ALL); +} + +void Fl_Widget::redraw_label() { + if (window()) { + if (box() == FL_NO_BOX) { + // Widgets with the FL_NO_BOX boxtype need a parent to + // redraw, since it is responsible for redrawing the + // background... + int X = x() > 0 ? x() - 1 : 0; + int Y = y() > 0 ? y() - 1 : 0; + window()->damage(FL_DAMAGE_ALL, X, Y, w() + 2, h() + 2); + } + + if (align() && !(align() & FL_ALIGN_INSIDE) && window()->shown()) { + // If the label is not inside the widget, compute the location of + // the label and redraw the window within that bounding box... + int W = 0, H = 0; + label_.measure(W, H); + W += 5; // Add a little to the size of the label to cover overflow + H += 5; + + if (align() & FL_ALIGN_BOTTOM) { + window()->damage(FL_DAMAGE_EXPOSE, x(), y() + h(), w(), H); + } else if (align() & FL_ALIGN_TOP) { + window()->damage(FL_DAMAGE_EXPOSE, x(), y() - H, w(), H); + } else if (align() & FL_ALIGN_LEFT) { + window()->damage(FL_DAMAGE_EXPOSE, x() - W, y(), W, h()); + } else if (align() & FL_ALIGN_RIGHT) { + window()->damage(FL_DAMAGE_EXPOSE, x() + w(), y(), W, h()); + } else { + window()->damage(FL_DAMAGE_ALL); + } + } else { + // The label is inside the widget, so just redraw the widget itself... + damage(FL_DAMAGE_ALL); + } + } +} + +void Fl_Widget::damage(uchar fl) { + if (type() < FL_WINDOW) { + // damage only the rectangle covered by a child widget: + damage(fl, x(), y(), w(), h()); + } else { + // damage entire window by deleting the region: + Fl_X* i = Fl_X::i((Fl_Window*)this); + if (!i) return; // window not mapped, so ignore it + if (i->region) {XDestroyRegion(i->region); i->region = 0;} + damage_ |= fl; + Fl::damage(FL_DAMAGE_CHILD); + } +} + +void Fl_Widget::damage(uchar fl, int X, int Y, int W, int H) { + Fl_Widget* wi = this; + // mark all parent widgets between this and window with FL_DAMAGE_CHILD: + while (wi->type() < FL_WINDOW) { + wi->damage_ |= fl; + wi = wi->parent(); + if (!wi) return; + fl = FL_DAMAGE_CHILD; + } + Fl_X* i = Fl_X::i((Fl_Window*)wi); + if (!i) return; // window not mapped, so ignore it + + // clip the damage to the window and quit if none: + if (X < 0) {W += X; X = 0;} + if (Y < 0) {H += Y; Y = 0;} + if (W > wi->w()-X) W = wi->w()-X; + if (H > wi->h()-Y) H = wi->h()-Y; + if (W <= 0 || H <= 0) return; + + if (!X && !Y && W==wi->w() && H==wi->h()) { + // if damage covers entire window delete region: + wi->damage(fl); + return; + } + + if (wi->damage()) { + // if we already have damage we must merge with existing region: + if (i->region) { +#ifdef WIN32 + Fl_Region R = XRectangleRegion(X, Y, W, H); + CombineRgn(i->region, i->region, R, RGN_OR); + XDestroyRegion(R); +#elif defined(__APPLE_QD__) + Fl_Region R = NewRgn(); + SetRectRgn(R, X, Y, X+W, Y+H); + UnionRgn(R, i->region, i->region); + DisposeRgn(R); +#elif defined(__APPLE_QUARTZ__) + Fl_Region R = NewRgn(); + SetRectRgn(R, X, Y, X+W, Y+H); + UnionRgn(R, i->region, i->region); + DisposeRgn(R); +#else + XRectangle R; + R.x = X; R.y = Y; R.width = W; R.height = H; + XUnionRectWithRegion(&R, i->region, i->region); +#endif + } + wi->damage_ |= fl; + } else { + // create a new region: + if (i->region) XDestroyRegion(i->region); + i->region = XRectangleRegion(X,Y,W,H); + wi->damage_ = fl; + } + Fl::damage(FL_DAMAGE_CHILD); +} + +void Fl_Window::flush() { + make_current(); +//if (damage() == FL_DAMAGE_EXPOSE && can_boxcheat(box())) fl_boxcheat = this; + fl_clip_region(i->region); i->region = 0; + draw(); +} + +#ifdef WIN32 +# include "Fl_win32.cxx" +#elif defined(__APPLE__) +# include "Fl_mac.cxx" +#endif + +// +// The following methods allow callbacks to schedule the deletion of +// widgets at "safe" times. +// + +static int num_dwidgets = 0, alloc_dwidgets = 0; +static Fl_Widget **dwidgets = 0; + +void +Fl::delete_widget(Fl_Widget *wi) { + if (!wi) return; + + if (num_dwidgets >= alloc_dwidgets) { + Fl_Widget **temp; + + temp = new Fl_Widget *[alloc_dwidgets + 10]; + if (alloc_dwidgets) { + memcpy(temp, dwidgets, alloc_dwidgets * sizeof(Fl_Widget *)); + delete[] dwidgets; + } + + dwidgets = temp; + alloc_dwidgets += 10; + } + + dwidgets[num_dwidgets] = wi; + num_dwidgets ++; +} + + +void +Fl::do_widget_deletion() { + if (!num_dwidgets) return; + + for (int i = 0; i < num_dwidgets; i ++) + delete dwidgets[i]; + + num_dwidgets = 0; +} + +static Fl_Widget ***widget_watch = 0; +static int num_widget_watch = 0; +static int max_widget_watch = 0; + +void Fl::watch_widget_pointer(Fl_Widget *&w) +{ + Fl_Widget **wp = &w; + int i; + for (i=0; i +#include +#include +#include + +#include "fastarrow.h" +static Fl_Bitmap fastarrow(fastarrow_bits, fastarrow_width, fastarrow_height); +#include "mediumarrow.h" +static Fl_Bitmap mediumarrow(mediumarrow_bits, mediumarrow_width, mediumarrow_height); +#include "slowarrow.h" +static Fl_Bitmap slowarrow(slowarrow_bits, slowarrow_width, slowarrow_height); + +// changing the value does not change the appearance: +void Fl_Adjuster::value_damage() {} + +void Fl_Adjuster::draw() { + int dx, dy, W, H; + if (w()>=h()) { + dx = W = w()/3; + dy = 0; H = h(); + } else { + dx = 0; W = w(); + dy = H = h()/3; + } + draw_box(drag==1?FL_DOWN_BOX:box(), x(), y()+2*dy, W, H, color()); + draw_box(drag==2?FL_DOWN_BOX:box(), x()+dx, y()+dy, W, H, color()); + draw_box(drag==3?FL_DOWN_BOX:box(), x()+2*dx, y(), W, H, color()); + if (active_r()) + fl_color(selection_color()); + else + fl_color(fl_inactive(selection_color())); + fastarrow.draw(x()+(W-fastarrow_width)/2, + y()+2*dy+(H-fastarrow_height)/2, W, H); + mediumarrow.draw(x()+dx+(W-mediumarrow_width)/2, + y()+dy+(H-mediumarrow_height)/2, W, H); + slowarrow.draw(x()+2*dx+(W-slowarrow_width)/2, + y()+(H-slowarrow_width)/2, W, H); + if (Fl::focus() == this) draw_focus(); +} + +int Fl_Adjuster::handle(int event) { + double v; + int delta; + int mx = Fl::event_x(); + switch (event) { + case FL_PUSH: + if (Fl::visible_focus()) Fl::focus(this); + ix = mx; + if (w()>=h()) + drag = 3*(mx-x())/w() + 1; + else + drag = 3-3*(Fl::event_y()-y()-1)/h(); + handle_push(); + redraw(); + return 1; + case FL_DRAG: + if (w() >= h()) { + delta = x()+(drag-1)*w()/3; // left edge of button + if (mx < delta) + delta = mx-delta; + else if (mx > (delta+w()/3)) // right edge of button + delta = mx-delta-w()/3; + else + delta = 0; + } else { + if (mx < x()) + delta = mx-x(); + else if (mx > (x()+w())) + delta = mx-x()-w(); + else + delta = 0; + } + switch (drag) { + case 3: v = increment(previous_value(), delta); break; + case 2: v = increment(previous_value(), delta*10); break; + default:v = increment(previous_value(), delta*100); break; + } + handle_drag(soft() ? softclamp(v) : clamp(v)); + return 1; + case FL_RELEASE: + if (Fl::event_is_click()) { // detect click but no drag + if (Fl::event_state()&0xF0000) delta = -10; + else delta = 10; + switch (drag) { + case 3: v = increment(previous_value(), delta); break; + case 2: v = increment(previous_value(), delta*10); break; + default:v = increment(previous_value(), delta*100); break; + } + handle_drag(soft() ? softclamp(v) : clamp(v)); + } + drag = 0; + redraw(); + handle_release(); + return 1; + case FL_KEYBOARD : + switch (Fl::event_key()) { + case FL_Up: + if (w() > h()) return 0; + handle_drag(clamp(increment(value(),-1))); + return 1; + case FL_Down: + if (w() > h()) return 0; + handle_drag(clamp(increment(value(),1))); + return 1; + case FL_Left: + if (w() < h()) return 0; + handle_drag(clamp(increment(value(),-1))); + return 1; + case FL_Right: + if (w() < h()) return 0; + handle_drag(clamp(increment(value(),1))); + return 1; + default: + return 0; + } + // break not required because of switch... + + case FL_FOCUS: + case FL_UNFOCUS: + if (Fl::visible_focus()) { + redraw(); + return 1; + } else return 0; + + case FL_ENTER : + case FL_LEAVE : + return 1; + } + return 0; +} + +Fl_Adjuster::Fl_Adjuster(int X, int Y, int W, int H, const char* l) + : Fl_Valuator(X, Y, W, H, l) { + box(FL_UP_BOX); + step(1, 10000); + selection_color(FL_SELECTION_COLOR); + drag = 0; + soft_ = 1; +} + +// +// End of "$Id: Fl_Adjuster.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Bitmap.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Bitmap.cxx new file mode 100644 index 000000000..407081d55 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Bitmap.cxx @@ -0,0 +1,518 @@ +// +// "$Id: Fl_Bitmap.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Bitmap drawing routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include +#include +#include +#include "flstring.h" + +#ifdef __APPLE_QD__ // MacOS bitmask functions +Fl_Bitmask fl_create_bitmask(int w, int h, const uchar *array) { + Rect srcRect; + srcRect.left = 0; srcRect.right = w; + srcRect.top = 0; srcRect.bottom = h; + GrafPtr savePort; + + GetPort(&savePort); // remember the current port + + Fl_Bitmask gw; + NewGWorld( &gw, 1, &srcRect, 0L, 0L, 0 ); + PixMapHandle pm = GetGWorldPixMap( gw ); + if ( pm ) + { + LockPixels( pm ); + if ( *pm ) + { + uchar *base = (uchar*)GetPixBaseAddr( pm ); + if ( base ) + { + PixMapPtr pmp = *pm; + // verify the parameters for direct memory write + if ( pmp->pixelType == 0 || pmp->pixelSize == 1 || pmp->cmpCount == 1 || pmp->cmpSize == 1 ) + { + static uchar reverse[16] = /* Bit reversal lookup table */ + { 0x00, 0x88, 0x44, 0xcc, 0x22, 0xaa, 0x66, 0xee, 0x11, 0x99, 0x55, 0xdd, 0x33, 0xbb, 0x77, 0xff }; + uchar *dst = base; + const uchar *src = array; + int rowBytesSrc = (w+7)>>3 ; + int rowPatch = (pmp->rowBytes&0x3fff) - rowBytesSrc; + for ( int j=0; j> 4) & 0x0f] & 0x0f); + } + } + UnlockPixels( pm ); + } + } + + SetPort(savePort); + return gw; /* tell caller we succeeded! */ +} + +void fl_delete_bitmask(Fl_Bitmask id) { + if (id) DisposeGWorld(id); +} +#elif defined(__APPLE_QUARTZ__) +Fl_Bitmask fl_create_bitmask(int w, int h, const uchar *array) { + static uchar reverse[16] = /* Bit reversal lookup table */ + { 0x00, 0x88, 0x44, 0xcc, 0x22, 0xaa, 0x66, 0xee, + 0x11, 0x99, 0x55, 0xdd, 0x33, 0xbb, 0x77, 0xff }; + int rowBytes = (w+7)>>3 ; + uchar *bmask = (uchar*)malloc(rowBytes*h), *dst = bmask; + const uchar *src = array; + for ( int i=rowBytes*h; i>0; i--,src++ ) { + *dst++ = ((reverse[*src & 0x0f] & 0xf0) | (reverse[(*src >> 4) & 0x0f] & 0x0f))^0xff; + } + CGDataProviderRef srcp = CGDataProviderCreateWithData( 0L, bmask, rowBytes*h, 0L); + CGImageRef id = CGImageMaskCreate( w, h, 1, 1, rowBytes, srcp, 0L, false); + CGDataProviderRelease(srcp); + return (Fl_Bitmask)id; +} +void fl_delete_bitmask(Fl_Bitmask id) { + if (id) CGImageRelease((CGImageRef)id); +} +#elif defined(WIN32) // Windows bitmask functions... +// 'fl_create_bitmap()' - Create a 1-bit bitmap for drawing... +static Fl_Bitmask fl_create_bitmap(int w, int h, const uchar *data) { + // we need to pad the lines out to words & swap the bits + // in each byte. + int w1 = (w+7)/8; + int w2 = ((w+15)/16)*2; + uchar* newarray = new uchar[w2*h]; + const uchar* src = data; + uchar* dest = newarray; + Fl_Bitmask id; + static uchar reverse[16] = /* Bit reversal lookup table */ + { 0x00, 0x88, 0x44, 0xcc, 0x22, 0xaa, 0x66, 0xee, + 0x11, 0x99, 0x55, 0xdd, 0x33, 0xbb, 0x77, 0xff }; + + for (int y=0; y < h; y++) { + for (int n = 0; n < w1; n++, src++) + *dest++ = (uchar)((reverse[*src & 0x0f] & 0xf0) | + (reverse[(*src >> 4) & 0x0f] & 0x0f)); + dest += w2-w1; + } + + id = CreateBitmap(w, h, 1, 1, newarray); + + delete[] newarray; + + return id; +} + +// 'fl_create_bitmask()' - Create an N-bit bitmap for masking... +Fl_Bitmask fl_create_bitmask(int w, int h, const uchar *data) { + // this won't work when the user changes display mode during run or + // has two screens with differnet depths + Fl_Bitmask id; + static uchar hiNibble[16] = + { 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, + 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0 }; + static uchar loNibble[16] = + { 0x00, 0x08, 0x04, 0x0c, 0x02, 0x0a, 0x06, 0x0e, + 0x01, 0x09, 0x05, 0x0d, 0x03, 0x0b, 0x07, 0x0f }; + int np = GetDeviceCaps(fl_gc, PLANES); //: was always one on sample machines + int bpp = GetDeviceCaps(fl_gc, BITSPIXEL);//: 1,4,8,16,24,32 and more odd stuff? + int Bpr = (bpp*w+7)/8; //: bytes per row + int pad = Bpr&1, w1 = (w+7)/8, shr = ((w-1)&7)+1; + if (bpp==4) shr = (shr+1)/2; + uchar *newarray = new uchar[(Bpr+pad)*h]; + uchar *dst = newarray; + const uchar *src = data; + + for (int i=0; i0; j--) { + uchar b = *src++; + if (bpp==1) { + *dst++ = (uchar)( hiNibble[b&15] ) | ( loNibble[(b>>4)&15] ); + } else if (bpp==4) { + for (int k=(j==1)?shr:4; k>0; k--) { + *dst++ = (uchar)("\377\360\017\000"[b&3]); + b = b >> 2; + } + } else { + for (int k=(j==1)?shr:8; k>0; k--) { + if (b&1) { + *dst++=0; + if (bpp>8) *dst++=0; + if (bpp>16) *dst++=0; + if (bpp>24) *dst++=0; + } else { + *dst++=0xff; + if (bpp>8) *dst++=0xff; + if (bpp>16) *dst++=0xff; + if (bpp>24) *dst++=0xff; + } + + b = b >> 1; + } + } + } + + dst += pad; + } + + id = CreateBitmap(w, h, np, bpp, newarray); + delete[] newarray; + + return id; +} + +#if 0 // This doesn't appear to be used anywhere... +Fl_Bitmask fl_create_bitmask(int w, int h, const uchar *data, int for_mask) { + // we need to pad the lines out to words & swap the bits + // in each byte. + int w1 = (w+7)/8; + int w2 = ((w+15)/16)*2; + uchar* newarray = new uchar[w2*h]; + const uchar* src = data; + uchar* dest = newarray; + Fl_Bitmask id; + static uchar reverse[16] = /* Bit reversal lookup table */ + { 0x00, 0x88, 0x44, 0xcc, 0x22, 0xaa, 0x66, 0xee, + 0x11, 0x99, 0x55, 0xdd, 0x33, 0xbb, 0x77, 0xff }; + + for (int y=0; y < h; y++) { + for (int n = 0; n < w1; n++, src++) + *dest++ = (reverse[*src & 0x0f] & 0xf0) | + (reverse[(*src >> 4) & 0x0f] & 0x0f); + dest += w2-w1; + } + + id = CreateBitmap(w, h, 1, 1, newarray); + + delete[] newarray; + + return (id); +} +# endif // 0 + +void fl_delete_bitmask(Fl_Bitmask bm) { + DeleteObject((HGDIOBJ)bm); +} +#else // X11 bitmask functions +Fl_Bitmask fl_create_bitmask(int w, int h, const uchar *data) { + return XCreateBitmapFromData(fl_display, fl_window, (const char *)data, + (w+7)&-8, h); +} + +void fl_delete_bitmask(Fl_Bitmask bm) { + fl_delete_offscreen((Fl_Offscreen)bm); +} +#endif // __APPLE__ + + +// MRS: Currently it appears that CopyDeepMask() does not work with an 8-bit alpha mask. +// If you want to test/fix this, uncomment the "#ifdef __APPLE__" and comment out +// the "#if 0" here. Also see Fl_Image.cxx for a similar check... + +//#ifdef __APPLE_QD__ +#if 0 +// Create an 8-bit mask used for alpha blending +Fl_Bitmask fl_create_alphamask(int w, int h, int d, int ld, const uchar *array) { + Rect srcRect; + srcRect.left = 0; srcRect.right = w; + srcRect.top = 0; srcRect.bottom = h; + GrafPtr savePort; + + GetPort(&savePort); // remember the current port + + Fl_Bitmask gw; + NewGWorld( &gw, 8, &srcRect, 0L, 0L, 0 ); + PixMapHandle pm = GetGWorldPixMap( gw ); + if ( pm ) + { + LockPixels( pm ); + if ( *pm ) + { + uchar *base = (uchar*)GetPixBaseAddr( pm ); + if ( base ) + { + PixMapPtr pmp = *pm; + // verify the parameters for direct memory write + if ( pmp->pixelType == 0 || pmp->pixelSize == 8 || pmp->cmpCount == 1 || pmp->cmpSize == 8 ) + { + // Copy alpha values from the source array to the pixmap... + array += d - 1; + int rowoffset = (pmp->rowBytes & 0x3fff) - w; + for (int y = h; y > 0; y --, array += ld, base += rowoffset) { + for (int x = w; x > 0; x --, array += d) { + *base++ = 255 /*255 - *array*/; + } + } + } + } + UnlockPixels( pm ); + } + } + + SetPort(savePort); + return gw; /* tell caller we succeeded! */ +} +#else +// Create a 1-bit mask used for alpha blending +Fl_Bitmask fl_create_alphamask(int w, int h, int d, int ld, const uchar *array) { + Fl_Bitmask mask; + int bmw = (w + 7) / 8; + uchar *bitmap = new uchar[bmw * h]; + uchar *bitptr, bit; + const uchar *dataptr; + int x, y; + static uchar dither[16][16] = { // Simple 16x16 Floyd dither + { 0, 128, 32, 160, 8, 136, 40, 168, + 2, 130, 34, 162, 10, 138, 42, 170 }, + { 192, 64, 224, 96, 200, 72, 232, 104, + 194, 66, 226, 98, 202, 74, 234, 106 }, + { 48, 176, 16, 144, 56, 184, 24, 152, + 50, 178, 18, 146, 58, 186, 26, 154 }, + { 240, 112, 208, 80, 248, 120, 216, 88, + 242, 114, 210, 82, 250, 122, 218, 90 }, + { 12, 140, 44, 172, 4, 132, 36, 164, + 14, 142, 46, 174, 6, 134, 38, 166 }, + { 204, 76, 236, 108, 196, 68, 228, 100, + 206, 78, 238, 110, 198, 70, 230, 102 }, + { 60, 188, 28, 156, 52, 180, 20, 148, + 62, 190, 30, 158, 54, 182, 22, 150 }, + { 252, 124, 220, 92, 244, 116, 212, 84, + 254, 126, 222, 94, 246, 118, 214, 86 }, + { 3, 131, 35, 163, 11, 139, 43, 171, + 1, 129, 33, 161, 9, 137, 41, 169 }, + { 195, 67, 227, 99, 203, 75, 235, 107, + 193, 65, 225, 97, 201, 73, 233, 105 }, + { 51, 179, 19, 147, 59, 187, 27, 155, + 49, 177, 17, 145, 57, 185, 25, 153 }, + { 243, 115, 211, 83, 251, 123, 219, 91, + 241, 113, 209, 81, 249, 121, 217, 89 }, + { 15, 143, 47, 175, 7, 135, 39, 167, + 13, 141, 45, 173, 5, 133, 37, 165 }, + { 207, 79, 239, 111, 199, 71, 231, 103, + 205, 77, 237, 109, 197, 69, 229, 101 }, + { 63, 191, 31, 159, 55, 183, 23, 151, + 61, 189, 29, 157, 53, 181, 21, 149 }, + { 254, 127, 223, 95, 247, 119, 215, 87, + 253, 125, 221, 93, 245, 117, 213, 85 } + }; + + // Generate a 1-bit "screen door" alpha mask; not always pretty, but + // definitely fast... In the future we may be able to support things + // like the RENDER extension in XFree86, when available, to provide + // true RGBA-blended rendering. See: + // + // http://www.xfree86.org/~keithp/render/protocol.html + // + // for more info on XRender... + // + // MacOS already provides alpha blending support and has its own + // fl_create_alphamask() function... + memset(bitmap, 0, bmw * h); + + for (dataptr = array + d - 1, y = 0; y < h; y ++, dataptr += ld) + for (bitptr = bitmap + y * bmw, bit = 1, x = 0; x < w; x ++, dataptr += d) { + if (*dataptr > dither[x & 15][y & 15]) + *bitptr |= bit; + if (bit < 128) bit <<= 1; + else { + bit = 1; + bitptr ++; + } + } + + mask = fl_create_bitmask(w, h, bitmap); + delete[] bitmap; + + return (mask); +} +#endif // __APPLE__ + +void Fl_Bitmap::draw(int XP, int YP, int WP, int HP, int cx, int cy) { + if (!array) { + draw_empty(XP, YP); + return; + } + + // account for current clip region (faster on Irix): + int X,Y,W,H; fl_clip_box(XP,YP,WP,HP,X,Y,W,H); + cx += X-XP; cy += Y-YP; + // clip the box down to the size of image, quit if empty: + if (cx < 0) {W += cx; X -= cx; cx = 0;} + if ((cx+W) > w()) W = w()-cx; + if (W <= 0) return; + if (cy < 0) {H += cy; Y -= cy; cy = 0;} + if ((cy+H) > h()) H = h()-cy; + if (H <= 0) return; +#ifdef WIN32 + if (!id) id = fl_create_bitmap(w(), h(), array); + + HDC tempdc = CreateCompatibleDC(fl_gc); + int save = SaveDC(tempdc); + SelectObject(tempdc, (HGDIOBJ)id); + SelectObject(fl_gc, fl_brush()); + // secret bitblt code found in old MSWindows reference manual: + BitBlt(fl_gc, X, Y, W, H, tempdc, cx, cy, 0xE20746L); + RestoreDC(tempdc, save); + DeleteDC(tempdc); +#elif defined(__APPLE_QD__) + if (!id) id = fl_create_bitmask(w(), h(), array); + GrafPtr dstPort; + GetPort( &dstPort ); + Rect src, dst; + GetPortBounds( (Fl_Offscreen)id, &src ); + SetRect( &src, cx, cy, cx+W, cy+H ); + SetRect( &dst, X, Y, X+W, Y+H ); + CopyBits(GetPortBitMapForCopyBits((Fl_Offscreen)id), // srcBits + GetPortBitMapForCopyBits(dstPort), // dstBits + &src, // src bounds + &dst, // dst bounds + srcOr, // mode + 0L); // mask region +#elif defined(__APPLE_QUARTZ__) + if (!id) id = fl_create_bitmask(w(), h(), array); + if (id && fl_gc) { + CGRect rect = { { X, Y }, { W, H } }; + Fl_X::q_begin_image(rect, cx, cy, w(), h()); + CGContextDrawImage(fl_gc, rect, (CGImageRef)id); + Fl_X::q_end_image(); + } +#else + if (!id) id = fl_create_bitmask(w(), h(), array); + + XSetStipple(fl_display, fl_gc, id); + int ox = X-cx; if (ox < 0) ox += w(); + int oy = Y-cy; if (oy < 0) oy += h(); + XSetTSOrigin(fl_display, fl_gc, ox, oy); + XSetFillStyle(fl_display, fl_gc, FillStippled); + XFillRectangle(fl_display, fl_window, fl_gc, X, Y, W, H); + XSetFillStyle(fl_display, fl_gc, FillSolid); +#endif +} + +Fl_Bitmap::~Fl_Bitmap() { + uncache(); + if (alloc_array) delete[] (uchar *)array; +} + +void Fl_Bitmap::uncache() { + if (id) { + fl_delete_bitmask((Fl_Offscreen)id); + id = 0; + } +} + +void Fl_Bitmap::label(Fl_Widget* widget) { + widget->image(this); +} + +void Fl_Bitmap::label(Fl_Menu_Item* m) { + Fl::set_labeltype(_FL_IMAGE_LABEL, labeltype, measure); + m->label(_FL_IMAGE_LABEL, (const char*)this); +} + +Fl_Image *Fl_Bitmap::copy(int W, int H) { + Fl_Bitmap *new_image; // New RGB image + uchar *new_array; // New array for image data + + // Optimize the simple copy where the width and height are the same... + if (W == w() && H == h()) { + new_array = new uchar [H * ((W + 7) / 8)]; + memcpy(new_array, array, H * ((W + 7) / 8)); + + new_image = new Fl_Bitmap(new_array, W, H); + new_image->alloc_array = 1; + + return new_image; + } + if (W <= 0 || H <= 0) return 0; + + // OK, need to resize the image data; allocate memory and + uchar *new_ptr, // Pointer into new array + new_bit, // Bit for new array + old_bit; // Bit for old array + const uchar *old_ptr; // Pointer into old array + int sx, sy, // Source coordinates + dx, dy, // Destination coordinates + xerr, yerr, // X & Y errors + xmod, ymod, // X & Y moduli + xstep, ystep; // X & Y step increments + + + // Figure out Bresenheim step/modulus values... + xmod = w() % W; + xstep = w() / W; + ymod = h() % H; + ystep = h() / H; + + // Allocate memory for the new image... + new_array = new uchar [H * ((W + 7) / 8)]; + new_image = new Fl_Bitmap(new_array, W, H); + new_image->alloc_array = 1; + + memset(new_array, 0, H * ((W + 7) / 8)); + + // Scale the image using a nearest-neighbor algorithm... + for (dy = H, sy = 0, yerr = H, new_ptr = new_array; dy > 0; dy --) { + for (dx = W, xerr = W, old_ptr = array + sy * ((w() + 7) / 8), sx = 0, new_bit = 1; + dx > 0; + dx --) { + old_bit = (uchar)(1 << (sx & 7)); + if (old_ptr[sx / 8] & old_bit) *new_ptr |= new_bit; + + if (new_bit < 128) new_bit <<= 1; + else { + new_bit = 1; + new_ptr ++; + } + + sx += xstep; + xerr -= xmod; + + if (xerr <= 0) { + xerr += W; + sx ++; + } + } + + if (new_bit > 1) new_ptr ++; + + sy += ystep; + yerr -= ymod; + if (yerr <= 0) { + yerr += H; + sy ++; + } + } + + return new_image; +} + + +// +// End of "$Id: Fl_Bitmap.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Box.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Box.cxx new file mode 100644 index 000000000..34b63d7e1 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Box.cxx @@ -0,0 +1,44 @@ +// +// "$Id: Fl_Box.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Box widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include + +void Fl_Box::draw() { + draw_box(); + draw_label(); +} + +int Fl_Box::handle(int event) { + if (event == FL_ENTER || event == FL_LEAVE) return 1; + else return 0; +} + + +// +// End of "$Id: Fl_Box.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Browser.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Browser.cxx new file mode 100644 index 000000000..b0006d698 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Browser.cxx @@ -0,0 +1,551 @@ +// +// "$Id: Fl_Browser.cxx 5987 2007-11-20 21:57:17Z mike $" +// +// Browser widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2007 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include "flstring.h" +#include +#include + +// I modified this from the original Forms data to use a linked list +// so that the number of items in the browser and size of those items +// is unlimited. The only problem is that the old browser used an +// index number to identify a line, and it is slow to convert from/to +// a pointer. I use a cache of the last match to try to speed this +// up. + +// Also added the ability to "hide" a line. This set's it's height to +// zero, so the Fl_Browser_ cannot pick it. + +#define SELECTED 1 +#define NOTDISPLAYED 2 + +struct FL_BLINE { // data is in a linked list of these + FL_BLINE* prev; + FL_BLINE* next; + void* data; + short length; // sizeof(txt)-1, may be longer than string + char flags; // selected, displayed + char txt[1]; // start of allocated array +}; + +void* Fl_Browser::item_first() const {return first;} + +void* Fl_Browser::item_next(void* l) const {return ((FL_BLINE*)l)->next;} + +void* Fl_Browser::item_prev(void* l) const {return ((FL_BLINE*)l)->prev;} + +int Fl_Browser::item_selected(void* l) const { + return ((FL_BLINE*)l)->flags&SELECTED;} + +void Fl_Browser::item_select(void* l, int v) { + if (v) ((FL_BLINE*)l)->flags |= SELECTED; + else ((FL_BLINE*)l)->flags &= ~SELECTED; +} + +FL_BLINE* Fl_Browser::find_line(int line) const { + int n; FL_BLINE* l; + if (line == cacheline) return cache; + if (cacheline && line > (cacheline/2) && line < ((cacheline+lines)/2)) { + n = cacheline; l = cache; + } else if (line <= (lines/2)) { + n = 1; l = first; + } else { + n = lines; l = last; + } + for (; n < line && l; n++) l = l->next; + for (; n > line && l; n--) l = l->prev; + ((Fl_Browser*)this)->cacheline = line; + ((Fl_Browser*)this)->cache = l; + return l; +} + +int Fl_Browser::lineno(void* v) const { + FL_BLINE* l = (FL_BLINE*)v; + if (!l) return 0; + if (l == cache) return cacheline; + if (l == first) return 1; + if (l == last) return lines; + if (!cache) { + ((Fl_Browser*)this)->cache = first; + ((Fl_Browser*)this)->cacheline = 1; + } + // assumme it is near cache, search both directions: + FL_BLINE* b = cache->prev; + int bnum = cacheline-1; + FL_BLINE* f = cache->next; + int fnum = cacheline+1; + int n = 0; + for (;;) { + if (b == l) {n = bnum; break;} + if (f == l) {n = fnum; break;} + if (b) {b = b->prev; bnum--;} + if (f) {f = f->next; fnum++;} + } + ((Fl_Browser*)this)->cache = l; + ((Fl_Browser*)this)->cacheline = n; + return n; +} + +FL_BLINE* Fl_Browser::_remove(int line) { + FL_BLINE* ttt = find_line(line); + deleting(ttt); + + cacheline = line-1; + cache = ttt->prev; + lines--; + full_height_ -= item_height(ttt); + if (ttt->prev) ttt->prev->next = ttt->next; + else first = ttt->next; + if (ttt->next) ttt->next->prev = ttt->prev; + else last = ttt->prev; + + return(ttt); +} + +void Fl_Browser::remove(int line) { + if (line < 1 || line > lines) return; + free(_remove(line)); +} + +void Fl_Browser::insert(int line, FL_BLINE* t) { + if (!first) { + t->prev = t->next = 0; + first = last = t; + } else if (line <= 1) { + inserting(first, t); + t->prev = 0; + t->next = first; + t->next->prev = t; + first = t; + } else if (line > lines) { + t->prev = last; + t->prev->next = t; + t->next = 0; + last = t; + } else { + FL_BLINE* n = find_line(line); + inserting(n, t); + t->next = n; + t->prev = n->prev; + t->prev->next = t; + n->prev = t; + } + cacheline = line; + cache = t; + lines++; + full_height_ += item_height(t); + redraw_line(t); +} + +void Fl_Browser::insert(int line, const char* newtext, void* d) { + int l = strlen(newtext); + FL_BLINE* t = (FL_BLINE*)malloc(sizeof(FL_BLINE)+l); + t->length = (short)l; + t->flags = 0; + strcpy(t->txt, newtext); + t->data = d; + insert(line, t); +} + +void Fl_Browser::move(int to, int from) { + if (from < 1 || from > lines) return; + insert(to, _remove(from)); +} + +void Fl_Browser::text(int line, const char* newtext) { + if (line < 1 || line > lines) return; + FL_BLINE* t = find_line(line); + int l = strlen(newtext); + if (l > t->length) { + FL_BLINE* n = (FL_BLINE*)malloc(sizeof(FL_BLINE)+l); + replacing(t, n); + cache = n; + n->data = t->data; + n->length = (short)l; + n->flags = t->flags; + n->prev = t->prev; + if (n->prev) n->prev->next = n; else first = n; + n->next = t->next; + if (n->next) n->next->prev = n; else last = n; + free(t); + t = n; + } + strcpy(t->txt, newtext); + redraw_line(t); +} + +void Fl_Browser::data(int line, void* d) { + if (line < 1 || line > lines) return; + find_line(line)->data = d; +} + +int Fl_Browser::item_height(void* lv) const { + FL_BLINE* l = (FL_BLINE*)lv; + if (l->flags & NOTDISPLAYED) return 0; + + int hmax = 2; // use 2 to insure we don't return a zero! + + if (!l->txt[0]) { + // For blank lines set the height to exactly 1 line! + fl_font(textfont(), textsize()); + int hh = fl_height(); + if (hh > hmax) hmax = hh; + } + else { + const int* i = column_widths(); + // do each column separately as they may all set different fonts: + for (char* str = l->txt; str && *str; str++) { + Fl_Font font = textfont(); // default font + int tsize = textsize(); // default size + while (*str==format_char()) { + str++; + switch (*str++) { + case 'l': case 'L': tsize = 24; break; + case 'm': case 'M': tsize = 18; break; + case 's': tsize = 11; break; + case 'b': font = (Fl_Font)(font|FL_BOLD); break; + case 'i': font = (Fl_Font)(font|FL_ITALIC); break; + case 'f': case 't': font = FL_COURIER; break; + case 'B': + case 'C': strtol(str, &str, 10); break;// skip a color number + case 'F': font = (Fl_Font)strtol(str,&str,10); break; + case 'S': tsize = strtol(str,&str,10); break; + case 0: case '@': str--; + case '.': goto END_FORMAT; + } + } + END_FORMAT: + char* ptr = str; + if (ptr && *i++) str = strchr(str, column_char()); + else str = NULL; + if((!str && *ptr) || (str && ptr < str)) { + fl_font(font, tsize); int hh = fl_height(); + if (hh > hmax) hmax = hh; + } + if (!str || !*str) break; + } + } + + return hmax; // previous version returned hmax+2! +} + +int Fl_Browser::item_width(void* v) const { + char* str = ((FL_BLINE*)v)->txt; + const int* i = column_widths(); + int ww = 0; + + while (*i) { // add up all tab-seperated fields + char* e; + e = strchr(str, column_char()); + if (!e) break; // last one occupied by text + str = e+1; + ww += *i++; + } + + // OK, we gotta parse the string and find the string width... + int tsize = textsize(); + Fl_Font font = textfont(); + int done = 0; + + while (*str == format_char_ && str[1] && str[1] != format_char_) { + str ++; + switch (*str++) { + case 'l': case 'L': tsize = 24; break; + case 'm': case 'M': tsize = 18; break; + case 's': tsize = 11; break; + case 'b': font = (Fl_Font)(font|FL_BOLD); break; + case 'i': font = (Fl_Font)(font|FL_ITALIC); break; + case 'f': case 't': font = FL_COURIER; break; + case 'B': + case 'C': strtol(str, &str, 10); break;// skip a color number + case 'F': font = (Fl_Font)strtol(str, &str, 10); break; + case 'S': tsize = strtol(str, &str, 10); break; + case '.': + done = 1; + break; + case '@': + str--; + done = 1; + } + + if (done) + break; + } + + if (*str == format_char_ && str[1]) + str ++; + + fl_font(font, tsize); + return ww + int(fl_width(str)) + 6; +} + +int Fl_Browser::full_height() const { + return full_height_; +} + +int Fl_Browser::incr_height() const { + return textsize()+2; +} + +void Fl_Browser::item_draw(void* v, int X, int Y, int W, int H) const { + char* str = ((FL_BLINE*)v)->txt; + const int* i = column_widths(); + + while (W > 6) { // do each tab-seperated field + int w1 = W; // width for this field + char* e = 0; // pointer to end of field or null if none + if (*i) { // find end of field and temporarily replace with 0 + e = strchr(str, column_char()); + if (e) {*e = 0; w1 = *i++;} + } + int tsize = textsize(); + Fl_Font font = textfont(); + Fl_Color lcol = textcolor(); + Fl_Align talign = FL_ALIGN_LEFT; + // check for all the @-lines recognized by XForms: + while (*str == format_char() && *++str && *str != format_char()) { + switch (*str++) { + case 'l': case 'L': tsize = 24; break; + case 'm': case 'M': tsize = 18; break; + case 's': tsize = 11; break; + case 'b': font = (Fl_Font)(font|FL_BOLD); break; + case 'i': font = (Fl_Font)(font|FL_ITALIC); break; + case 'f': case 't': font = FL_COURIER; break; + case 'c': talign = FL_ALIGN_CENTER; break; + case 'r': talign = FL_ALIGN_RIGHT; break; + case 'B': + if (!(((FL_BLINE*)v)->flags & SELECTED)) { + fl_color((Fl_Color)strtol(str, &str, 10)); + fl_rectf(X, Y, w1, H); + } else strtol(str, &str, 10); + break; + case 'C': + lcol = (Fl_Color)strtol(str, &str, 10); + break; + case 'F': + font = (Fl_Font)strtol(str, &str, 10); + break; + case 'N': + lcol = FL_INACTIVE_COLOR; + break; + case 'S': + tsize = strtol(str, &str, 10); + break; + case '-': + fl_color(FL_DARK3); + fl_line(X+3, Y+H/2, X+w1-3, Y+H/2); + fl_color(FL_LIGHT3); + fl_line(X+3, Y+H/2+1, X+w1-3, Y+H/2+1); + break; + case 'u': + case '_': + fl_color(lcol); + fl_line(X+3, Y+H-1, X+w1-3, Y+H-1); + break; + case '.': + goto BREAK; + case '@': + str--; goto BREAK; + } + } + BREAK: + fl_font(font, tsize); + if (((FL_BLINE*)v)->flags & SELECTED) + lcol = fl_contrast(lcol, selection_color()); + if (!active_r()) lcol = fl_inactive(lcol); + fl_color(lcol); + fl_draw(str, X+3, Y, w1-6, H, e ? Fl_Align(talign|FL_ALIGN_CLIP) : talign, 0, 0); + if (!e) break; // no more fields... + *e = column_char(); // put the seperator back + X += w1; + W -= w1; + str = e+1; + } +} + +static const int no_columns[1] = {0}; + +Fl_Browser::Fl_Browser(int X, int Y, int W, int H, const char*l) + : Fl_Browser_(X, Y, W, H, l) { + column_widths_ = no_columns; + lines = 0; + full_height_ = 0; + cacheline = 0; + format_char_ = '@'; + column_char_ = '\t'; + first = last = cache = 0; +} + +void Fl_Browser::lineposition(int line, Fl_Line_Position pos) { + if (line<1) line = 1; + if (line>lines) line = lines; + int p = 0; + + FL_BLINE* l; + for (l=first; l && line>1; l = l->next) { + line--; p += item_height(l); + } + if (l && (pos == BOTTOM)) p += item_height (l); + + int final = p, X, Y, W, H; + bbox(X, Y, W, H); + + switch(pos) { + case TOP: break; + case BOTTOM: final -= H; break; + case MIDDLE: final -= H/2; break; + } + + if (final > (full_height() - H)) final = full_height() -H; + position(final); +} + +int Fl_Browser::topline() const { + return lineno(top()); +} + +void Fl_Browser::clear() { + for (FL_BLINE* l = first; l;) { + FL_BLINE* n = l->next; + free(l); + l = n; + } + full_height_ = 0; + first = 0; + lines = 0; + new_list(); +} + +void Fl_Browser::add(const char* newtext, void* d) { + insert(lines+1, newtext, d); + //Fl_Browser_::display(last); +} + +const char* Fl_Browser::text(int line) const { + if (line < 1 || line > lines) return 0; + return find_line(line)->txt; +} + +void* Fl_Browser::data(int line) const { + if (line < 1 || line > lines) return 0; + return find_line(line)->data; +} + +int Fl_Browser::select(int line, int v) { + if (line < 1 || line > lines) return 0; + return Fl_Browser_::select(find_line(line), v); +} + +int Fl_Browser::selected(int line) const { + if (line < 1 || line > lines) return 0; + return find_line(line)->flags & SELECTED; +} + +void Fl_Browser::show(int line) { + FL_BLINE* t = find_line(line); + if (t->flags & NOTDISPLAYED) { + t->flags &= ~NOTDISPLAYED; + full_height_ += item_height(t); + if (Fl_Browser_::displayed(t)) redraw(); + } +} + +void Fl_Browser::hide(int line) { + FL_BLINE* t = find_line(line); + if (!(t->flags & NOTDISPLAYED)) { + full_height_ -= item_height(t); + t->flags |= NOTDISPLAYED; + if (Fl_Browser_::displayed(t)) redraw(); + } +} + +void Fl_Browser::display(int line, int v) { + if (line < 1 || line > lines) return; + if (v) show(line); else hide(line); +} + +int Fl_Browser::visible(int line) const { + if (line < 1 || line > lines) return 0; + return !(find_line(line)->flags&NOTDISPLAYED); +} + +int Fl_Browser::value() const { + return lineno(selection()); +} + +// SWAP TWO LINES +void Fl_Browser::swap(FL_BLINE *a, FL_BLINE *b) { + + if ( a == b || !a || !b) return; // nothing to do + swapping(a, b); + FL_BLINE *aprev = a->prev; + FL_BLINE *anext = a->next; + FL_BLINE *bprev = b->prev; + FL_BLINE *bnext = b->next; + if ( b->prev == a ) { // A ADJACENT TO B + if ( aprev ) aprev->next = b; else first = b; + b->next = a; + a->next = bnext; + b->prev = aprev; + a->prev = b; + if ( bnext ) bnext->prev = a; else last = a; + } else if ( a->prev == b ) { // B ADJACENT TO A + if ( bprev ) bprev->next = a; else first = a; + a->next = b; + b->next = anext; + a->prev = bprev; + b->prev = a; + if ( anext ) anext->prev = b; else last = b; + } else { // A AND B NOT ADJACENT + // handle prev's + b->prev = aprev; + if ( anext ) anext->prev = b; else last = b; + a->prev = bprev; + if ( bnext ) bnext->prev = a; else last = a; + // handle next's + if ( aprev ) aprev->next = b; else first = b; + b->next = anext; + if ( bprev ) bprev->next = a; else first = a; + a->next = bnext; + } + // Disable cache -- we played around with positions + cacheline = 0; + cache = 0; +} + +void Fl_Browser::swap(int ai, int bi) { + if (ai < 1 || ai > lines || bi < 1 || bi > lines) return; + FL_BLINE* a = find_line(ai); + FL_BLINE* b = find_line(bi); + swap(a,b); +} + +// +// End of "$Id: Fl_Browser.cxx 5987 2007-11-20 21:57:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Browser_.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Browser_.cxx new file mode 100644 index 000000000..5659293cb --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Browser_.cxx @@ -0,0 +1,842 @@ +// +// "$Id: Fl_Browser_.cxx 5992 2007-12-15 16:20:16Z mike $" +// +// Base Browser widget class for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2006 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#define DISPLAY_SEARCH_BOTH_WAYS_AT_ONCE + +#include +#include +#include +#include +#include + + +// This is the base class for browsers. To be useful it must be +// subclassed and several virtual functions defined. The +// Forms-compatable browser and the file chooser's browser are +// subclassed off of this. + +// Yes, I know this should be a template... + +// This has been designed so that the subclass has complete control +// over the storage of the data, although because next() and prev() +// functions are used to index, it works best as a linked list or as a +// large block of characters in which the line breaks must be searched +// for. + +// A great deal of work has been done so that the "height" of a data +// object does not need to be determined until it is drawn. This was +// done for the file chooser, because the height requires doing stat() +// to see if the file is a directory, which can be annoyingly slow +// over the network. + +/* redraw bits: + 1 = redraw children (the scrollbar) + 2 = redraw one or two items + 4 = redraw all items +*/ + +static void scrollbar_callback(Fl_Widget* s, void*) { + ((Fl_Browser_*)(s->parent()))->position(int(((Fl_Scrollbar*)s)->value())); +} + +static void hscrollbar_callback(Fl_Widget* s, void*) { + ((Fl_Browser_*)(s->parent()))->hposition(int(((Fl_Scrollbar*)s)->value())); +} + +// Scrollbar size should be part of the Fl class, but is left here for +// binary compatibility in 1.1.x - M. Sweet +int Fl_Browser_::scrollbar_width_ = 16; + +// Get the standard scrollbar size +int Fl::scrollbar_size() { + return Fl_Browser_::scrollbar_width(); +} + +// Set the standard scrollbar size +void Fl::scrollbar_size(int W) { + Fl_Browser_::scrollbar_width(W); +} + +// return where to draw the actual box: +void Fl_Browser_::bbox(int& X, int& Y, int& W, int& H) const { + Fl_Boxtype b = box() ? box() : FL_DOWN_BOX; + X = x()+Fl::box_dx(b); + Y = y()+Fl::box_dy(b); + W = w()-Fl::box_dw(b); + H = h()-Fl::box_dh(b); + if (scrollbar.visible()) { + W -= scrollbar_width_; + if (scrollbar.align() & FL_ALIGN_LEFT) X += scrollbar_width_; + } + if (W < 0) W = 0; + if (hscrollbar.visible()) { + H -= scrollbar_width_; + if (scrollbar.align() & FL_ALIGN_TOP) Y += scrollbar_width_; + } + if (H < 0) H = 0; +} + +int Fl_Browser_::leftedge() const { + int X, Y, W, H; bbox(X, Y, W, H); + return X; +} + +// The scrollbars may be moved again by draw(), since each one's size +// depends on whether the other is visible or not. This skips over +// Fl_Group::resize since it moves the scrollbars uselessly. +void Fl_Browser_::resize(int X, int Y, int W, int H) { + Fl_Widget::resize(X, Y, W, H); + // move the scrollbars so they can respond to events: + bbox(X,Y,W,H); + scrollbar.resize( + scrollbar.align()&FL_ALIGN_LEFT ? X-scrollbar_width_ : X+W, + Y, scrollbar_width_, H); + hscrollbar.resize( + X, scrollbar.align()&FL_ALIGN_TOP ? Y-scrollbar_width_ : Y+H, + W, scrollbar_width_); +} + +// Cause minimal update to redraw the given item: +void Fl_Browser_::redraw_line(void* l) { + if (!redraw1 || redraw1 == l) {redraw1 = l; damage(FL_DAMAGE_EXPOSE);} + else if (!redraw2 || redraw2 == l) {redraw2 = l; damage(FL_DAMAGE_EXPOSE);} + else damage(FL_DAMAGE_SCROLL); +} + +// Figure out top() based on position(): +void Fl_Browser_::update_top() { + if (!top_) top_ = item_first(); + if (position_ != real_position_) { + void* l; + int ly; + int yy = position_; + // start from either head or current position, whichever is closer: + if (!top_ || yy <= (real_position_/2)) { + l = item_first(); + ly = 0; + } else { + l = top_; + ly = real_position_-offset_; + } + if (!l) { + top_ = 0; + offset_ = 0; + real_position_ = 0; + } else { + int hh = item_quick_height(l); + // step through list until we find line containing this point: + while (ly > yy) { + void* l1 = item_prev(l); + if (!l1) {ly = 0; break;} // hit the top + l = l1; + hh = item_quick_height(l); + ly -= hh; + } + while ((ly+hh) <= yy) { + void* l1 = item_next(l); + if (!l1) {yy = ly+hh-1; break;} + l = l1; + ly += hh; + hh = item_quick_height(l); + } + // top item must *really* be visible, use slow height: + for (;;) { + hh = item_height(l); + if ((ly+hh) > yy) break; // it is big enough to see + // go up to top of previous item: + void* l1 = item_prev(l); + if (!l1) {ly = yy = 0; break;} // hit the top + l = l1; yy = position_ = ly = ly-item_quick_height(l); + } + // use it: + top_ = l; + offset_ = yy-ly; + real_position_ = yy; + } + damage(FL_DAMAGE_SCROLL); + } +} + +// Change position(), top() will update when update_top() is called +// (probably by draw() or handle()): +void Fl_Browser_::position(int yy) { + if (yy < 0) yy = 0; + if (yy == position_) return; + position_ = yy; + if (yy != real_position_) redraw_lines(); +} + +void Fl_Browser_::hposition(int xx) { + if (xx < 0) xx = 0; + if (xx == hposition_) return; + hposition_ = xx; + if (xx != real_hposition_) redraw_lines(); +} + +// Tell whether item is currently displayed: +int Fl_Browser_::displayed(void* p) const { + int X, Y, W, H; bbox(X, Y, W, H); + int yy = H+offset_; + for (void* l = top_; l && yy > 0; l = item_next(l)) { + if (l == p) return 1; + yy -= item_height(l); + } + return 0; +} + +// Ensure this item is displayed: +// Messy because we have no idea if it is before top or after bottom: +void Fl_Browser_::display(void* p) { + + // First special case - want to display first item in the list? + update_top(); + if (p == item_first()) {position(0); return;} + + int X, Y, W, H, Yp; bbox(X, Y, W, H); + void* l = top_; + Y = Yp = -offset_; + int h1; + + // 2nd special case - want to display item already displayed at top of browser? + if (l == p) {position(real_position_+Y); return;} // scroll up a bit + + // 3rd special case - want to display item just above top of browser? + void* lp = item_prev(l); + if (lp == p) {position(real_position_+Y-item_quick_height(lp)); return;} + +#ifdef DISPLAY_SEARCH_BOTH_WAYS_AT_ONCE + // search for item. We search both up and down the list at the same time, + // this evens up the execution time for the two cases - the old way was + // much slower for going up than for going down. + while (l || lp) { + if (l) { + h1 = item_quick_height(l); + if (l == p) { + if (Y <= H) { // it is visible or right at bottom + Y = Y+h1-H; // find where bottom edge is + if (Y > 0) position(real_position_+Y); // scroll down a bit + } else { + position(real_position_+Y-(H-h1)/2); // center it + } + return; + } + Y += h1; + l = item_next(l); + } + if (lp) { + h1 = item_quick_height(lp); + Yp -= h1; + if (lp == p) { + if ((Yp + h1) >= 0) position(real_position_+Yp); + else position(real_position_+Yp-(H-h1)/2); + return; + } + lp = item_prev(lp); + } + } +#else + // Old version went forwards and then backwards: + // search forward for it: + l = top_; + for (; l; l = item_next(l)) { + h1 = item_quick_height(l); + if (l == p) { + if (Y <= H) { // it is visible or right at bottom + Y = Y+h1-H; // find where bottom edge is + if (Y > 0) position(real_position_+Y); // scroll down a bit + } else { + position(real_position_+Y-(H-h1)/2); // center it + } + return; + } + Y += h1; + } + // search backward for it, if found center it: + l = lp; + Y = -offset_; + for (; l; l = item_prev(l)) { + h1 = item_quick_height(l); + Y -= h1; + if (l == p) { + if ((Y + h1) >= 0) position(real_position_+Y); + else position(real_position_+Y-(H-h1)/2); + return; + } + } +#endif +} + +// redraw, has side effect of updating top and setting scrollbar: + +void Fl_Browser_::draw() { + int drawsquare = 0; + update_top(); + int full_width_ = full_width(); + int full_height_ = full_height(); + int X, Y, W, H; bbox(X, Y, W, H); + int dont_repeat = 0; +J1: + if (damage() & FL_DAMAGE_ALL) { // redraw the box if full redraw + Fl_Boxtype b = box() ? box() : FL_DOWN_BOX; + draw_box(b, x(), y(), w(), h(), color()); + drawsquare = 1; + } + // see if scrollbar needs to be switched on/off: + if ((has_scrollbar_ & VERTICAL) && ( + (has_scrollbar_ & ALWAYS_ON) || position_ || full_height_ > H)) { + if (!scrollbar.visible()) { + scrollbar.set_visible(); + drawsquare = 1; + bbox(X, Y, W, H); + } + } else { + top_ = item_first(); real_position_ = offset_ = 0; + if (scrollbar.visible()) { + scrollbar.clear_visible(); + clear_damage((uchar)(damage()|FL_DAMAGE_SCROLL)); + } + } + + if ((has_scrollbar_ & HORIZONTAL) && ( + (has_scrollbar_ & ALWAYS_ON) || hposition_ || full_width_ > W)) { + if (!hscrollbar.visible()) { + hscrollbar.set_visible(); + drawsquare = 1; + bbox(X, Y, W, H); + } + } else { + real_hposition_ = 0; + if (hscrollbar.visible()) { + hscrollbar.clear_visible(); + clear_damage((uchar)(damage()|FL_DAMAGE_SCROLL)); + } + } + + // Check the vertical scrollbar again, just in case it needs to be drawn + // because the horizontal one is drawn. There should be a cleaner way + // to do this besides copying the same code... + if ((has_scrollbar_ & VERTICAL) && ( + (has_scrollbar_ & ALWAYS_ON) || position_ || full_height_ > H)) { + if (!scrollbar.visible()) { + scrollbar.set_visible(); + drawsquare = 1; + bbox(X, Y, W, H); + } + } else { + top_ = item_first(); real_position_ = offset_ = 0; + if (scrollbar.visible()) { + scrollbar.clear_visible(); + clear_damage((uchar)(damage()|FL_DAMAGE_SCROLL)); + } + } + + bbox(X, Y, W, H); + + fl_clip(X, Y, W, H); + // for each line, draw it if full redraw or scrolled. Erase background + // if not a full redraw or if it is selected: + void* l = top(); + int yy = -offset_; + for (; l && yy < H; l = item_next(l)) { + int hh = item_height(l); + if (hh <= 0) continue; + if ((damage()&(FL_DAMAGE_SCROLL|FL_DAMAGE_ALL)) || l == redraw1 || l == redraw2) { + if (item_selected(l)) { + fl_color(active_r() ? selection_color() : fl_inactive(selection_color())); + fl_rectf(X, yy+Y, W, hh); + } else if (!(damage()&FL_DAMAGE_ALL)) { + fl_push_clip(X, yy+Y, W, hh); + draw_box(box() ? box() : FL_DOWN_BOX, x(), y(), w(), h(), color()); + fl_pop_clip(); + } + item_draw(l, X-hposition_, yy+Y, W+hposition_, hh); + if (l == selection_ && Fl::focus() == this) { + draw_box(FL_BORDER_FRAME, X, yy+Y, W, hh, color()); + draw_focus(FL_NO_BOX, X, yy+Y, W+1, hh+1); + } + int ww = item_width(l); + if (ww > max_width) {max_width = ww; max_width_item = l;} + } + yy += hh; + } + // erase the area below last line: + if (!(damage()&FL_DAMAGE_ALL) && yy < H) { + fl_push_clip(X, yy+Y, W, H-yy); + draw_box(box() ? box() : FL_DOWN_BOX, x(), y(), w(), h(), color()); + fl_pop_clip(); + } + fl_pop_clip(); + redraw1 = redraw2 = 0; + + if (!dont_repeat) { + dont_repeat = 1; + // see if changes to full_height caused by calls to slow_height + // caused scrollbar state to change, in which case we have to redraw: + full_height_ = full_height(); + full_width_ = full_width(); + if ((has_scrollbar_ & VERTICAL) && + ((has_scrollbar_ & ALWAYS_ON) || position_ || full_height_>H)) { + if (!scrollbar.visible()) { damage(FL_DAMAGE_ALL); goto J1; } + } else { + if (scrollbar.visible()) { damage(FL_DAMAGE_ALL); goto J1; } + } + if ((has_scrollbar_ & HORIZONTAL) && + ((has_scrollbar_ & ALWAYS_ON) || hposition_ || full_width_>W)) { + if (!hscrollbar.visible()) { damage(FL_DAMAGE_ALL); goto J1; } + } else { + if (hscrollbar.visible()) { damage(FL_DAMAGE_ALL); goto J1; } + } + } + + // update the scrollbars and redraw them: + int dy = top_ ? item_quick_height(top_) : 0; if (dy < 10) dy = 10; + if (scrollbar.visible()) { + scrollbar.damage_resize( + scrollbar.align()&FL_ALIGN_LEFT ? X-scrollbar_width_ : X+W, + Y, scrollbar_width_, H); + scrollbar.value(position_, H, 0, full_height_); + scrollbar.linesize(dy); + if (drawsquare) draw_child(scrollbar); + else update_child(scrollbar); + } + if (hscrollbar.visible()) { + hscrollbar.damage_resize( + X, scrollbar.align()&FL_ALIGN_TOP ? Y-scrollbar_width_ : Y+H, + W, scrollbar_width_); + hscrollbar.value(hposition_, W, 0, full_width_); + hscrollbar.linesize(dy); + if (drawsquare) draw_child(hscrollbar); + else update_child(hscrollbar); + } + + // draw that little square between the scrollbars: + if (drawsquare && scrollbar.visible() && hscrollbar.visible()) { + fl_color(parent()->color()); + fl_rectf(scrollbar.x(), hscrollbar.y(), scrollbar_width_,scrollbar_width_); + } + + real_hposition_ = hposition_; +} + +// Quick way to delete and reset everything: +void Fl_Browser_::new_list() { + top_ = 0; + position_ = real_position_ = 0; + hposition_ = real_hposition_ = 0; + selection_ = 0; + offset_ = 0; + max_width = 0; + max_width_item = 0; + redraw_lines(); +} + +// Tell it that this item is going away, and that this must remove +// all pointers to it: +void Fl_Browser_::deleting(void* l) { + if (displayed(l)) { + redraw_lines(); + if (l == top_) { + real_position_ -= offset_; + offset_ = 0; + top_ = item_next(l); + if (!top_) top_ = item_prev(l); + } + } else { + // we don't know where this item is, recalculate top... + real_position_ = 0; + offset_ = 0; + top_ = 0; + } + if (l == selection_) selection_ = 0; + if (l == max_width_item) {max_width_item = 0; max_width = 0;} +} + +void Fl_Browser_::replacing(void* a, void* b) { + redraw_line(a); + if (a == selection_) selection_ = b; + if (a == top_) top_ = b; + if (a == max_width_item) {max_width_item = 0; max_width = 0;} +} + +void Fl_Browser_::swapping(void* a, void* b) { + redraw_line(a); + redraw_line(b); + if (a == selection_) selection_ = b; + else if (b == selection_) selection_ = a; + if (a == top_) top_ = b; + else if (b == top_) top_ = a; +} + +void Fl_Browser_::inserting(void* a, void* b) { + if (displayed(a)) redraw_lines(); + if (a == top_) top_ = b; +} + +void* Fl_Browser_::find_item(int my) { + update_top(); + int X, Y, W, H; bbox(X, Y, W, H); + void* l; + int yy = Y-offset_; + for (l = top_; l; l = item_next(l)) { + int hh = item_height(l); if (hh <= 0) continue; + yy += hh; + if (my <= yy || yy>=(Y+H)) return l; + } + return 0; +} + +int Fl_Browser_::select(void* l, int i, int docallbacks) { + if (type() == FL_MULTI_BROWSER) { + if (selection_ != l) { + if (selection_) redraw_line(selection_); + selection_ = l; + redraw_line(l); + } + if ((!i)==(!item_selected(l))) return 0; + item_select(l, i); + redraw_line(l); + } else { + if (i && selection_ == l) return 0; + if (!i && selection_ != l) return 0; + if (selection_) { + item_select(selection_, 0); + redraw_line(selection_); + selection_ = 0; + } + if (i) { + item_select(l, 1); + selection_ = l; + redraw_line(l); + display(l); + } + } + if (docallbacks) { + set_changed(); + do_callback(); + } + return 1; +} + +int Fl_Browser_::deselect(int docallbacks) { + if (type() == FL_MULTI_BROWSER) { + int change = 0; + for (void* p = item_first(); p; p = item_next(p)) + change |= select(p, 0, docallbacks); + return change; + } else { + if (!selection_) return 0; + item_select(selection_, 0); + redraw_line(selection_); + selection_ = 0; + return 1; + } +} + +int Fl_Browser_::select_only(void* l, int docallbacks) { + if (!l) return deselect(docallbacks); + int change = 0; + if (type() == FL_MULTI_BROWSER) { + for (void* p = item_first(); p; p = item_next(p)) + if (p != l) change |= select(p, 0, docallbacks); + } + change |= select(l, 1, docallbacks); + display(l); + return change; +} + +int Fl_Browser_::handle(int event) { + // must do shortcuts first or the scrollbar will get them... + if (event == FL_ENTER || event == FL_LEAVE) return 1; + if (event == FL_KEYBOARD && type() >= FL_HOLD_BROWSER) { + void* l1 = selection_; + void* l = l1; if (!l) l = top_; if (!l) l = item_first(); + if (l) { + if (type()==FL_HOLD_BROWSER) { + switch (Fl::event_key()) { + case FL_Down: + while ((l = item_next(l))) + if (item_height(l)>0) {select_only(l, when()); break;} + return 1; + case FL_Up: + while ((l = item_prev(l))) if (item_height(l)>0) { + select_only(l, when()); break;} + return 1; + } + } else { + switch (Fl::event_key()) { + case FL_Enter: + case FL_KP_Enter: + select_only(l, when() & ~FL_WHEN_ENTER_KEY); + if (when() & FL_WHEN_ENTER_KEY) { + set_changed(); + do_callback(); + } + return 1; + case ' ': + selection_ = l; + select(l, !item_selected(l), when() & ~FL_WHEN_ENTER_KEY); + return 1; + case FL_Down: + while ((l = item_next(l))) { + if (Fl::event_state(FL_SHIFT|FL_CTRL)) + select(l, l1 ? item_selected(l1) : 1, when()); + if (item_height(l)>0) goto J1; + } + return 1; + case FL_Up: + while ((l = item_prev(l))) { + if (Fl::event_state(FL_SHIFT|FL_CTRL)) + select(l, l1 ? item_selected(l1) : 1, when()); + if (item_height(l)>0) goto J1; + } + return 1; +J1: + if (selection_) redraw_line(selection_); + selection_ = l; redraw_line(l); + display(l); + return 1; + } + } + } + } + + if (Fl_Group::handle(event)) return 1; + int X, Y, W, H; bbox(X, Y, W, H); + int my; +// NOTE: +// instead of: +// change = select_only(find_item(my), when() & FL_WHEN_CHANGED) +// we use the construct: +// change = select_only(find_item(my), 0); +// if (change && (when() & FL_WHEN_CHANGED)) { +// set_changed(); +// do_callback(); +// } +// See str #834 +// The first form calls the callback *before* setting change. +// The callback may execute an Fl::wait(), resulting in another +// call of Fl_Browser_::handle() for the same widget. The sequence +// of events can be an FL_PUSH followed by an FL_RELEASE. +// This second call of Fl_Browser_::handle() may result in a - +// somewhat unexpected - second concurrent invocation of the callback. + + static char change; + static char whichway; + static int py; + switch (event) { + case FL_PUSH: + if (!Fl::event_inside(X, Y, W, H)) return 0; + if (Fl::visible_focus()) { + Fl::focus(this); + redraw(); + } + my = py = Fl::event_y(); + change = 0; + if (type() == FL_NORMAL_BROWSER || !top_) + ; + else if (type() != FL_MULTI_BROWSER) { + change = select_only(find_item(my), 0); + if (change && (when() & FL_WHEN_CHANGED)) { + set_changed(); + do_callback(); + } + } else { + void* l = find_item(my); + whichway = 1; + if (Fl::event_state(FL_CTRL)) { // toggle selection: + TOGGLE: + if (l) { + whichway = !item_selected(l); + change = select(l, whichway, 0); + if (change && (when() & FL_WHEN_CHANGED)) { + set_changed(); + do_callback(); + } + } + } else if (Fl::event_state(FL_SHIFT)) { // extend selection: + if (l == selection_) goto TOGGLE; + // state of previous selection determines new value: + whichway = l ? !item_selected(l) : 1; + // see which of the new item or previous selection is earlier, + // by searching from the previous forward for this one: + int down; + if (!l) down = 1; + else {for (void* m = selection_; ; m = item_next(m)) { + if (m == l) {down = 1; break;} + if (!m) {down = 0; break;} + }} + if (down) { + for (void* m = selection_; m != l; m = item_next(m)) + select(m, whichway, when() & FL_WHEN_CHANGED); + } else { + void* e = selection_; + for (void* m = item_next(l); m; m = item_next(m)) { + select(m, whichway, when() & FL_WHEN_CHANGED); + if (m == e) break; + } + } + // do the clicked item last so the select box is around it: + change = 1; + if (l) select(l, whichway, when() & FL_WHEN_CHANGED); + } else { // select only this item + change = select_only(l, 0); + if (change && (when() & FL_WHEN_CHANGED)) { + set_changed(); + do_callback(); + } + } + } + return 1; + case FL_DRAG: + // do the scrolling first: + my = Fl::event_y(); + if (my < Y && my < py) { + int p = real_position_+my-Y; + if (p<0) p = 0; + position(p); + } else if (my > (Y+H) && my > py) { + int p = real_position_+my-(Y+H); + int hh = full_height()-H; if (p > hh) p = hh; + if (p<0) p = 0; + position(p); + } + if (type() == FL_NORMAL_BROWSER || !top_) + ; + else if (type() == FL_MULTI_BROWSER) { + void* l = find_item(my); + void* t; void* b; // this will be the range to change + if (my > py) { // go down + t = selection_ ? item_next(selection_) : 0; + b = l ? item_next(l) : 0; + } else { // go up + t = l; + b = selection_; + } + for (; t && t != b; t = item_next(t)) { + char change_t; + change_t = select(t, whichway, 0); + change |= change_t; + if (change_t && (when() & FL_WHEN_CHANGED)) { + set_changed(); + do_callback(); + } + } + if (l) selection_ = l; + } else { + void* l1 = selection_; + void* l = + (Fl::event_x()x()+w()) ? selection_ : + find_item(my); + change = (l != l1); + select_only(l, when() & FL_WHEN_CHANGED); + } + py = my; + return 1; + case FL_RELEASE: + if (type() == FL_SELECT_BROWSER) { + void* t = selection_; deselect(); selection_ = t; + } + if (change) { + set_changed(); + if (when() & FL_WHEN_RELEASE) do_callback(); + } else { + if (when() & FL_WHEN_NOT_CHANGED) do_callback(); + } + + // double click calls the callback: (like Enter Key) + if (Fl::event_clicks() && (when() & FL_WHEN_ENTER_KEY)) { + set_changed(); + do_callback(); + } + return 1; + case FL_FOCUS: + case FL_UNFOCUS: + if (type() >= FL_HOLD_BROWSER && Fl::visible_focus()) { + redraw(); + return 1; + } else return 0; + } + + return 0; +} + +Fl_Browser_::Fl_Browser_(int X, int Y, int W, int H, const char* l) + : Fl_Group(X, Y, W, H, l), + scrollbar(0, 0, 0, 0, 0), // they will be resized by draw() + hscrollbar(0, 0, 0, 0, 0) +{ + box(FL_NO_BOX); + align(FL_ALIGN_BOTTOM); + position_ = real_position_ = 0; + hposition_ = real_hposition_ = 0; + offset_ = 0; + top_ = 0; + when(FL_WHEN_RELEASE_ALWAYS); + selection_ = 0; + color(FL_BACKGROUND2_COLOR, FL_SELECTION_COLOR); + scrollbar.callback(scrollbar_callback); +//scrollbar.align(FL_ALIGN_LEFT|FL_ALIGN_BOTTOM); // back compatability? + hscrollbar.callback(hscrollbar_callback); + hscrollbar.type(FL_HORIZONTAL); + textfont_ = FL_HELVETICA; + textsize_ = (uchar)FL_NORMAL_SIZE; + textcolor_ = FL_FOREGROUND_COLOR; + has_scrollbar_ = BOTH; + max_width = 0; + max_width_item = 0; + redraw1 = redraw2 = 0; + end(); +} + +// Default versions of some of the virtual functions: + +int Fl_Browser_::item_quick_height(void* l) const { + return item_height(l); +} + +int Fl_Browser_::incr_height() const { + return item_quick_height(item_first()); +} + +int Fl_Browser_::full_height() const { + int t = 0; + for (void* p = item_first(); p; p = item_next(p)) + t += item_quick_height(p); + return t; +} + +int Fl_Browser_::full_width() const { + return max_width; +} + +void Fl_Browser_::item_select(void*, int) {} + +int Fl_Browser_::item_selected(void* l) const {return l==selection_;} + +// +// End of "$Id: Fl_Browser_.cxx 5992 2007-12-15 16:20:16Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Browser_load.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Browser_load.cxx new file mode 100644 index 000000000..0ba153173 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Browser_load.cxx @@ -0,0 +1,57 @@ +// +// "$Id: Fl_Browser_load.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// File loading routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include + +int Fl_Browser::load(const char *filename) { +#define MAXFL_BLINE 1024 + char newtext[MAXFL_BLINE]; + int c; + int i; + clear(); + if (!filename || !(filename[0])) return 1; + FILE *fl = fopen(filename,"r"); + if (!fl) return 0; + i = 0; + do { + c = getc(fl); + if (c == '\n' || c <= 0 || i>=(MAXFL_BLINE-1)) { + newtext[i] = 0; + add(newtext); + i = 0; + } else + newtext[i++] = c; + } while (c >= 0); + fclose(fl); + return 1; +} + +// +// End of "$Id: Fl_Browser_load.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Button.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Button.cxx new file mode 100644 index 000000000..31cbc8753 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Button.cxx @@ -0,0 +1,173 @@ +// +// "$Id: Fl_Button.cxx 6031 2008-02-20 17:59:13Z matt $" +// +// Button widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2006 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include + +// There are a lot of subclasses, named Fl_*_Button. Some of +// them are implemented by setting the type() value and testing it +// here. This includes Fl_Radio_Button and Fl_Toggle_Button + +int Fl_Button::value(int v) { + v = v ? 1 : 0; + oldval = v; + clear_changed(); + if (value_ != v) { + value_ = v; + if (box()) redraw(); + else redraw_label(); + return 1; + } else { + return 0; + } +} + +void Fl_Button::setonly() { // set this radio button on, turn others off + value(1); + Fl_Group* g = (Fl_Group*)parent(); + Fl_Widget*const* a = g->array(); + for (int i = g->children(); i--;) { + Fl_Widget* o = *a++; + if (o != this && o->type()==FL_RADIO_BUTTON) ((Fl_Button*)o)->value(0); + } +} + +void Fl_Button::draw() { + if (type() == FL_HIDDEN_BUTTON) return; + Fl_Color col = value() ? selection_color() : color(); + draw_box(value() ? (down_box()?down_box():fl_down(box())) : box(), col); + if (labeltype() == FL_NORMAL_LABEL && value()) { + Fl_Color c = labelcolor(); + labelcolor(fl_contrast(c, col)); + draw_label(); + labelcolor(c); + } else draw_label(); + if (Fl::focus() == this) draw_focus(); +} + +int Fl_Button::handle(int event) { + int newval; + switch (event) { + case FL_ENTER: + case FL_LEAVE: +// if ((value_?selection_color():color())==FL_GRAY) redraw(); + return 1; + case FL_PUSH: + if (Fl::visible_focus() && handle(FL_FOCUS)) Fl::focus(this); + case FL_DRAG: + if (Fl::event_inside(this)) { + if (type() == FL_RADIO_BUTTON) newval = 1; + else newval = !oldval; + } else + { + clear_changed(); + newval = oldval; + } + if (newval != value_) { + value_ = newval; + set_changed(); + redraw(); + if (when() & FL_WHEN_CHANGED) do_callback(); + } + return 1; + case FL_RELEASE: + if (value_ == oldval) { + if (when() & FL_WHEN_NOT_CHANGED) do_callback(); + return 1; + } + set_changed(); + if (type() == FL_RADIO_BUTTON) setonly(); + else if (type() == FL_TOGGLE_BUTTON) oldval = value_; + else { + value(oldval); + set_changed(); + if (when() & FL_WHEN_CHANGED) do_callback(); + } + if (when() & FL_WHEN_RELEASE) do_callback(); + return 1; + case FL_SHORTCUT: + if (!(shortcut() ? + Fl::test_shortcut(shortcut()) : test_shortcut())) return 0; + + if (Fl::visible_focus() && handle(FL_FOCUS)) Fl::focus(this); + + if (type() == FL_RADIO_BUTTON && !value_) { + setonly(); + set_changed(); + if (when() & FL_WHEN_CHANGED) do_callback(); + } else if (type() == FL_TOGGLE_BUTTON) { + value(!value()); + set_changed(); + if (when() & FL_WHEN_CHANGED) do_callback(); + } else if (when() & FL_WHEN_RELEASE) do_callback(); + return 1; + case FL_FOCUS : + case FL_UNFOCUS : + if (Fl::visible_focus()) { + if (box() == FL_NO_BOX) { + // Widgets with the FL_NO_BOX boxtype need a parent to + // redraw, since it is responsible for redrawing the + // background... + int X = x() > 0 ? x() - 1 : 0; + int Y = y() > 0 ? y() - 1 : 0; + if (window()) window()->damage(FL_DAMAGE_ALL, X, Y, w() + 2, h() + 2); + } else redraw(); + return 1; + } else return 0; + case FL_KEYBOARD : + if (Fl::focus() == this && Fl::event_key() == ' ' && + !(Fl::event_state() & (FL_SHIFT | FL_CTRL | FL_ALT | FL_META))) { + set_changed(); + if (type() == FL_RADIO_BUTTON && !value_) { + setonly(); + if (when() & FL_WHEN_CHANGED) do_callback(); + } else if (type() == FL_TOGGLE_BUTTON) { + value(!value()); + if (when() & FL_WHEN_CHANGED) do_callback(); + } + if (when() & FL_WHEN_RELEASE) do_callback(); + return 1; + } + default: + return 0; + } +} + +Fl_Button::Fl_Button(int X, int Y, int W, int H, const char *l) +: Fl_Widget(X,Y,W,H,l) { + box(FL_UP_BOX); + down_box(FL_NO_BOX); + value_ = oldval = 0; + shortcut_ = 0; + set_flag(SHORTCUT_LABEL); +} + +// +// End of "$Id: Fl_Button.cxx 6031 2008-02-20 17:59:13Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Chart.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Chart.cxx new file mode 100644 index 000000000..8c86a7f09 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Chart.cxx @@ -0,0 +1,390 @@ +// +// "$Id: Fl_Chart.cxx 5942 2007-10-06 17:33:17Z matt $" +// +// Forms-compatible chart widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include +#include "flstring.h" +#include + +#define ARCINC (2.0*M_PI/360.0) + +// this function is in fl_boxtype.cxx: +void fl_rectbound(int x,int y,int w,int h, Fl_Color color); + +/* Widget specific information */ + +static void draw_barchart(int x,int y,int w,int h, + int numb, FL_CHART_ENTRY entries[], + double min, double max, int autosize, int maxnumb, + Fl_Color textcolor) +/* Draws a bar chart. x,y,w,h is the bounding box, entries the array of + numb entries and min and max the boundaries. */ +{ + double incr; + int zeroh; + double lh = fl_height(); + if (max == min) incr = h; + else incr = h/(max-min); + if ( (-min*incr) < lh) { + incr = (h - lh + min*incr)/(max-min); + zeroh = int(y+h-lh); + } else { + zeroh = (int)rint(y+h+min * incr); + } + int bwidth = (int)rint(w/double(autosize?numb:maxnumb)); + /* Draw base line */ + fl_color(textcolor); + fl_line(x, zeroh, x+w, zeroh); + if (min == 0.0 && max == 0.0) return; /* Nothing else to draw */ + int i; + /* Draw the bars */ + for (i=0; i 0) + fl_rectbound(x+i*bwidth,zeroh-hh,bwidth+1,hh+1,(Fl_Color)entries[i].col); + } + /* Draw the labels */ + fl_color(textcolor); + for (i=0; i lw) lw = w1; + } + if (lw > 0.0) lw += 4.0; + double incr; + int zeroh; + if (max == min) incr = w; + else incr = w/(max-min); + if ( (-min*incr) < lw) { + incr = (w - lw + min*incr)/(max-min); + zeroh = x+(int)rint(lw); + } else { + zeroh = (int)rint(x-min * incr); + } + int bwidth = (int)rint(h/double(autosize?numb:maxnumb)); + /* Draw base line */ + fl_color(textcolor); + fl_line(zeroh, y, zeroh, y+h); + if (min == 0.0 && max == 0.0) return; /* Nothing else to draw */ + /* Draw the bars */ + for (i=0; i 0) + fl_rectbound(zeroh,y+i*bwidth,ww+1,bwidth+1, (Fl_Color)entries[i].col); + else if (ww < 0) + fl_rectbound(zeroh+ww,y+i*bwidth,-ww+1,bwidth+1,(Fl_Color)entries[i].col); + } + /* Draw the labels */ + fl_color(textcolor); + for (i=0; i0.0)!=(entries[i].val>0.0)) { + double ttt = entries[i-1].val/(entries[i-1].val-entries[i].val); + int xt = x + (int)rint((i-.5+ttt)*bwidth); + fl_polygon(x0,zeroh, x0,yy0, xt,zeroh); + fl_polygon(xt,zeroh, x1,yy1, x1,zeroh); + } else { + fl_polygon(x0,zeroh, x0,yy0, x1,yy1, x1,zeroh); + } + fl_color(textcolor); + fl_line(x0,yy0,x1,yy1); + } + } + /* Draw base line */ + fl_color(textcolor); + fl_line(x,zeroh,x+w,zeroh); + /* Draw the labels */ + for (i=0; i=0 ? FL_ALIGN_BOTTOM : FL_ALIGN_TOP); +} + +static void draw_piechart(int x,int y,int w,int h, + int numb, FL_CHART_ENTRY entries[], int special, + Fl_Color textcolor) +/* Draws a pie chart. x,y,w,h is the bounding box, entries the array of + numb entries */ +{ + int i; + double xc,yc,rad; /* center and radius */ + double tot; /* sum of values */ + double incr; /* increment in angle */ + double curang; /* current angle we are drawing */ + double txc,tyc; /* temporary center */ + double lh = fl_height(); + /* compute center and radius */ + double h_denom = (special ? 2.3 : 2.0); + rad = (h - 2*lh)/h_denom/1.1; + xc = x+w/2.0; yc = y+h-1.1*rad-lh; + /* compute sum of values */ + tot = 0.0; + for (i=0; i 0.0) tot += entries[i].val; + if (tot == 0.0) return; + incr = 360.0/tot; + /* Draw the pie */ + curang = 0.0; + for (i=0; i 0.0) + { + txc = xc; tyc = yc; + /* Correct for special pies */ + if (special && i==0) + { + txc += 0.3*rad*cos(ARCINC*(curang+0.5*incr*entries[i].val)); + tyc -= 0.3*rad*sin(ARCINC*(curang+0.5*incr*entries[i].val)); + } + fl_color((Fl_Color)entries[i].col); + fl_begin_polygon(); fl_vertex(txc,tyc); + fl_arc(txc,tyc,rad,curang, curang+incr*entries[i].val); + fl_end_polygon(); + fl_color(textcolor); + fl_begin_loop(); fl_vertex(txc,tyc); + fl_arc(txc,tyc,rad,curang, curang+incr*entries[i].val); + fl_end_loop(); + curang += 0.5 * incr * entries[i].val; + /* draw the label */ + double xl = txc + 1.1*rad*cos(ARCINC*curang); + fl_draw(entries[i].str, + (int)rint(xl), + (int)rint(tyc - 1.1*rad*sin(ARCINC*curang)), + 0, 0, + xl= max) { + min = max = 0.0; + for (int i=0; i max) max = entries[i].val; + } + } + + fl_font(textfont(),textsize()); + + switch (type()) { + case FL_BAR_CHART: + ww++; // makes the bars fill box correctly + draw_barchart(xx,yy,ww,hh, numb, entries, min, max, + autosize(), maxnumb, textcolor()); + break; + case FL_HORBAR_CHART: + hh++; // makes the bars fill box correctly + draw_horbarchart(xx,yy,ww,hh, numb, entries, min, max, + autosize(), maxnumb, textcolor()); + break; + case FL_PIE_CHART: + draw_piechart(xx,yy,ww,hh,numb,entries,0, textcolor()); + break; + case FL_SPECIALPIE_CHART: + draw_piechart(xx,yy,ww,hh,numb,entries,1,textcolor()); + break; + default: + draw_linechart(type(),xx,yy,ww,hh, numb, entries, min, max, + autosize(), maxnumb, textcolor()); + break; + } + draw_label(); + fl_pop_clip(); +} + +/*------------------------------*/ + +#define FL_CHART_BOXTYPE FL_BORDER_BOX +#define FL_CHART_COL1 FL_COL1 +#define FL_CHART_LCOL FL_LCOL +#define FL_CHART_ALIGN FL_ALIGN_BOTTOM + +Fl_Chart::Fl_Chart(int X, int Y, int W, int H,const char *l) : +Fl_Widget(X,Y,W,H,l) { + box(FL_BORDER_BOX); + align(FL_ALIGN_BOTTOM); + numb = 0; + maxnumb = 0; + sizenumb = FL_CHART_MAX; + autosize_ = 1; + min = max = 0; + textfont_ = FL_HELVETICA; + textsize_ = 10; + textcolor_ = FL_FOREGROUND_COLOR; + entries = (FL_CHART_ENTRY *)calloc(sizeof(FL_CHART_ENTRY), FL_CHART_MAX + 1); +} + +Fl_Chart::~Fl_Chart() { + free(entries); +} + +void Fl_Chart::clear() { + numb = 0; + redraw(); +} + +void Fl_Chart::add(double val, const char *str, unsigned col) { + /* Allocate more entries if required */ + if (numb >= sizenumb) { + sizenumb += FL_CHART_MAX; + entries = (FL_CHART_ENTRY *)realloc(entries, sizeof(FL_CHART_ENTRY) * (sizenumb + 1)); + } + // Shift entries as needed + if (numb >= maxnumb && maxnumb > 0) { + memmove(entries, entries + 1, sizeof(FL_CHART_ENTRY) * (numb - 1)); + numb --; + } + entries[numb].val = float(val); + entries[numb].col = col; + if (str) { + strlcpy(entries[numb].str,str,FL_CHART_LABEL_MAX + 1); + } else { + entries[numb].str[0] = 0; + } + numb++; + redraw(); +} + +void Fl_Chart::insert(int ind, double val, const char *str, unsigned col) { + int i; + if (ind < 1 || ind > numb+1) return; + /* Allocate more entries if required */ + if (numb >= sizenumb) { + sizenumb += FL_CHART_MAX; + entries = (FL_CHART_ENTRY *)realloc(entries, sizeof(FL_CHART_ENTRY) * (sizenumb + 1)); + } + // Shift entries as needed + for (i=numb; i >= ind; i--) entries[i] = entries[i-1]; + if (numb < maxnumb || maxnumb == 0) numb++; + /* Fill in the new entry */ + entries[ind-1].val = float(val); + entries[ind-1].col = col; + if (str) { + strlcpy(entries[ind-1].str,str,FL_CHART_LABEL_MAX+1); + } else { + entries[ind-1].str[0] = 0; + } + redraw(); +} + +void Fl_Chart::replace(int ind,double val, const char *str, unsigned col) { + if (ind < 1 || ind > numb) return; + entries[ind-1].val = float(val); + entries[ind-1].col = col; + if (str) { + strlcpy(entries[ind-1].str,str,FL_CHART_LABEL_MAX+1); + } else { + entries[ind-1].str[0] = 0; + } + redraw(); +} + +void Fl_Chart::bounds(double mymin, double mymax) { + this->min = mymin; + this->max = mymax; + redraw(); +} + +void Fl_Chart::maxsize(int m) { + int i; + /* Fill in the new number */ + if (m < 0) return; + maxnumb = m; + /* Shift entries if required */ + if (numb > maxnumb) { + for (i = 0; i +#include +#include "flstring.h" +#include +#include + +/* This uses a cache for faster access when you're scanning the list +either forwards or backwards. */ + +Fl_Check_Browser::cb_item *Fl_Check_Browser::find_item(int n) const { + int i = n; + cb_item *p = first; + + if (n <= 0 || n > nitems_ || p == 0) { + return 0; + } + + if (n == cached_item) { + p = cache; + n = 1; + } else if (n == cached_item + 1) { + p = cache->next; + n = 1; + } else if (n == cached_item - 1) { + p = cache->prev; + n = 1; + } + + while (--n) { + p = p->next; + } + + /* Cast to not const and cache it. */ + + ((Fl_Check_Browser *)this)->cache = p; + ((Fl_Check_Browser *)this)->cached_item = i; + + return p; +} + +int Fl_Check_Browser::lineno(cb_item *p0) const { + cb_item *p = first; + + if (p == 0) { + return 0; + } + + int i = 1; + while (p) { + if (p == p0) { + return i; + } + i++; + p = p->next; + } + + return 0; +} + +Fl_Check_Browser::Fl_Check_Browser(int X, int Y, int W, int H, const char *l) + : Fl_Browser_(X, Y, W, H, l) { + type(FL_SELECT_BROWSER); + when(FL_WHEN_NEVER); + first = last = 0; + nitems_ = nchecked_ = 0; + cached_item = -1; +} + +void *Fl_Check_Browser::item_first() const { + return first; +} + +void *Fl_Check_Browser::item_next(void *l) const { + return ((cb_item *)l)->next; +} + +void *Fl_Check_Browser::item_prev(void *l) const { + return ((cb_item *)l)->prev; +} + +int Fl_Check_Browser::item_height(void *) const { + return textsize() + 2; +} + +#define CHECK_SIZE (textsize()-2) + +int Fl_Check_Browser::item_width(void *v) const { + fl_font(textfont(), textsize()); + return int(fl_width(((cb_item *)v)->text)) + CHECK_SIZE + 8; +} + +void Fl_Check_Browser::item_draw(void *v, int X, int Y, int, int) const { + cb_item *i = (cb_item *)v; + char *s = i->text; + int tsize = textsize(); + Fl_Color col = active_r() ? textcolor() : fl_inactive(textcolor()); + int cy = Y + (tsize + 1 - CHECK_SIZE) / 2; + X += 2; + + fl_color(active_r() ? FL_FOREGROUND_COLOR : fl_inactive(FL_FOREGROUND_COLOR)); + fl_loop(X, cy, X, cy + CHECK_SIZE, + X + CHECK_SIZE, cy + CHECK_SIZE, X + CHECK_SIZE, cy); + if (i->checked) { + int tx = X + 3; + int tw = CHECK_SIZE - 4; + int d1 = tw/3; + int d2 = tw-d1; + int ty = cy + (CHECK_SIZE+d2)/2-d1-2; + for (int n = 0; n < 3; n++, ty++) { + fl_line(tx, ty, tx+d1, ty+d1); + fl_line(tx+d1, ty+d1, tx+tw-1, ty+d1-d2+1); + } + } + fl_font(textfont(), tsize); + if (i->selected) { + col = fl_contrast(col, selection_color()); + } + fl_color(col); + fl_draw(s, X + CHECK_SIZE + 8, Y + tsize - 1); +} + +void Fl_Check_Browser::item_select(void *v, int state) { + cb_item *i = (cb_item *)v; + + if (state) { + if (i->checked) { + i->checked = 0; + nchecked_--; + } else { + i->checked = 1; + nchecked_++; + } + } +} + +int Fl_Check_Browser::item_selected(void *v) const { + cb_item *i = (cb_item *)v; + return i->selected; +} + +int Fl_Check_Browser::add(char *s) { + return (add(s, 0)); +} + +int Fl_Check_Browser::add(char *s, int b) { + cb_item *p = (cb_item *)malloc(sizeof(cb_item)); + p->next = 0; + p->prev = 0; + p->checked = b; + p->selected = 0; + p->text = strdup(s); + + if (b) { + nchecked_++; + } + + if (last == 0) { + first = last = p; + } else { + last->next = p; + p->prev = last; + last = p; + } + nitems_++; + + return (nitems_); +} + +int Fl_Check_Browser::remove(int item) { + cb_item *p = find_item(item); + + // line at item exists + if(p) { + // tell the Browser_ what we will do + deleting(p); + + // fix checked count + if(p->checked) + --nchecked_; + + // remove the node + if (p->prev) + p->prev->next = p->next; + else + first = p->next; + if (p->next) + p->next->prev = p->prev; + else + last = p->prev; + + free(p->text); + free(p); + + --nitems_; + cached_item = -1; + } + + return (nitems_); +} + +void Fl_Check_Browser::clear() { + cb_item *p = first; + cb_item *next; + + if (p == 0) { + return; + } + + new_list(); + do { + next = p->next; + free(p->text); + free(p); + p = next; + } while (p); + + first = last = 0; + nitems_ = nchecked_ = 0; + cached_item = -1; +} + +int Fl_Check_Browser::checked(int i) const { + cb_item *p = find_item(i); + + if (p) return p->checked; + return 0; +} + +void Fl_Check_Browser::checked(int i, int b) { + cb_item *p = find_item(i); + + if (p && (p->checked ^ b)) { + p->checked = b; + if (b) { + nchecked_++; + } else { + nchecked_--; + } + redraw(); + } +} + +int Fl_Check_Browser::value() const { + return lineno((cb_item *)selection()); +} + +char *Fl_Check_Browser::text(int i) const { + cb_item *p = find_item(i); + + if (p) return p->text; + return 0; +} + +void Fl_Check_Browser::check_all() { + cb_item *p; + + nchecked_ = nitems_; + for (p = first; p; p = p->next) { + p->checked = 1; + } + redraw(); +} + +void Fl_Check_Browser::check_none() { + cb_item *p; + + nchecked_ = 0; + for (p = first; p; p = p->next) { + p->checked = 0; + } + redraw(); +} + +int Fl_Check_Browser::handle(int event) { + if (event==FL_PUSH) + deselect(); + return Fl_Browser_::handle(event); +} + +// +// End of "$Id: Fl_Check_Browser.cxx 5985 2007-11-20 21:15:08Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Check_Button.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Check_Button.cxx new file mode 100644 index 000000000..a2b88f871 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Check_Button.cxx @@ -0,0 +1,40 @@ +// +// "$Id: Fl_Check_Button.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Check button widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include + +// A subclass of Fl_Button that always draws as a diamond box. This +// diamond is smaller than the widget size and can be surchecked by +// another box type, for compatability with Forms. + +Fl_Check_Button::Fl_Check_Button(int X, int Y, int W, int H, const char *l) +: Fl_Light_Button(X, Y, W, H, l) { + box(FL_NO_BOX); + down_box(FL_DOWN_BOX); + selection_color(FL_FOREGROUND_COLOR); +} diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Choice.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Choice.cxx new file mode 100644 index 000000000..c9f927bee --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Choice.cxx @@ -0,0 +1,191 @@ +// +// "$Id: Fl_Choice.cxx 5485 2006-09-24 13:35:23Z mike $" +// +// Choice widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2006 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include "flstring.h" + +// Emulates the Forms choice widget. This is almost exactly the same +// as an Fl_Menu_Button. The only difference is the appearance of the +// button: it draws the text of the current pick and a down-arrow. + +void Fl_Choice::draw() { + int dx = Fl::box_dx(FL_DOWN_BOX); + int dy = Fl::box_dy(FL_DOWN_BOX); + int H = h() - 2 * dy; + int W = (H > 20) ? 20 : H; + int X = x() + w() - W - dx; + int Y = y() + dy; + int w1 = (W - 4) / 3; if (w1 < 1) w1 = 1; + int x1 = X + (W - 2 * w1 - 1) / 2; + int y1 = Y + (H - w1 - 1) / 2; + + if (Fl::scheme()) { + draw_box(FL_UP_BOX, color()); + + fl_color(active_r() ? labelcolor() : fl_inactive(labelcolor())); + if (!strcmp(Fl::scheme(), "plastic")) { + // Show larger up/down arrows... + fl_polygon(x1, y1 + 3, x1 + w1, y1 + w1 + 3, x1 + 2 * w1, y1 + 3); + fl_polygon(x1, y1 + 1, x1 + w1, y1 - w1 + 1, x1 + 2 * w1, y1 + 1); + } else { + // Show smaller up/down arrows with a divider... + x1 = x() + w() - 13 - dx; + y1 = y() + h() / 2; + fl_polygon(x1, y1 - 2, x1 + 3, y1 - 5, x1 + 6, y1 - 2); + fl_polygon(x1, y1 + 2, x1 + 3, y1 + 5, x1 + 6, y1 + 2); + + fl_color(fl_darker(color())); + fl_yxline(x1 - 7, y1 - 8, y1 + 8); + + fl_color(fl_lighter(color())); + fl_yxline(x1 - 6, y1 - 8, y1 + 8); + } + } else { + if (fl_contrast(textcolor(), FL_BACKGROUND2_COLOR) == textcolor()) { + draw_box(FL_DOWN_BOX, FL_BACKGROUND2_COLOR); + } else { + draw_box(FL_DOWN_BOX, fl_lighter(color())); + } + draw_box(FL_UP_BOX,X,Y,W,H,color()); + + fl_color(active_r() ? labelcolor() : fl_inactive(labelcolor())); + fl_polygon(x1, y1, x1 + w1, y1 + w1, x1 + 2 * w1, y1); + } + + W += 2 * dx; + + if (mvalue()) { + Fl_Menu_Item m = *mvalue(); + if (active_r()) m.activate(); else m.deactivate(); + + // ERCO + int xx = x() + dx, yy = y() + dy + 1, ww = w() - W, hh = H - 2; + + fl_clip(xx, yy, ww, hh); + + if ( Fl::scheme()) { + Fl_Label l; + l.value = m.text; + l.image = 0; + l.deimage = 0; + l.type = m.labeltype_; + l.font = m.labelsize_ || m.labelfont_ ? m.labelfont_ : uchar(textfont()); + l.size = m.labelsize_ ? m.labelsize_ : textsize(); + l.color= m.labelcolor_ ? m.labelcolor_ : textcolor(); + if (!m.active()) l.color = fl_inactive((Fl_Color)l.color); + fl_draw_shortcut = 2; // hack value to make '&' disappear + l.draw(xx+3, yy, ww>6 ? ww-6 : 0, hh, FL_ALIGN_LEFT); + fl_draw_shortcut = 0; + if ( Fl::focus() == this ) draw_focus(box(), xx, yy, ww, hh); + } + else { + fl_draw_shortcut = 2; // hack value to make '&' disappear + m.draw(xx, yy, ww, hh, this, Fl::focus() == this); + fl_draw_shortcut = 0; + } + + fl_pop_clip(); + } + + draw_label(); +} + +Fl_Choice::Fl_Choice(int X, int Y, int W, int H, const char *l) +: Fl_Menu_(X,Y,W,H,l) { + align(FL_ALIGN_LEFT); + when(FL_WHEN_RELEASE); + textfont(FL_HELVETICA); + box(FL_FLAT_BOX); + down_box(FL_BORDER_BOX); +} + +int Fl_Choice::value(const Fl_Menu_Item *v) { + if (!Fl_Menu_::value(v)) return 0; + redraw(); + return 1; +} + +int Fl_Choice::value(int v) { + if (v == -1) return value((const Fl_Menu_Item *)0); + if (v < 0 || v >= (size() - 1)) return 0; + if (!Fl_Menu_::value(v)) return 0; + redraw(); + return 1; +} + +int Fl_Choice::handle(int e) { + if (!menu() || !menu()->text) return 0; + const Fl_Menu_Item* v; + switch (e) { + case FL_ENTER: + case FL_LEAVE: + return 1; + + case FL_KEYBOARD: + if (Fl::event_key() != ' ' || + (Fl::event_state() & (FL_SHIFT | FL_CTRL | FL_ALT | FL_META))) return 0; + case FL_PUSH: + if (Fl::visible_focus()) Fl::focus(this); + J1: + if (Fl::scheme() + || fl_contrast(textcolor(), FL_BACKGROUND2_COLOR) != textcolor()) { + v = menu()->pulldown(x(), y(), w(), h(), mvalue(), this); + } else { + // In order to preserve the old look-n-feel of "white" menus, + // temporarily override the color() of this widget... + Fl_Color c = color(); + color(FL_BACKGROUND2_COLOR); + v = menu()->pulldown(x(), y(), w(), h(), mvalue(), this); + color(c); + } + if (!v || v->submenu()) return 1; + if (v != mvalue()) redraw(); + picked(v); + return 1; + case FL_SHORTCUT: + if (Fl_Widget::test_shortcut()) goto J1; + v = menu()->test_shortcut(); + if (!v) return 0; + if (v != mvalue()) redraw(); + picked(v); + return 1; + case FL_FOCUS: + case FL_UNFOCUS: + if (Fl::visible_focus()) { + redraw(); + return 1; + } else return 0; + default: + return 0; + } +} + +// +// End of "$Id: Fl_Choice.cxx 5485 2006-09-24 13:35:23Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Clock.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Clock.cxx new file mode 100644 index 000000000..6516256d0 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Clock.cxx @@ -0,0 +1,177 @@ +// +// "$Id: Fl_Clock.cxx 5472 2006-09-20 03:03:14Z mike $" +// +// Clock widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2006 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include +#include +#ifndef WIN32 +# include +#endif /* !WIN32 */ + +// Original clock display written by Paul Haeberli at SGI. +// Modifications by Mark Overmars for Forms +// Further changes by Bill Spitzak for fltk + +const float hourhand[4][2] = {{-0.5f, 0}, {0, 1.5f}, {0.5f, 0}, {0, -7.0f}}; +const float minhand[4][2] = {{-0.5f, 0}, {0, 1.5f}, {0.5f, 0}, {0, -11.5f}}; +const float sechand[4][2] = {{-0.1f, 0}, {0, 2.0f}, {0.1f, 0}, {0, -11.5f}}; + +static void drawhand(double ang,const float v[][2],Fl_Color fill,Fl_Color line) +{ + fl_push_matrix(); + fl_rotate(ang); + fl_color(fill); fl_begin_polygon(); + int i; for (i=0; i<4; i++) fl_vertex(v[i][0],v[i][1]); fl_end_polygon(); + fl_color(line); fl_begin_loop(); + for (i=0; i<4; i++) fl_vertex(v[i][0],v[i][1]); fl_end_loop(); + fl_pop_matrix(); +} + +void Fl_Clock_Output::drawhands(Fl_Color fill, Fl_Color line) { + if (!active_r()) { + fill = fl_inactive(fill); + line = fl_inactive(line); + } + drawhand(-360*(hour()+minute()/60.0)/12, hourhand, fill, line); + drawhand(-360*(minute()+second()/60.0)/60, minhand, fill, line); + drawhand(-360*(second()/60.0), sechand, fill, line); +} + +static void rect(double x, double y, double w, double h) { + double r = x+w; + double t = y+h; + fl_begin_polygon(); + fl_vertex(x, y); + fl_vertex(r, y); + fl_vertex(r, t); + fl_vertex(x, t); + fl_end_polygon(); +} + +void Fl_Clock_Output::draw(int X, int Y, int W, int H) { + Fl_Color box_color = type()==FL_ROUND_CLOCK ? FL_GRAY : color(); + Fl_Color shadow_color = fl_color_average(box_color, FL_BLACK, 0.5); + draw_box(box(), X, Y, W, H, box_color); + fl_push_matrix(); + fl_translate(X+W/2.0-.5, Y+H/2.0-.5); + fl_scale((W-1)/28.0, (H-1)/28.0); + if (type() == FL_ROUND_CLOCK) { + fl_color(active_r() ? color() : fl_inactive(color())); + fl_begin_polygon(); fl_circle(0,0,14); fl_end_polygon(); + fl_color(active_r() ? FL_FOREGROUND_COLOR : fl_inactive(FL_FOREGROUND_COLOR)); + fl_begin_loop(); fl_circle(0,0,14); fl_end_loop(); + } + // draw the shadows: + fl_push_matrix(); + fl_translate(0.60, 0.60); + drawhands(shadow_color, shadow_color); + fl_pop_matrix(); + // draw the tick marks: + fl_push_matrix(); + fl_color(active_r() ? FL_FOREGROUND_COLOR : fl_inactive(FL_FOREGROUND_COLOR)); + for (int i=0; i<12; i++) { + if (i==6) rect(-0.5, 9, 1, 2); + else if (i==3 || i==0 || i== 9) rect(-0.5, 9.5, 1, 1); + else rect(-0.25, 9.5, .5, 1); + fl_rotate(-30); + } + fl_pop_matrix(); + // draw the hands: + drawhands(selection_color(), FL_FOREGROUND_COLOR); // color was 54 + fl_pop_matrix(); +} + +void Fl_Clock_Output::draw() { + draw(x(), y(), w(), h()); + draw_label(); +} + +void Fl_Clock_Output::value(int H, int m, int s) { + if (H!=hour_ || m!=minute_ || s!=second_) { + hour_ = H; minute_ = m; second_ = s; + value_ = (H * 60 + m) * 60 + s; + damage(FL_DAMAGE_CHILD); + } +} + +void Fl_Clock_Output::value(ulong v) { + value_ = v; + struct tm *timeofday; + // Some platforms, notably Windows, now use a 64-bit time_t value... + time_t vv = (time_t)v; + timeofday = localtime(&vv); + value(timeofday->tm_hour, timeofday->tm_min, timeofday->tm_sec); +} + +Fl_Clock_Output::Fl_Clock_Output(int X, int Y, int W, int H, const char *l) +: Fl_Widget(X, Y, W, H, l) { + box(FL_UP_BOX); + selection_color(fl_gray_ramp(5)); + align(FL_ALIGN_BOTTOM); + hour_ = 0; + minute_ = 0; + second_ = 0; + value_ = 0; +} + +//////////////////////////////////////////////////////////////// + +Fl_Clock::Fl_Clock(int X, int Y, int W, int H, const char *l) + : Fl_Clock_Output(X, Y, W, H, l) {} + +Fl_Clock::Fl_Clock(uchar t, int X, int Y, int W, int H, const char *l) + : Fl_Clock_Output(X, Y, W, H, l) { + type(t); + box(t==FL_ROUND_CLOCK ? FL_NO_BOX : FL_UP_BOX); +} + +static void tick(void *v) { + ((Fl_Clock*)v)->value(time(0)); + Fl::add_timeout(1.0, tick, v); +} + +int Fl_Clock::handle(int event) { + switch (event) { + case FL_SHOW: + tick(this); + break; + case FL_HIDE: + Fl::remove_timeout(tick, this); + break; + } + return Fl_Clock_Output::handle(event); +} + +Fl_Clock::~Fl_Clock() { + Fl::remove_timeout(tick, this); +} + +// +// End of "$Id: Fl_Clock.cxx 5472 2006-09-20 03:03:14Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Color_Chooser.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Color_Chooser.cxx new file mode 100644 index 000000000..b68520baf --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Color_Chooser.cxx @@ -0,0 +1,529 @@ +// +// "$Id: Fl_Color_Chooser.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Color chooser for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include +#include + +// Besides being a useful object on it's own, the Fl_Color_Chooser was +// an attempt to make a complex composite object that could be easily +// imbedded into a user interface. If you wish to make complex objects +// of your own, be sure to read this code. + +// The function fl_color_chooser() creates a window containing a color +// chooser and a few buttons and current-color indicators. It is an +// easier interface for simple programs that just need a color. + +// The "hue box" can be a circle or rectilinear. +// You get a circle by defining this: +#define CIRCLE 1 +// And the "hue box" can auto-update when the value changes +// you get this by defining this: +#define UPDATE_HUE_BOX 1 + +void Fl_Color_Chooser::hsv2rgb( + double H, double S, double V, double& R, double& G, double& B) { + if (S < 5.0e-6) { + R = G = B = V; + } else { + int i = (int)H; + double f = H - (float)i; + double p1 = V*(1.0-S); + double p2 = V*(1.0-S*f); + double p3 = V*(1.0-S*(1.0-f)); + switch (i) { + case 0: R = V; G = p3; B = p1; break; + case 1: R = p2; G = V; B = p1; break; + case 2: R = p1; G = V; B = p3; break; + case 3: R = p1; G = p2; B = V; break; + case 4: R = p3; G = p1; B = V; break; + case 5: R = V; G = p1; B = p2; break; + } + } +} + +void Fl_Color_Chooser::rgb2hsv( + double R, double G, double B, double& H, double& S, double& V) { + double maxv = R > G ? R : G; if (B > maxv) maxv = B; + V = maxv; + if (maxv>0) { + double minv = R < G ? R : G; if (B < minv) minv = B; + S = 1.0 - double(minv)/maxv; + if (maxv > minv) { + if (maxv == R) {H = (G-B)/double(maxv-minv); if (H<0) H += 6.0;} + else if (maxv == G) H = 2.0+(B-R)/double(maxv-minv); + else H = 4.0+(R-G)/double(maxv-minv); + } + } +} + +enum {M_RGB, M_BYTE, M_HEX, M_HSV}; // modes +static Fl_Menu_Item mode_menu[] = { + {"rgb"}, + {"byte"}, + {"hex"}, + {"hsv"}, + {0} +}; + +int Flcc_Value_Input::format(char* buf) { + Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent(); + if (c->mode() == M_HEX) return sprintf(buf,"0x%02X", int(value())); + else return Fl_Valuator::format(buf); +} + +void Fl_Color_Chooser::set_valuators() { + switch (mode()) { + case M_RGB: + rvalue.range(0,1); rvalue.step(1,1000); rvalue.value(r_); + gvalue.range(0,1); gvalue.step(1,1000); gvalue.value(g_); + bvalue.range(0,1); bvalue.step(1,1000); bvalue.value(b_); + break; + case M_BYTE: + case M_HEX: + rvalue.range(0,255); rvalue.step(1); rvalue.value(int(255*r_+.5)); + gvalue.range(0,255); gvalue.step(1); gvalue.value(int(255*g_+.5)); + bvalue.range(0,255); bvalue.step(1); bvalue.value(int(255*b_+.5)); + break; + case M_HSV: + rvalue.range(0,6); rvalue.step(1,1000); rvalue.value(hue_); + gvalue.range(0,1); gvalue.step(1,1000); gvalue.value(saturation_); + bvalue.range(0,1); bvalue.step(1,1000); bvalue.value(value_); + break; + } +} + +int Fl_Color_Chooser::rgb(double R, double G, double B) { + if (R == r_ && G == g_ && B == b_) return 0; + r_ = R; g_ = G; b_ = B; + double ph = hue_; + double ps = saturation_; + double pv = value_; + rgb2hsv(R,G,B,hue_,saturation_,value_); + set_valuators(); + set_changed(); + if (value_ != pv) { +#ifdef UPDATE_HUE_BOX + huebox.damage(FL_DAMAGE_SCROLL); +#endif + valuebox.damage(FL_DAMAGE_EXPOSE);} + if (hue_ != ph || saturation_ != ps) { + huebox.damage(FL_DAMAGE_EXPOSE); + valuebox.damage(FL_DAMAGE_SCROLL); + } + return 1; +} + +int Fl_Color_Chooser::hsv(double H, double S, double V) { + H = fmod(H,6.0); if (H < 0.0) H += 6.0; + if (S < 0.0) S = 0.0; else if (S > 1.0) S = 1.0; + if (V < 0.0) V = 0.0; else if (V > 1.0) V = 1.0; + if (H == hue_ && S == saturation_ && V == value_) return 0; + double ph = hue_; + double ps = saturation_; + double pv = value_; + hue_ = H; saturation_ = S; value_ = V; + if (value_ != pv) { +#ifdef UPDATE_HUE_BOX + huebox.damage(FL_DAMAGE_SCROLL); +#endif + valuebox.damage(FL_DAMAGE_EXPOSE);} + if (hue_ != ph || saturation_ != ps) { + huebox.damage(FL_DAMAGE_EXPOSE); + valuebox.damage(FL_DAMAGE_SCROLL); + } + hsv2rgb(H,S,V,r_,g_,b_); + set_valuators(); + set_changed(); + return 1; +} + +//////////////////////////////////////////////////////////////// + +static void tohs(double x, double y, double& h, double& s) { +#ifdef CIRCLE + x = 2*x-1; + y = 1-2*y; + s = sqrt(x*x+y*y); if (s > 1.0) s = 1.0; + h = (3.0/M_PI)*atan2(y,x); + if (h<0) h += 6.0; +#else + h = fmod(6.0*x,6.0); if (h < 0.0) h += 6.0; + s = 1.0-y; if (s < 0.0) s = 0.0; else if (s > 1.0) s = 1.0; +#endif +} + +int Flcc_HueBox::handle(int e) { + static double ih, is; + Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent(); + switch (e) { + case FL_PUSH: + if (Fl::visible_focus()) { + Fl::focus(this); + redraw(); + } + ih = c->hue(); + is = c->saturation(); + case FL_DRAG: { + double Xf, Yf, H, S; + Xf = (Fl::event_x()-x()-Fl::box_dx(box()))/double(w()-Fl::box_dw(box())); + Yf = (Fl::event_y()-y()-Fl::box_dy(box()))/double(h()-Fl::box_dh(box())); + tohs(Xf, Yf, H, S); + if (fabs(H-ih) < 3*6.0/w()) H = ih; + if (fabs(S-is) < 3*1.0/h()) S = is; + if (Fl::event_state(FL_CTRL)) H = ih; + if (c->hsv(H, S, c->value())) c->do_callback(); + } return 1; + case FL_FOCUS : + case FL_UNFOCUS : + if (Fl::visible_focus()) { + redraw(); + return 1; + } + else return 1; + case FL_KEYBOARD : + return handle_key(Fl::event_key()); + default: + return 0; + } +} + +static void generate_image(void* vv, int X, int Y, int W, uchar* buf) { + Flcc_HueBox* v = (Flcc_HueBox*)vv; + int iw = v->w()-Fl::box_dw(v->box()); + double Yf = double(Y)/(v->h()-Fl::box_dh(v->box())); +#ifdef UPDATE_HUE_BOX + const double V = ((Fl_Color_Chooser*)(v->parent()))->value(); +#else + const double V = 1.0; +#endif + for (int x = X; x < X+W; x++) { + double Xf = double(x)/iw; + double H,S; tohs(Xf,Yf,H,S); + double r,g,b; + Fl_Color_Chooser::hsv2rgb(H,S,V,r,g,b); + *buf++ = uchar(255*r+.5); + *buf++ = uchar(255*g+.5); + *buf++ = uchar(255*b+.5); + } +} + +int Flcc_HueBox::handle_key(int key) { + int w1 = w()-Fl::box_dw(box())-6; + int h1 = h()-Fl::box_dh(box())-6; + Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent(); + +#ifdef CIRCLE + int X = int(.5*(cos(c->hue()*(M_PI/3.0))*c->saturation()+1) * w1); + int Y = int(.5*(1-sin(c->hue()*(M_PI/3.0))*c->saturation()) * h1); +#else + int X = int(c->hue()/6.0*w1); + int Y = int((1-c->saturation())*h1); +#endif + + switch (key) { + case FL_Up : + Y -= 3; + break; + case FL_Down : + Y += 3; + break; + case FL_Left : + X -= 3; + break; + case FL_Right : + X += 3; + break; + default : + return 0; + } + + double Xf, Yf, H, S; + Xf = (double)X/(double)w1; + Yf = (double)Y/(double)h1; + tohs(Xf, Yf, H, S); + if (c->hsv(H, S, c->value())) c->do_callback(); + + return 1; +} + +void Flcc_HueBox::draw() { + if (damage()&FL_DAMAGE_ALL) draw_box(); + int x1 = x()+Fl::box_dx(box()); + int yy1 = y()+Fl::box_dy(box()); + int w1 = w()-Fl::box_dw(box()); + int h1 = h()-Fl::box_dh(box()); + if (damage() == FL_DAMAGE_EXPOSE) fl_clip(x1+px,yy1+py,6,6); + fl_draw_image(generate_image, this, x1, yy1, w1, h1); + if (damage() == FL_DAMAGE_EXPOSE) fl_pop_clip(); + Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent(); +#ifdef CIRCLE + int X = int(.5*(cos(c->hue()*(M_PI/3.0))*c->saturation()+1) * (w1-6)); + int Y = int(.5*(1-sin(c->hue()*(M_PI/3.0))*c->saturation()) * (h1-6)); +#else + int X = int(c->hue()/6.0*(w1-6)); + int Y = int((1-c->saturation())*(h1-6)); +#endif + if (X < 0) X = 0; else if (X > w1-6) X = w1-6; + if (Y < 0) Y = 0; else if (Y > h1-6) Y = h1-6; + // fl_color(c->value()>.75 ? FL_BLACK : FL_WHITE); + draw_box(FL_UP_BOX,x1+X,yy1+Y,6,6,Fl::focus() == this ? FL_FOREGROUND_COLOR : FL_GRAY); + px = X; py = Y; +} + +//////////////////////////////////////////////////////////////// + +int Flcc_ValueBox::handle(int e) { + static double iv; + Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent(); + switch (e) { + case FL_PUSH: + if (Fl::visible_focus()) { + Fl::focus(this); + redraw(); + } + iv = c->value(); + case FL_DRAG: { + double Yf; + Yf = 1-(Fl::event_y()-y()-Fl::box_dy(box()))/double(h()-Fl::box_dh(box())); + if (fabs(Yf-iv)<(3*1.0/h())) Yf = iv; + if (c->hsv(c->hue(),c->saturation(),Yf)) c->do_callback(); + } return 1; + case FL_FOCUS : + case FL_UNFOCUS : + if (Fl::visible_focus()) { + redraw(); + return 1; + } + else return 1; + case FL_KEYBOARD : + return handle_key(Fl::event_key()); + default: + return 0; + } +} + +static double tr, tg, tb; +static void generate_vimage(void* vv, int X, int Y, int W, uchar* buf) { + Flcc_ValueBox* v = (Flcc_ValueBox*)vv; + double Yf = 255*(1.0-double(Y)/(v->h()-Fl::box_dh(v->box()))); + uchar r = uchar(tr*Yf+.5); + uchar g = uchar(tg*Yf+.5); + uchar b = uchar(tb*Yf+.5); + for (int x = X; x < X+W; x++) { + *buf++ = r; *buf++ = g; *buf++ = b; + } +} + +void Flcc_ValueBox::draw() { + if (damage()&FL_DAMAGE_ALL) draw_box(); + Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent(); + c->hsv2rgb(c->hue(),c->saturation(),1.0,tr,tg,tb); + int x1 = x()+Fl::box_dx(box()); + int yy1 = y()+Fl::box_dy(box()); + int w1 = w()-Fl::box_dw(box()); + int h1 = h()-Fl::box_dh(box()); + if (damage() == FL_DAMAGE_EXPOSE) fl_clip(x1,yy1+py,w1,6); + fl_draw_image(generate_vimage, this, x1, yy1, w1, h1); + if (damage() == FL_DAMAGE_EXPOSE) fl_pop_clip(); + int Y = int((1-c->value()) * (h1-6)); + if (Y < 0) Y = 0; else if (Y > h1-6) Y = h1-6; + draw_box(FL_UP_BOX,x1,yy1+Y,w1,6,Fl::focus() == this ? FL_FOREGROUND_COLOR : FL_GRAY); + py = Y; +} + +int Flcc_ValueBox::handle_key(int key) { + int h1 = h()-Fl::box_dh(box())-6; + Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent(); + + int Y = int((1-c->value()) * h1); + if (Y < 0) Y = 0; else if (Y > h1) Y = h1; + + switch (key) { + case FL_Up : + Y -= 3; + break; + case FL_Down : + Y += 3; + break; + default : + return 0; + } + + double Yf; + Yf = 1-((double)Y/(double)h1); + if (c->hsv(c->hue(),c->saturation(),Yf)) c->do_callback(); + + return 1; +} + +//////////////////////////////////////////////////////////////// + +void Fl_Color_Chooser::rgb_cb(Fl_Widget* o, void*) { + Fl_Color_Chooser* c = (Fl_Color_Chooser*)(o->parent()); + double R = c->rvalue.value(); + double G = c->gvalue.value(); + double B = c->bvalue.value(); + if (c->mode() == M_HSV) { + if (c->hsv(R,G,B)) c->do_callback(); + return; + } + if (c->mode() != M_RGB) { + R = R/255; + G = G/255; + B = B/255; + } + if (c->rgb(R,G,B)) c->do_callback(); +} + +void Fl_Color_Chooser::mode_cb(Fl_Widget* o, void*) { + Fl_Color_Chooser* c = (Fl_Color_Chooser*)(o->parent()); + // force them to redraw even if value is the same: + c->rvalue.value(-1); + c->gvalue.value(-1); + c->bvalue.value(-1); + c->set_valuators(); +} + +//////////////////////////////////////////////////////////////// + +Fl_Color_Chooser::Fl_Color_Chooser(int X, int Y, int W, int H, const char* L) + : Fl_Group(0,0,195,115,L), + huebox(0,0,115,115), + valuebox(115,0,20,115), + choice(140,0,55,25), + rvalue(140,30,55,25), + gvalue(140,60,55,25), + bvalue(140,90,55,25), + resize_box(0,0,115,115) +{ + end(); + resizable(resize_box); + resize(X,Y,W,H); + r_ = g_ = b_ = 0; + hue_ = 0.0; + saturation_ = 0.0; + value_ = 0.0; + huebox.box(FL_DOWN_FRAME); + valuebox.box(FL_DOWN_FRAME); + choice.menu(mode_menu); + set_valuators(); + rvalue.callback(rgb_cb); + gvalue.callback(rgb_cb); + bvalue.callback(rgb_cb); + choice.callback(mode_cb); + choice.box(FL_THIN_UP_BOX); + choice.textfont(FL_HELVETICA_BOLD_ITALIC); +} + +//////////////////////////////////////////////////////////////// +// fl_color_chooser(): + +#include +#include +#include + +class ColorChip : public Fl_Widget { + void draw(); +public: + uchar r,g,b; + ColorChip(int X, int Y, int W, int H) : Fl_Widget(X,Y,W,H) { + box(FL_ENGRAVED_FRAME);} +}; + +void ColorChip::draw() { + if (damage()&FL_DAMAGE_ALL) draw_box(); + fl_rectf(x()+Fl::box_dx(box()), + y()+Fl::box_dy(box()), + w()-Fl::box_dw(box()), + h()-Fl::box_dh(box()),r,g,b); +} + +static void chooser_cb(Fl_Object* o, void* vv) { + Fl_Color_Chooser* c = (Fl_Color_Chooser*)o; + ColorChip* v = (ColorChip*)vv; + v->r = uchar(255*c->r()+.5); + v->g = uchar(255*c->g()+.5); + v->b = uchar(255*c->b()+.5); + v->damage(FL_DAMAGE_EXPOSE); +} + +extern const char* fl_ok; +extern const char* fl_cancel; + +int fl_color_chooser(const char* name, double& r, double& g, double& b) { + Fl_Window window(215,200,name); + Fl_Color_Chooser chooser(10, 10, 195, 115); + ColorChip ok_color(10, 130, 95, 25); + Fl_Return_Button ok_button(10, 165, 95, 25, fl_ok); + ColorChip cancel_color(110, 130, 95, 25); + cancel_color.r = uchar(255*r+.5); ok_color.r = cancel_color.r; + ok_color.g = cancel_color.g = uchar(255*g+.5); + ok_color.b = cancel_color.b = uchar(255*b+.5); + Fl_Button cancel_button(110, 165, 95, 25, fl_cancel); + window.resizable(chooser); + chooser.rgb(r,g,b); + chooser.callback(chooser_cb, &ok_color); + window.end(); + window.set_modal(); + window.hotspot(window); + window.show(); + while (window.shown()) { + Fl::wait(); + for (;;) { + Fl_Widget* o = Fl::readqueue(); + if (!o) break; + if (o == &ok_button) { + r = chooser.r(); + g = chooser.g(); + b = chooser.b(); + return 1; + } + if (o == &window || o == &cancel_button) return 0; + } + } + return 0; +} + +int fl_color_chooser(const char* name, uchar& r, uchar& g, uchar& b) { + double dr = r/255.0; + double dg = g/255.0; + double db = b/255.0; + if (fl_color_chooser(name,dr,dg,db)) { + r = uchar(255*dr+.5); + g = uchar(255*dg+.5); + b = uchar(255*db+.5); + return 1; + } + return 0; +} + +// +// End of "$Id: Fl_Color_Chooser.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Counter.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Counter.cxx new file mode 100644 index 000000000..53902236b --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Counter.cxx @@ -0,0 +1,197 @@ +// +// "$Id: Fl_Counter.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Counter widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include + +void Fl_Counter::draw() { + int i; Fl_Boxtype boxtype[5]; + Fl_Color selcolor; + + boxtype[0] = box(); + if (boxtype[0] == FL_UP_BOX) boxtype[0] = FL_DOWN_BOX; + if (boxtype[0] == FL_THIN_UP_BOX) boxtype[0] = FL_THIN_DOWN_BOX; + for (i=1; i<5; i++) + if (mouseobj == i) + boxtype[i] = fl_down(box()); + else + boxtype[i] = box(); + + int xx[5], ww[5]; + if (type() == FL_NORMAL_COUNTER) { + int W = w()*15/100; + xx[1] = x(); ww[1] = W; + xx[2] = x()+1*W; ww[2] = W; + xx[0] = x()+2*W; ww[0] = w()-4*W; + xx[3] = x()+w()-2*W; ww[3] = W; + xx[4] = x()+w()-1*W; ww[4] = W; + } else { + int W = w()*20/100; + xx[1] = 0; ww[1] = 0; + xx[2] = x(); ww[2] = W; + xx[0] = x()+W; ww[0] = w()-2*W; + xx[3] = x()+w()-1*W; ww[3] = W; + xx[4] = 0; ww[4] = 0; + } + + draw_box(boxtype[0], xx[0], y(), ww[0], h(), FL_BACKGROUND2_COLOR); + fl_font(textfont(), textsize()); + fl_color(active_r() ? textcolor() : fl_inactive(textcolor())); + char str[128]; format(str); + fl_draw(str, xx[0], y(), ww[0], h(), FL_ALIGN_CENTER); + if (Fl::focus() == this) draw_focus(boxtype[0], xx[0], y(), ww[0], h()); + if (!(damage()&FL_DAMAGE_ALL)) return; // only need to redraw text + + if (active_r()) + selcolor = labelcolor(); + else + selcolor = fl_inactive(labelcolor()); + + if (type() == FL_NORMAL_COUNTER) { + draw_box(boxtype[1], xx[1], y(), ww[1], h(), color()); + fl_draw_symbol("@-4<<", xx[1], y(), ww[1], h(), selcolor); + } + draw_box(boxtype[2], xx[2], y(), ww[2], h(), color()); + fl_draw_symbol("@-4<", xx[2], y(), ww[2], h(), selcolor); + draw_box(boxtype[3], xx[3], y(), ww[3], h(), color()); + fl_draw_symbol("@-4>", xx[3], y(), ww[3], h(), selcolor); + if (type() == FL_NORMAL_COUNTER) { + draw_box(boxtype[4], xx[4], y(), ww[4], h(), color()); + fl_draw_symbol("@-4>>", xx[4], y(), ww[4], h(), selcolor); + } +} + +void Fl_Counter::increment_cb() { + if (!mouseobj) return; + double v = value(); + switch (mouseobj) { + case 1: v -= lstep_; break; + case 2: v = increment(v, -1); break; + case 3: v = increment(v, 1); break; + case 4: v += lstep_; break; + } + handle_drag(clamp(round(v))); +} + +#define INITIALREPEAT .5 +#define REPEAT .1 + +void Fl_Counter::repeat_callback(void* v) { + Fl_Counter* b = (Fl_Counter*)v; + if (b->mouseobj) { + Fl::add_timeout(REPEAT, repeat_callback, b); + b->increment_cb(); + } +} + +int Fl_Counter::calc_mouseobj() { + if (type() == FL_NORMAL_COUNTER) { + int W = w()*15/100; + if (Fl::event_inside(x(), y(), W, h())) return 1; + if (Fl::event_inside(x()+W, y(), W, h())) return 2; + if (Fl::event_inside(x()+w()-2*W, y(), W, h())) return 3; + if (Fl::event_inside(x()+w()-W, y(), W, h())) return 4; + } else { + int W = w()*20/100; + if (Fl::event_inside(x(), y(), W, h())) return 2; + if (Fl::event_inside(x()+w()-W, y(), W, h())) return 3; + } + return -1; +} + +int Fl_Counter::handle(int event) { + int i; + switch (event) { + case FL_RELEASE: + if (mouseobj) { + Fl::remove_timeout(repeat_callback, this); + mouseobj = 0; + redraw(); + } + handle_release(); + return 1; + case FL_PUSH: + if (Fl::visible_focus()) Fl::focus(this); + handle_push(); + case FL_DRAG: + i = calc_mouseobj(); + if (i != mouseobj) { + Fl::remove_timeout(repeat_callback, this); + mouseobj = (uchar)i; + if (i) Fl::add_timeout(INITIALREPEAT, repeat_callback, this); + increment_cb(); + redraw(); + } + return 1; + case FL_KEYBOARD : + switch (Fl::event_key()) { + case FL_Left: + handle_drag(clamp(increment(value(),-1))); + return 1; + case FL_Right: + handle_drag(clamp(increment(value(),1))); + return 1; + default: + return 0; + } + // break not required because of switch... + case FL_FOCUS : + case FL_UNFOCUS : + if (Fl::visible_focus()) { + redraw(); + return 1; + } else return 0; + case FL_ENTER : + case FL_LEAVE : + return 1; + default: + return 0; + } +} + +Fl_Counter::~Fl_Counter() { + Fl::remove_timeout(repeat_callback, this); +} + +Fl_Counter::Fl_Counter(int X, int Y, int W, int H, const char* l) + : Fl_Valuator(X, Y, W, H, l) { + box(FL_UP_BOX); + selection_color(FL_INACTIVE_COLOR); // was FL_BLUE + align(FL_ALIGN_BOTTOM); + bounds(-1000000.0, 1000000.0); + Fl_Valuator::step(1, 10); + lstep_ = 1.0; + mouseobj = 0; + textfont_ = FL_HELVETICA; + textsize_ = (uchar)FL_NORMAL_SIZE; + textcolor_ = FL_FOREGROUND_COLOR; +} + +// +// End of "$Id: Fl_Counter.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Dial.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Dial.cxx new file mode 100644 index 000000000..af5a1b83a --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Dial.cxx @@ -0,0 +1,147 @@ +// +// "$Id: Fl_Dial.cxx 5472 2006-09-20 03:03:14Z mike $" +// +// Circular dial widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2006 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include +#include + +// All angles are measured with 0 to the right and counter-clockwise + +void Fl_Dial::draw(int X, int Y, int W, int H) { + if (damage()&FL_DAMAGE_ALL) draw_box(box(), X, Y, W, H, color()); + X += Fl::box_dx(box()); + Y += Fl::box_dy(box()); + W -= Fl::box_dw(box()); + H -= Fl::box_dh(box()); + double angle = (a2-a1)*(value()-minimum())/(maximum()-minimum()) + a1; + if (type() == FL_FILL_DIAL) { + // foo: draw this nicely in certain round box types + int foo = (box() > _FL_ROUND_UP_BOX && Fl::box_dx(box())); + if (foo) {X--; Y--; W+=2; H+=2;} + if (active_r()) fl_color(color()); + else fl_color(fl_inactive(color())); + fl_pie(X, Y, W, H, 270-a1, angle > a1 ? 360+270-angle : 270-360-angle); + if (active_r()) fl_color(selection_color()); + else fl_color(fl_inactive(selection_color())); + fl_pie(X, Y, W, H, 270-angle, 270-a1); + if (foo) { + if (active_r()) fl_color(FL_FOREGROUND_COLOR); + else fl_color(fl_inactive(FL_FOREGROUND_COLOR)); + fl_arc(X, Y, W, H, 0, 360); + } + return; + } + if (!(damage()&FL_DAMAGE_ALL)) { + if (active_r()) fl_color(color()); + else fl_color(fl_inactive(color())); + fl_pie(X+1, Y+1, W-2, H-2, 0, 360); + } + fl_push_matrix(); + fl_translate(X+W/2-.5, Y+H/2-.5); + fl_scale(W-1, H-1); + fl_rotate(45-angle); + if (active_r()) fl_color(selection_color()); + else fl_color(fl_inactive(selection_color())); + if (type()) { // FL_LINE_DIAL + fl_begin_polygon(); + fl_vertex(0.0, 0.0); + fl_vertex(-0.04, 0.0); + fl_vertex(-0.25, 0.25); + fl_vertex(0.0, 0.04); + fl_end_polygon(); + if (active_r()) fl_color(FL_FOREGROUND_COLOR); + else fl_color(fl_inactive(FL_FOREGROUND_COLOR)); + fl_begin_loop(); + fl_vertex(0.0, 0.0); + fl_vertex(-0.04, 0.0); + fl_vertex(-0.25, 0.25); + fl_vertex(0.0, 0.04); + fl_end_loop(); + } else { + fl_begin_polygon(); fl_circle(-0.20, 0.20, 0.07); fl_end_polygon(); + if (active_r()) fl_color(FL_FOREGROUND_COLOR); + else fl_color(fl_inactive(FL_FOREGROUND_COLOR)); + fl_begin_loop(); fl_circle(-0.20, 0.20, 0.07); fl_end_loop(); + } + fl_pop_matrix(); +} + +void Fl_Dial::draw() { + draw(x(), y(), w(), h()); + draw_label(); +} + +int Fl_Dial::handle(int event, int X, int Y, int W, int H) { + switch (event) { + case FL_PUSH: + handle_push(); + case FL_DRAG: { + int mx = (Fl::event_x()-X-W/2)*H; + int my = (Fl::event_y()-Y-H/2)*W; + if (!mx && !my) return 1; + double angle = 270-atan2((float)-my, (float)mx)*180/M_PI; + double oldangle = (a2-a1)*(value()-minimum())/(maximum()-minimum()) + a1; + while (angle < oldangle-180) angle += 360; + while (angle > oldangle+180) angle -= 360; + double val; + if ((a1= a1)) { + val = minimum(); + } else if ((a1= a2) : (angle <= a2)) { + val = maximum(); + } else { + val = minimum() + (maximum()-minimum())*(angle-a1)/(a2-a1); + } + handle_drag(clamp(round(val))); + } return 1; + case FL_RELEASE: + handle_release(); + return 1; + case FL_ENTER : + case FL_LEAVE : + return 1; + default: + return 0; + } +} + +int Fl_Dial::handle(int e) { + return handle(e, x(), y(), w(), h()); +} + +Fl_Dial::Fl_Dial(int X, int Y, int W, int H, const char* l) + : Fl_Valuator(X, Y, W, H, l) { + box(FL_OVAL_BOX); + selection_color(FL_INACTIVE_COLOR); // was 37 + a1 = 45; + a2 = 315; +} + +// +// End of "$Id: Fl_Dial.cxx 5472 2006-09-20 03:03:14Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Double_Window.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Double_Window.cxx new file mode 100644 index 000000000..4546d2424 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Double_Window.cxx @@ -0,0 +1,452 @@ +// +// "$Id: Fl_Double_Window.cxx 5829 2007-05-14 15:51:00Z matt $" +// +// Double-buffered window code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2007 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include +#include + +// On systems that support double buffering "naturally" the base +// Fl_Window class will probably do double-buffer and this subclass +// does nothing. + +#if USE_XDBE + +#include + +static int use_xdbe; + +static int can_xdbe() { + static int tried; + if (!tried) { + tried = 1; + int event_base, error_base; + if (!XdbeQueryExtension(fl_display, &event_base, &error_base)) return 0; + Drawable root = RootWindow(fl_display,fl_screen); + int numscreens = 1; + XdbeScreenVisualInfo *a = XdbeGetVisualInfo(fl_display,&root,&numscreens); + if (!a) return 0; + for (int j = 0; j < a->count; j++) + if (a->visinfo[j].visual == fl_visual->visualid + /*&& a->visinfo[j].perflevel > 0*/) {use_xdbe = 1; break;} + XdbeFreeVisualInfo(a); + } + return use_xdbe; +} +#endif + +void Fl_Double_Window::show() { + Fl_Window::show(); +} + +#ifdef WIN32 + +// Code used to switch output to an off-screen window. See macros in +// win32.H which save the old state in local variables. + +typedef struct { BYTE a; BYTE b; BYTE c; BYTE d; } FL_BLENDFUNCTION; +typedef BOOL (WINAPI* fl_alpha_blend_func) + (HDC,int,int,int,int,HDC,int,int,int,int,FL_BLENDFUNCTION); +static fl_alpha_blend_func fl_alpha_blend = NULL; +static FL_BLENDFUNCTION blendfunc = { 0, 0, 255, 1}; + +/* + * This function checks if the version of MSWindows that we + * curently run on supports alpha blending for bitmap transfers + * and finds the required function if so. + */ +char fl_can_do_alpha_blending() { + static char been_here = 0; + static char can_do = 0; + // do this test only once + if (been_here) return can_do; + been_here = 1; + // load the library that implements alpha blending + HMODULE hMod = LoadLibrary("MSIMG32.DLL"); + // give up if that doesn't exist (Win95?) + if (!hMod) return 0; + // now find the blending function inside that dll + fl_alpha_blend = (fl_alpha_blend_func)GetProcAddress(hMod, "AlphaBlend"); + // give up if we can't find it (Win95) + if (!fl_alpha_blend) return 0; + // we have the call, but does our display support alpha blending? + HDC dc = 0L;//fl_gc; + // get the current or the desktop's device context + if (!dc) dc = GetDC(0L); + if (!dc) return 0; + // check the device capabilities flags. However GetDeviceCaps + // does not return anything useful, so we have to do it manually: + + HBITMAP bm = CreateCompatibleBitmap(dc, 1, 1); + HDC new_gc = CreateCompatibleDC(dc); + int save = SaveDC(new_gc); + SelectObject(new_gc, bm); + /*COLORREF set = */ SetPixel(new_gc, 0, 0, 0x01010101); + BOOL alpha_ok = fl_alpha_blend(dc, 0, 0, 1, 1, new_gc, 0, 0, 1, 1, blendfunc); + RestoreDC(new_gc, save); + DeleteDC(new_gc); + DeleteObject(bm); + + if (!fl_gc) ReleaseDC(0L, dc); + if (alpha_ok) can_do = 1; + return can_do; +} + +HDC fl_makeDC(HBITMAP bitmap) { + HDC new_gc = CreateCompatibleDC(fl_gc); + SetTextAlign(new_gc, TA_BASELINE|TA_LEFT); + SetBkMode(new_gc, TRANSPARENT); +#if USE_COLORMAP + if (fl_palette) SelectPalette(new_gc, fl_palette, FALSE); +#endif + SelectObject(new_gc, bitmap); + return new_gc; +} + +void fl_copy_offscreen(int x,int y,int w,int h,HBITMAP bitmap,int srcx,int srcy) { + HDC new_gc = CreateCompatibleDC(fl_gc); + int save = SaveDC(new_gc); + SelectObject(new_gc, bitmap); + BitBlt(fl_gc, x, y, w, h, new_gc, srcx, srcy, SRCCOPY); + RestoreDC(new_gc, save); + DeleteDC(new_gc); +} + +void fl_copy_offscreen_with_alpha(int x,int y,int w,int h,HBITMAP bitmap,int srcx,int srcy) { + HDC new_gc = CreateCompatibleDC(fl_gc); + int save = SaveDC(new_gc); + SelectObject(new_gc, bitmap); + BOOL alpha_ok = 0; + // first try to alpha blend + if (fl_can_do_alpha_blending()) + alpha_ok = fl_alpha_blend(fl_gc, x, y, w, h, new_gc, srcx, srcy, w, h, blendfunc); + // if that failed (it shouldn,t), still copy the bitmap over, but now alpha is 1 + if (!alpha_ok) + BitBlt(fl_gc, x, y, w, h, new_gc, srcx, srcy, SRCCOPY); + RestoreDC(new_gc, save); + DeleteDC(new_gc); +} + +extern void fl_restore_clip(); + +#elif defined(__APPLE_QD__) + +char fl_can_do_alpha_blending() { + return 0; +} + +GWorldPtr fl_create_offscreen(int w, int h) { + GWorldPtr gw; + Rect bounds; + bounds.left=0; bounds.right=w; bounds.top=0; bounds.bottom=h; + QDErr err = NewGWorld(&gw, 0, &bounds, 0L, 0L, 0); // 'useTempMem' should not be used (says the Carbon port manual) + if ( err == -108 ) + { } +// fl_message( "The application memory is low. Please increase the initial memory assignment.\n" ); + if (err!=noErr || gw==0L) return 0L; + return gw; +} + +void fl_copy_offscreen(int x,int y,int w,int h,GWorldPtr gWorld,int srcx,int srcy) { + Rect src; + if ( !gWorld ) return; + src.top = srcy; src.left = srcx; src.bottom = srcy+h; src.right = srcx+w; + Rect dst; + GrafPtr dstPort; GetPort(&dstPort); + dst.top = y; dst.left = x; dst.bottom = y+h; dst.right = x+w; + RGBColor rgb, oldbg, oldfg; + GetForeColor(&oldfg); + GetBackColor(&oldbg); + rgb.red = 0xffff; rgb.green = 0xffff; rgb.blue = 0xffff; + RGBBackColor( &rgb ); + rgb.red = 0x0000; rgb.green = 0x0000; rgb.blue = 0x0000; + RGBForeColor( &rgb ); + CopyBits(GetPortBitMapForCopyBits(gWorld), GetPortBitMapForCopyBits(dstPort), &src, &dst, srcCopy, 0L); + RGBBackColor(&oldbg); + RGBForeColor(&oldfg); +} + +void fl_delete_offscreen(GWorldPtr gWorld) { + DisposeGWorld(gWorld); +} + +static GrafPtr prevPort; +static GDHandle prevGD; + +void fl_begin_offscreen(GWorldPtr gWorld) { + GetGWorld( &prevPort, &prevGD ); + if ( gWorld ) + { + SetGWorld( gWorld, 0 ); // sets the correct port + PixMapHandle pm = GetGWorldPixMap(gWorld); + Boolean ret = LockPixels(pm); + if ( ret == false ) + { + Rect rect; + GetPortBounds( gWorld, &rect ); + UpdateGWorld( &gWorld, 0, &rect, 0, 0, 0 ); + pm = GetGWorldPixMap( gWorld ); + LockPixels( pm ); + } + fl_window = 0; + } + fl_push_no_clip(); +} + +void fl_end_offscreen() { + GWorldPtr currPort; + GDHandle currGD; + GetGWorld( &currPort, &currGD ); + fl_pop_clip(); + PixMapHandle pm = GetGWorldPixMap(currPort); + UnlockPixels(pm); + SetGWorld( prevPort, prevGD ); + fl_window = GetWindowFromPort( prevPort ); +} + +extern void fl_restore_clip(); + +#elif defined(__APPLE_QUARTZ__) + +char fl_can_do_alpha_blending() { + return 1; +} + +Fl_Offscreen fl_create_offscreen(int w, int h) { + void *data = calloc(w*h,4); + CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB(); + CGContextRef ctx = CGBitmapContextCreate( + data, w, h, 8, w*4, lut, kCGImageAlphaNoneSkipLast); + CGColorSpaceRelease(lut); + return (Fl_Offscreen)ctx; +} + +Fl_Offscreen fl_create_offscreen_with_alpha(int w, int h) { + void *data = calloc(w*h,4); + CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB(); + CGContextRef ctx = CGBitmapContextCreate( + data, w, h, 8, w*4, lut, kCGImageAlphaPremultipliedLast); + CGColorSpaceRelease(lut); + return (Fl_Offscreen)ctx; +} + +void fl_copy_offscreen(int x,int y,int w,int h,Fl_Offscreen osrc,int srcx,int srcy) { + CGContextRef src = (CGContextRef)osrc; + void *data = CGBitmapContextGetData(src); + int sw = CGBitmapContextGetWidth(src); + int sh = CGBitmapContextGetHeight(src); + CGImageAlphaInfo alpha = CGBitmapContextGetAlphaInfo(src); + CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB(); + CGDataProviderRef src_bytes = CGDataProviderCreateWithData( 0L, data, sw*sh*4, 0L); + CGImageRef img = CGImageCreate( sw, sh, 8, 4*8, 4*sw, lut, alpha, + src_bytes, 0L, false, kCGRenderingIntentDefault); + // fl_push_clip(); + CGRect rect = { { x, y }, { w, h } }; + Fl_X::q_begin_image(rect, srcx, srcy, sw, sh); + CGContextDrawImage(fl_gc, rect, img); + Fl_X::q_end_image(); + CGImageRelease(img); + CGColorSpaceRelease(lut); + CGDataProviderRelease(src_bytes); +} + +void fl_delete_offscreen(Fl_Offscreen ctx) { + if (!ctx) return; + void *data = CGBitmapContextGetData((CGContextRef)ctx); + CGContextRelease((CGContextRef)ctx); + if (!data) return; + free(data); +} + +const int stack_max = 16; +static int stack_ix = 0; +static CGContextRef stack_gc[stack_max]; +static Window stack_window[stack_max]; + +void fl_begin_offscreen(Fl_Offscreen ctx) { + if (stack_ix0) + stack_ix--; + else + fprintf(stderr, "FLTK CGContext Stack underflow error\n"); + if (stack_ixother_xid) { +#if USE_XDBE + if (can_xdbe()) { + myi->other_xid = + XdbeAllocateBackBufferName(fl_display, fl_xid(this), XdbeCopied); + myi->backbuffer_bad = 1; + } else +#endif +#ifdef __APPLE_QD__ + if ( ( !QDIsPortBuffered( GetWindowPort(myi->xid) ) ) + || force_doublebuffering_ ) { + myi->other_xid = fl_create_offscreen(w(), h()); + clear_damage(FL_DAMAGE_ALL); + } +#elif defined(__APPLE_QUARTZ__) + if (force_doublebuffering_) { + myi->other_xid = fl_create_offscreen(w(), h()); + clear_damage(FL_DAMAGE_ALL); + } +#else + myi->other_xid = fl_create_offscreen(w(), h()); + clear_damage(FL_DAMAGE_ALL); +#endif + } +#if USE_XDBE + if (use_xdbe) { + if (myi->backbuffer_bad) { + // Make sure we do a complete redraw... + if (myi->region) {XDestroyRegion(myi->region); myi->region = 0;} + clear_damage(FL_DAMAGE_ALL); + myi->backbuffer_bad = 0; + } + + // Redraw as needed... + if (damage()) { + fl_clip_region(myi->region); myi->region = 0; + fl_window = myi->other_xid; + draw(); + fl_window = myi->xid; + } + + // Copy contents of back buffer to window... + XdbeSwapInfo s; + s.swap_window = fl_xid(this); + s.swap_action = XdbeCopied; + XdbeSwapBuffers(fl_display, &s, 1); + return; + } else +#endif + if (damage() & ~FL_DAMAGE_EXPOSE) { + fl_clip_region(myi->region); myi->region = 0; +#ifdef WIN32 + HDC _sgc = fl_gc; + fl_gc = fl_makeDC(myi->other_xid); + int save = SaveDC(fl_gc); + fl_restore_clip(); // duplicate region into new gc + draw(); + RestoreDC(fl_gc, save); + DeleteDC(fl_gc); + fl_gc = _sgc; +#elif defined(__APPLE__) + if ( myi->other_xid ) { + fl_begin_offscreen( myi->other_xid ); + fl_clip_region( 0 ); + draw(); + fl_end_offscreen(); + } else { + draw(); + } +#else // X: + fl_window = myi->other_xid; + draw(); + fl_window = myi->xid; +#endif + } + if (eraseoverlay) fl_clip_region(0); + // on Irix (at least) it is faster to reduce the area copied to + // the current clip region: + int X,Y,W,H; fl_clip_box(0,0,w(),h(),X,Y,W,H); + if (myi->other_xid) fl_copy_offscreen(X, Y, W, H, myi->other_xid, X, Y); +} + +void Fl_Double_Window::resize(int X,int Y,int W,int H) { + int ow = w(); + int oh = h(); + Fl_Window::resize(X,Y,W,H); +#if USE_XDBE + if (use_xdbe) return; +#endif + Fl_X* myi = Fl_X::i(this); + if (myi && myi->other_xid && (ow != w() || oh != h())) { + fl_delete_offscreen(myi->other_xid); + myi->other_xid = 0; + } +} + +void Fl_Double_Window::hide() { + Fl_X* myi = Fl_X::i(this); + if (myi && myi->other_xid) { +#if USE_XDBE + if (!use_xdbe) +#endif + fl_delete_offscreen(myi->other_xid); + } + Fl_Window::hide(); +} + +Fl_Double_Window::~Fl_Double_Window() { + hide(); +} + +// +// End of "$Id: Fl_Double_Window.cxx 5829 2007-05-14 15:51:00Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_File_Browser.cxx b/plugins/zynaddsubfx/fltk/src/Fl_File_Browser.cxx new file mode 100644 index 000000000..35eee8345 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_File_Browser.cxx @@ -0,0 +1,639 @@ +// +// "$Id: Fl_File_Browser.cxx 5635 2007-01-23 15:02:00Z mike $" +// +// Fl_File_Browser routines. +// +// Copyright 1999-2006 by Michael Sweet. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +// Contents: +// +// Fl_File_Browser::full_height() - Return the height of the list. +// Fl_File_Browser::item_height() - Return the height of a list item. +// Fl_File_Browser::item_width() - Return the width of a list item. +// Fl_File_Browser::item_draw() - Draw a list item. +// Fl_File_Browser::Fl_File_Browser() - Create a Fl_File_Browser widget. +// Fl_File_Browser::load() - Load a directory into the browser. +// Fl_File_Browser::filter() - Set the filename filter. +// + +// +// Include necessary header files... +// + +#include +#include +#include +#include +#include +#include "flstring.h" + +#ifdef __CYGWIN__ +# include +#elif defined(WIN32) +# include +# include +// Apparently Borland C++ defines DIRECTORY in , which +// interfers with the Fl_File_Icon enumeration of the same name. +# ifdef DIRECTORY +# undef DIRECTORY +# endif // DIRECTORY +#endif // __CYGWIN__ + +#ifdef __EMX__ +# define INCL_DOS +# define INCL_DOSMISC +# include +#endif // __EMX__ + +// CodeWarrior (__MWERKS__) gets its include paths confused, so we +// temporarily disable this... +#if defined(__APPLE__) && !defined(__MWERKS__) +# include +# include +# include +#endif // __APPLE__ && !__MWERKS__ + + +// +// FL_BLINE definition from "Fl_Browser.cxx"... +// + +#define SELECTED 1 +#define NOTDISPLAYED 2 + +struct FL_BLINE // data is in a linked list of these +{ + FL_BLINE *prev; // Previous item in list + FL_BLINE *next; // Next item in list + void *data; // Pointer to data (function) + short length; // sizeof(txt)-1, may be longer than string + char flags; // selected, displayed + char txt[1]; // start of allocated array +}; + + +// +// 'Fl_File_Browser::full_height()' - Return the height of the list. +// + +int // O - Height in pixels +Fl_File_Browser::full_height() const +{ + int i, // Looping var + th; // Total height of list. + + + for (i = 0, th = 0; i < size(); i ++) + th += item_height(find_line(i)); + + return (th); +} + + +// +// 'Fl_File_Browser::item_height()' - Return the height of a list item. +// + +int // O - Height in pixels +Fl_File_Browser::item_height(void *p) const // I - List item data +{ + FL_BLINE *line; // Pointer to line + char *t; // Pointer into text + int height; // Width of line + int textheight; // Height of text + + + // Figure out the standard text height... + fl_font(textfont(), textsize()); + textheight = fl_height(); + + // We always have at least 1 line... + height = textheight; + + // Scan for newlines... + line = (FL_BLINE *)p; + + if (line != NULL) + for (t = line->txt; *t != '\0'; t ++) + if (*t == '\n') + height += textheight; + + // If we have enabled icons then add space for them... + if (Fl_File_Icon::first() != NULL && height < iconsize_) + height = iconsize_; + + // Add space for the selection border.. + height += 2; + + // Return the height + return (height); +} + + +// +// 'Fl_File_Browser::item_width()' - Return the width of a list item. +// + +int // O - Width in pixels +Fl_File_Browser::item_width(void *p) const // I - List item data +{ + int i; // Looping var + FL_BLINE *line; // Pointer to line + char *t, // Pointer into text + *ptr, // Pointer into fragment + fragment[10240]; // Fragment of text + int width, // Width of line + tempwidth; // Width of fragment + int column; // Current column + const int *columns; // Columns + + + // Scan for newlines... + line = (FL_BLINE *)p; + columns = column_widths(); + + // Set the font and size... + if (line->txt[strlen(line->txt) - 1] == '/') + fl_font(textfont() | FL_BOLD, textsize()); + else + fl_font(textfont(), textsize()); + + if (strchr(line->txt, '\n') == NULL && + strchr(line->txt, column_char()) == NULL) + { + // Do a fast width calculation... + width = (int)fl_width(line->txt); + } + else + { + // More than 1 line or have columns; find the maximum width... + width = 0; + tempwidth = 0; + column = 0; + + for (t = line->txt, ptr = fragment; *t != '\0'; t ++) + if (*t == '\n') + { + // Newline - nul terminate this fragment and get the width... + *ptr = '\0'; + + tempwidth += (int)fl_width(fragment); + + // Update the max width as needed... + if (tempwidth > width) + width = tempwidth; + + // Point back to the start of the fragment... + ptr = fragment; + tempwidth = 0; + column = 0; + } + else if (*t == column_char()) + { + // Advance to the next column... + column ++; + if (columns) + { + for (i = 0, tempwidth = 0; i < column && columns[i]; i ++) + tempwidth += columns[i]; + } + else + tempwidth = column * (int)(fl_height() * 0.6 * 8.0); + + if (tempwidth > width) + width = tempwidth; + + ptr = fragment; + } + else + *ptr++ = *t; + + if (ptr > fragment) + { + // Nul terminate this fragment and get the width... + *ptr = '\0'; + + tempwidth += (int)fl_width(fragment); + + // Update the max width as needed... + if (tempwidth > width) + width = tempwidth; + } + } + + // If we have enabled icons then add space for them... + if (Fl_File_Icon::first() != NULL) + width += iconsize_ + 8; + + // Add space for the selection border.. + width += 2; + + // Return the width + return (width); +} + + +// +// 'Fl_File_Browser::item_draw()' - Draw a list item. +// + +void +Fl_File_Browser::item_draw(void *p, // I - List item data + int X, // I - Upper-lefthand X coordinate + int Y, // I - Upper-lefthand Y coordinate + int W, // I - Width of item + int) const // I - Height of item +{ + int i; // Looping var + FL_BLINE *line; // Pointer to line + Fl_Color c; // Text color + char *t, // Pointer into text + *ptr, // Pointer into fragment + fragment[10240]; // Fragment of text + int width, // Width of line + height; // Height of line + int column; // Current column + const int *columns; // Columns + + + // Draw the list item text... + line = (FL_BLINE *)p; + + if (line->txt[strlen(line->txt) - 1] == '/') + fl_font(textfont() | FL_BOLD, textsize()); + else + fl_font(textfont(), textsize()); + + if (line->flags & SELECTED) + c = fl_contrast(textcolor(), selection_color()); + else + c = textcolor(); + + if (Fl_File_Icon::first() == NULL) + { + // No icons, just draw the text... + X ++; + W -= 2; + } + else + { + // Draw the icon if it is set... + if (line->data) + ((Fl_File_Icon *)line->data)->draw(X, Y, iconsize_, iconsize_, + (line->flags & SELECTED) ? FL_YELLOW : + FL_LIGHT2, + active_r()); + + // Draw the text offset to the right... + X += iconsize_ + 9; + W -= iconsize_ - 10; + + // Center the text vertically... + height = fl_height(); + + for (t = line->txt; *t != '\0'; t ++) + if (*t == '\n') + height += fl_height(); + + if (height < iconsize_) + Y += (iconsize_ - height) / 2; + } + + // Draw the text... + line = (FL_BLINE *)p; + columns = column_widths(); + width = 0; + column = 0; + + if (active_r()) + fl_color(c); + else + fl_color(fl_inactive(c)); + + for (t = line->txt, ptr = fragment; *t != '\0'; t ++) + if (*t == '\n') + { + // Newline - nul terminate this fragment and draw it... + *ptr = '\0'; + + fl_draw(fragment, X + width, Y, W - width, fl_height(), + (Fl_Align)(FL_ALIGN_LEFT | FL_ALIGN_CLIP), 0, 0); + + // Point back to the start of the fragment... + ptr = fragment; + width = 0; + Y += fl_height(); + column = 0; + } + else if (*t == column_char()) + { + // Tab - nul terminate this fragment and draw it... + *ptr = '\0'; + + int cW = W - width; // Clip width... + + if (columns) + { + // Try clipping inside this column... + for (i = 0; i < column && columns[i]; i ++); + + if (columns[i]) + cW = columns[i]; + } + + fl_draw(fragment, X + width, Y, cW, fl_height(), + (Fl_Align)(FL_ALIGN_LEFT | FL_ALIGN_CLIP), 0, 0); + + // Advance to the next column... + column ++; + if (columns) + { + for (i = 0, width = 0; i < column && columns[i]; i ++) + width += columns[i]; + } + else + width = column * (int)(fl_height() * 0.6 * 8.0); + + ptr = fragment; + } + else + *ptr++ = *t; + + if (ptr > fragment) + { + // Nul terminate this fragment and draw it... + *ptr = '\0'; + + fl_draw(fragment, X + width, Y, W - width, fl_height(), + (Fl_Align)(FL_ALIGN_LEFT | FL_ALIGN_CLIP), 0, 0); + } +} + + +// +// 'Fl_File_Browser::Fl_File_Browser()' - Create a Fl_File_Browser widget. +// + +Fl_File_Browser::Fl_File_Browser(int X, // I - Upper-lefthand X coordinate + int Y, // I - Upper-lefthand Y coordinate + int W, // I - Width in pixels + int H, // I - Height in pixels + const char *l) // I - Label text + : Fl_Browser(X, Y, W, H, l) +{ + // Initialize the filter pattern, current directory, and icon size... + pattern_ = "*"; + directory_ = ""; + iconsize_ = (uchar)(3 * textsize() / 2); + filetype_ = FILES; +} + + +// +// 'Fl_File_Browser::load()' - Load a directory into the browser. +// + +int // O - Number of files loaded +Fl_File_Browser::load(const char *directory,// I - Directory to load + Fl_File_Sort_F *sort) // I - Sort function to use +{ + int i; // Looping var + int num_files; // Number of files in directory + int num_dirs; // Number of directories in list + char filename[4096]; // Current file + Fl_File_Icon *icon; // Icon to use + + +// printf("Fl_File_Browser::load(\"%s\")\n", directory); + + clear(); + + directory_ = directory; + + if (!directory) + return (0); + + if (directory_[0] == '\0') + { + // + // No directory specified; for UNIX list all mount points. For DOS + // list all valid drive letters... + // + + num_files = 0; + if ((icon = Fl_File_Icon::find("any", Fl_File_Icon::DEVICE)) == NULL) + icon = Fl_File_Icon::find("any", Fl_File_Icon::DIRECTORY); + +#ifdef WIN32 +# ifdef __CYGWIN__ + // + // Cygwin provides an implementation of setmntent() to get the list + // of available drives... + // + FILE *m = setmntent("/-not-used-", "r"); + struct mntent *p; + + while ((p = getmntent (m)) != NULL) { + add(p->mnt_dir, icon); + num_files ++; + } + + endmntent(m); +# else + // + // Normal WIN32 code uses drive bits... + // + DWORD drives; // Drive available bits + + drives = GetLogicalDrives(); + for (i = 'A'; i <= 'Z'; i ++, drives >>= 1) + if (drives & 1) + { + sprintf(filename, "%c:/", i); + + if (i < 'C') // see also: GetDriveType and GetVolumeInformation in WIN32 + add(filename, icon); + else + add(filename, icon); + + num_files ++; + } +# endif // __CYGWIN__ +#elif defined(__EMX__) + // + // OS/2 code uses drive bits... + // + ULONG curdrive; // Current drive + ULONG drives; // Drive available bits + int start = 3; // 'C' (MRS - dunno if this is correct!) + + + DosQueryCurrentDisk(&curdrive, &drives); + drives >>= start - 1; + for (i = 'A'; i <= 'Z'; i ++, drives >>= 1) + if (drives & 1) + { + sprintf(filename, "%c:/", i); + add(filename, icon); + + num_files ++; + } +#elif defined(__APPLE__) && !defined(__MWERKS__) + // MacOS X and Darwin use getfsstat() system call... + int numfs; // Number of file systems + struct statfs *fs; // Buffer for file system info + + + // We always have the root filesystem. + add("/", icon); + + // Get the mounted filesystems... + numfs = getfsstat(NULL, 0, MNT_NOWAIT); + if (numfs > 0) { + // We have file systems, get them... + fs = new struct statfs[numfs]; + getfsstat(fs, sizeof(struct statfs) * numfs, MNT_NOWAIT); + + // Add filesystems to the list... + for (i = 0; i < numfs; i ++) { + // Ignore "/", "/dev", and "/.vol"... + if (fs[i].f_mntonname[1] && strcmp(fs[i].f_mntonname, "/dev") && + strcmp(fs[i].f_mntonname, "/.vol")) { + snprintf(filename, sizeof(filename), "%s/", fs[i].f_mntonname); + add(filename, icon); + } + num_files ++; + } + + // Free the memory used for the file system info array... + delete[] fs; + } +#else + // + // UNIX code uses /etc/fstab or similar... + // + FILE *mtab; // /etc/mtab or /etc/mnttab file + char line[1024]; // Input line + + // + // Open the file that contains a list of mounted filesystems... + // + + mtab = fopen("/etc/mnttab", "r"); // Fairly standard + if (mtab == NULL) + mtab = fopen("/etc/mtab", "r"); // More standard + if (mtab == NULL) + mtab = fopen("/etc/fstab", "r"); // Otherwise fallback to full list + if (mtab == NULL) + mtab = fopen("/etc/vfstab", "r"); // Alternate full list file + + if (mtab != NULL) + { + while (fgets(line, sizeof(line), mtab) != NULL) + { + if (line[0] == '#' || line[0] == '\n') + continue; + if (sscanf(line, "%*s%4095s", filename) != 1) + continue; + + strlcat(filename, "/", sizeof(filename)); + +// printf("Fl_File_Browser::load() - adding \"%s\" to list...\n", filename); + add(filename, icon); + num_files ++; + } + + fclose(mtab); + } +#endif // WIN32 || __EMX__ + } + else + { + dirent **files; // Files in in directory + + + // + // Build the file list... + // + +#if (defined(WIN32) && !defined(__CYGWIN__)) || defined(__EMX__) + strlcpy(filename, directory_, sizeof(filename)); + i = strlen(filename) - 1; + + if (i == 2 && filename[1] == ':' && + (filename[2] == '/' || filename[2] == '\\')) + filename[2] = '/'; + else if (filename[i] != '/' && filename[i] != '\\') + strlcat(filename, "/", sizeof(filename)); + + num_files = fl_filename_list(filename, &files, sort); +#else + num_files = fl_filename_list(directory_, &files, sort); +#endif /* WIN32 || __EMX__ */ + + if (num_files <= 0) + return (0); + + for (i = 0, num_dirs = 0; i < num_files; i ++) { + if (strcmp(files[i]->d_name, "./")) { + snprintf(filename, sizeof(filename), "%s/%s", directory_, + files[i]->d_name); + + icon = Fl_File_Icon::find(filename); + if ((icon && icon->type() == Fl_File_Icon::DIRECTORY) || + _fl_filename_isdir_quick(filename)) { + num_dirs ++; + insert(num_dirs, files[i]->d_name, icon); + } else if (filetype_ == FILES && + fl_filename_match(files[i]->d_name, pattern_)) { + add(files[i]->d_name, icon); + } + } + + free(files[i]); + } + + free(files); + } + + return (num_files); +} + + +// +// 'Fl_File_Browser::filter()' - Set the filename filter. +// + +void +Fl_File_Browser::filter(const char *pattern) // I - Pattern string +{ + // If pattern is NULL set the pattern to "*"... + if (pattern) + pattern_ = pattern; + else + pattern_ = "*"; +} + + +// +// End of "$Id: Fl_File_Browser.cxx 5635 2007-01-23 15:02:00Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_File_Chooser.cxx b/plugins/zynaddsubfx/fltk/src/Fl_File_Chooser.cxx new file mode 100644 index 000000000..ef66b5c71 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_File_Chooser.cxx @@ -0,0 +1,444 @@ +// +// "$Id: Fl_File_Chooser.cxx 6092 2008-04-11 12:57:37Z matt $" +// +// Fl_File_Chooser dialog for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// generated by Fast Light User Interface Designer (fluid) version 1.0108 + +#include "../FL/Fl_File_Chooser.H" +#include + +void Fl_File_Chooser::cb_window_i(Fl_Double_Window*, void*) { + fileName->value(""); +fileList->deselect(); +Fl::remove_timeout((Fl_Timeout_Handler)previewCB, this); +window->hide(); +} +void Fl_File_Chooser::cb_window(Fl_Double_Window* o, void* v) { + ((Fl_File_Chooser*)(o->user_data()))->cb_window_i(o,v); +} + +void Fl_File_Chooser::cb_showChoice_i(Fl_Choice*, void*) { + showChoiceCB(); +} +void Fl_File_Chooser::cb_showChoice(Fl_Choice* o, void* v) { + ((Fl_File_Chooser*)(o->parent()->parent()->user_data()))->cb_showChoice_i(o,v); +} + +void Fl_File_Chooser::cb_favoritesButton_i(Fl_Menu_Button*, void*) { + favoritesButtonCB(); +} +void Fl_File_Chooser::cb_favoritesButton(Fl_Menu_Button* o, void* v) { + ((Fl_File_Chooser*)(o->parent()->parent()->user_data()))->cb_favoritesButton_i(o,v); +} + +void Fl_File_Chooser::cb_newButton_i(Fl_Button*, void*) { + newdir(); +} +void Fl_File_Chooser::cb_newButton(Fl_Button* o, void* v) { + ((Fl_File_Chooser*)(o->parent()->parent()->user_data()))->cb_newButton_i(o,v); +} + +#include +static unsigned char idata_new[] = +{0,0,120,0,132,0,2,1,1,254,1,128,49,128,49,128,253,128,253,128,49,128,49, +128,1,128,1,128,255,255,0,0}; +static Fl_Bitmap image_new(idata_new, 16, 16); + +void Fl_File_Chooser::cb__i(Fl_Tile*, void*) { + update_preview(); +} +void Fl_File_Chooser::cb_(Fl_Tile* o, void* v) { + ((Fl_File_Chooser*)(o->parent()->user_data()))->cb__i(o,v); +} + +void Fl_File_Chooser::cb_fileList_i(Fl_File_Browser*, void*) { + fileListCB(); +} +void Fl_File_Chooser::cb_fileList(Fl_File_Browser* o, void* v) { + ((Fl_File_Chooser*)(o->parent()->parent()->user_data()))->cb_fileList_i(o,v); +} + +void Fl_File_Chooser::cb_previewButton_i(Fl_Check_Button*, void*) { + preview(previewButton->value()); +} +void Fl_File_Chooser::cb_previewButton(Fl_Check_Button* o, void* v) { + ((Fl_File_Chooser*)(o->parent()->parent()->parent()->user_data()))->cb_previewButton_i(o,v); +} + +void Fl_File_Chooser::cb_fileName_i(Fl_File_Input*, void*) { + fileNameCB(); +} +void Fl_File_Chooser::cb_fileName(Fl_File_Input* o, void* v) { + ((Fl_File_Chooser*)(o->parent()->parent()->user_data()))->cb_fileName_i(o,v); +} + +void Fl_File_Chooser::cb_okButton_i(Fl_Return_Button*, void*) { + window->hide(); + +// Do any callback that is registered... +if (callback_) + (*callback_)(this, data_); +} +void Fl_File_Chooser::cb_okButton(Fl_Return_Button* o, void* v) { + ((Fl_File_Chooser*)(o->parent()->parent()->parent()->user_data()))->cb_okButton_i(o,v); +} + +void Fl_File_Chooser::cb_cancelButton_i(Fl_Button*, void*) { + fileName->value(""); +fileList->deselect(); +Fl::remove_timeout((Fl_Timeout_Handler)previewCB, this); +window->hide(); +} +void Fl_File_Chooser::cb_cancelButton(Fl_Button* o, void* v) { + ((Fl_File_Chooser*)(o->parent()->parent()->parent()->user_data()))->cb_cancelButton_i(o,v); +} + +void Fl_File_Chooser::cb_favList_i(Fl_File_Browser*, void*) { + favoritesCB(favList); +} +void Fl_File_Chooser::cb_favList(Fl_File_Browser* o, void* v) { + ((Fl_File_Chooser*)(o->parent()->user_data()))->cb_favList_i(o,v); +} + +void Fl_File_Chooser::cb_favUpButton_i(Fl_Button*, void*) { + favoritesCB(favUpButton); +} +void Fl_File_Chooser::cb_favUpButton(Fl_Button* o, void* v) { + ((Fl_File_Chooser*)(o->parent()->parent()->user_data()))->cb_favUpButton_i(o,v); +} + +void Fl_File_Chooser::cb_favDeleteButton_i(Fl_Button*, void*) { + favoritesCB(favDeleteButton); +} +void Fl_File_Chooser::cb_favDeleteButton(Fl_Button* o, void* v) { + ((Fl_File_Chooser*)(o->parent()->parent()->user_data()))->cb_favDeleteButton_i(o,v); +} + +void Fl_File_Chooser::cb_favDownButton_i(Fl_Button*, void*) { + favoritesCB(favDownButton); +} +void Fl_File_Chooser::cb_favDownButton(Fl_Button* o, void* v) { + ((Fl_File_Chooser*)(o->parent()->parent()->user_data()))->cb_favDownButton_i(o,v); +} + +void Fl_File_Chooser::cb_favCancelButton_i(Fl_Button*, void*) { + favWindow->hide(); +} +void Fl_File_Chooser::cb_favCancelButton(Fl_Button* o, void* v) { + ((Fl_File_Chooser*)(o->parent()->parent()->user_data()))->cb_favCancelButton_i(o,v); +} + +void Fl_File_Chooser::cb_favOkButton_i(Fl_Return_Button*, void*) { + favoritesCB(favOkButton); +} +void Fl_File_Chooser::cb_favOkButton(Fl_Return_Button* o, void* v) { + ((Fl_File_Chooser*)(o->parent()->parent()->user_data()))->cb_favOkButton_i(o,v); +} + +Fl_File_Chooser::Fl_File_Chooser(const char *d, const char *p, int t, const char *title) { + Fl_Group *prev_current = Fl_Group::current(); + { window = new Fl_Double_Window(490, 380, "Choose File"); + window->callback((Fl_Callback*)cb_window, (void*)(this)); + { Fl_Group* o = new Fl_Group(10, 10, 470, 25); + { showChoice = new Fl_Choice(65, 10, 215, 25, "Show:"); + showChoice->down_box(FL_BORDER_BOX); + showChoice->labelfont(1); + showChoice->callback((Fl_Callback*)cb_showChoice); + Fl_Group::current()->resizable(showChoice); + showChoice->label(show_label); + } // Fl_Choice* showChoice + { favoritesButton = new Fl_Menu_Button(290, 10, 155, 25, "Favorites"); + favoritesButton->down_box(FL_BORDER_BOX); + favoritesButton->callback((Fl_Callback*)cb_favoritesButton); + favoritesButton->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE); + favoritesButton->label(favorites_label); + } // Fl_Menu_Button* favoritesButton + { Fl_Button* o = newButton = new Fl_Button(455, 10, 25, 25); + newButton->image(image_new); + newButton->labelsize(8); + newButton->callback((Fl_Callback*)cb_newButton); + o->tooltip(new_directory_tooltip); + } // Fl_Button* newButton + o->end(); + } // Fl_Group* o + { Fl_Tile* o = new Fl_Tile(10, 45, 470, 225); + o->callback((Fl_Callback*)cb_); + { fileList = new Fl_File_Browser(10, 45, 295, 225); + fileList->type(2); + fileList->callback((Fl_Callback*)cb_fileList); + fileList->window()->hotspot(fileList); + } // Fl_File_Browser* fileList + { previewBox = new Fl_Box(305, 45, 175, 225, "?"); + previewBox->box(FL_DOWN_BOX); + previewBox->labelsize(100); + previewBox->align(FL_ALIGN_CLIP|FL_ALIGN_INSIDE); + } // Fl_Box* previewBox + o->end(); + Fl_Group::current()->resizable(o); + } // Fl_Tile* o + { Fl_Group* o = new Fl_Group(10, 275, 470, 95); + { Fl_Group* o = new Fl_Group(10, 275, 470, 20); + { previewButton = new Fl_Check_Button(10, 275, 73, 20, "Preview"); + previewButton->down_box(FL_DOWN_BOX); + previewButton->value(1); + previewButton->shortcut(0x80070); + previewButton->callback((Fl_Callback*)cb_previewButton); + previewButton->label(preview_label); + } // Fl_Check_Button* previewButton + { Fl_Box* o = new Fl_Box(115, 275, 365, 20); + Fl_Group::current()->resizable(o); + } // Fl_Box* o + o->end(); + } // Fl_Group* o + { fileName = new Fl_File_Input(115, 300, 365, 35); + fileName->labelfont(1); + fileName->callback((Fl_Callback*)cb_fileName); + fileName->when(FL_WHEN_ENTER_KEY); + Fl_Group::current()->resizable(fileName); + fileName->when(FL_WHEN_CHANGED | FL_WHEN_ENTER_KEY); + } // Fl_File_Input* fileName + { Fl_Box* o = new Fl_Box(10, 310, 105, 25, "Filename:"); + o->labelfont(1); + o->align(FL_ALIGN_RIGHT|FL_ALIGN_INSIDE); + o->label(filename_label); + } // Fl_Box* o + { Fl_Group* o = new Fl_Group(10, 345, 470, 25); + { okButton = new Fl_Return_Button(313, 345, 85, 25, "OK"); + okButton->callback((Fl_Callback*)cb_okButton); + okButton->label(fl_ok); + } // Fl_Return_Button* okButton + { Fl_Button* o = cancelButton = new Fl_Button(408, 345, 72, 25, "Cancel"); + cancelButton->callback((Fl_Callback*)cb_cancelButton); + o->label(fl_cancel); + } // Fl_Button* cancelButton + { Fl_Box* o = new Fl_Box(10, 345, 30, 25); + Fl_Group::current()->resizable(o); + } // Fl_Box* o + o->end(); + } // Fl_Group* o + o->end(); + } // Fl_Group* o + if (title) window->label(title); + window->set_modal(); + window->end(); + } // Fl_Double_Window* window + { favWindow = new Fl_Double_Window(355, 150, "Manage Favorites"); + favWindow->user_data((void*)(this)); + { favList = new Fl_File_Browser(10, 10, 300, 95); + favList->type(2); + favList->callback((Fl_Callback*)cb_favList); + Fl_Group::current()->resizable(favList); + } // Fl_File_Browser* favList + { Fl_Group* o = new Fl_Group(320, 10, 25, 95); + { favUpButton = new Fl_Button(320, 10, 25, 25, "@8>"); + favUpButton->callback((Fl_Callback*)cb_favUpButton); + } // Fl_Button* favUpButton + { favDeleteButton = new Fl_Button(320, 45, 25, 25, "X"); + favDeleteButton->labelfont(1); + favDeleteButton->callback((Fl_Callback*)cb_favDeleteButton); + Fl_Group::current()->resizable(favDeleteButton); + } // Fl_Button* favDeleteButton + { favDownButton = new Fl_Button(320, 80, 25, 25, "@2>"); + favDownButton->callback((Fl_Callback*)cb_favDownButton); + } // Fl_Button* favDownButton + o->end(); + } // Fl_Group* o + { Fl_Group* o = new Fl_Group(10, 113, 335, 29); + { favCancelButton = new Fl_Button(273, 115, 72, 25, "Cancel"); + favCancelButton->callback((Fl_Callback*)cb_favCancelButton); + favCancelButton->label(fl_cancel); + } // Fl_Button* favCancelButton + { favOkButton = new Fl_Return_Button(181, 115, 79, 25, "Save"); + favOkButton->callback((Fl_Callback*)cb_favOkButton); + favOkButton->label(save_label); + } // Fl_Return_Button* favOkButton + { Fl_Box* o = new Fl_Box(10, 115, 161, 25); + Fl_Group::current()->resizable(o); + } // Fl_Box* o + o->end(); + } // Fl_Group* o + favWindow->label(manage_favorites_label); + favWindow->set_modal(); + favWindow->size_range(181, 150); + favWindow->end(); + } // Fl_Double_Window* favWindow + callback_ = 0; +data_ = 0; +directory_[0] = 0; +window->size_range(window->w(), window->h(), Fl::w(), Fl::h()); +type(t); +filter(p); +update_favorites(); +value(d); +type(t); +int e; +prefs_.get("preview", e, 1); +preview(e); +Fl_Group::current(prev_current); +} + +Fl_File_Chooser::~Fl_File_Chooser() { + Fl::remove_timeout((Fl_Timeout_Handler)previewCB, this); +delete window; +delete favWindow; +} + +void Fl_File_Chooser::callback(void (*cb)(Fl_File_Chooser *, void *), void *d ) { + callback_ = cb; +data_ = d; +} + +void Fl_File_Chooser::color(Fl_Color c) { + fileList->color(c); +} + +Fl_Color Fl_File_Chooser::color() { + return (fileList->color()); +} + +char * Fl_File_Chooser::directory() { + return directory_; +} + +const char * Fl_File_Chooser::filter() { + return (fileList->filter()); +} + +int Fl_File_Chooser::filter_value() { + return showChoice->value(); +} + +void Fl_File_Chooser::filter_value(int f) { + showChoice->value(f); +showChoiceCB(); +} + +void Fl_File_Chooser::hide() { + window->hide(); +} + +void Fl_File_Chooser::iconsize(uchar s) { + fileList->iconsize(s); +} + +uchar Fl_File_Chooser::iconsize() { + return (fileList->iconsize()); +} + +void Fl_File_Chooser::label(const char *l) { + window->label(l); +} + +const char * Fl_File_Chooser::label() { + return (window->label()); +} + +void Fl_File_Chooser::ok_label(const char *l) { + okButton->label(l); +int w=0, h=0; +okButton->measure_label(w, h); +okButton->resize(cancelButton->x() - 50 - w, cancelButton->y(), + w + 40, 25); +okButton->parent()->init_sizes(); +} + +const char * Fl_File_Chooser::ok_label() { + return (okButton->label()); +} + +void Fl_File_Chooser::show() { + window->hotspot(fileList); +window->show(); +Fl::flush(); +fl_cursor(FL_CURSOR_WAIT); +rescan_keep_filename(); +fl_cursor(FL_CURSOR_DEFAULT); +fileName->take_focus(); +} + +int Fl_File_Chooser::shown() { + return window->shown(); +} + +void Fl_File_Chooser::textcolor(Fl_Color c) { + fileList->textcolor(c); +} + +Fl_Color Fl_File_Chooser::textcolor() { + return (fileList->textcolor()); +} + +void Fl_File_Chooser::textfont(uchar f) { + fileList->textfont(f); +} + +uchar Fl_File_Chooser::textfont() { + return (fileList->textfont()); +} + +void Fl_File_Chooser::textsize(uchar s) { + fileList->textsize(s); +} + +uchar Fl_File_Chooser::textsize() { + return (fileList->textsize()); +} + +void Fl_File_Chooser::type(int t) { + type_ = t; +if (t & MULTI) + fileList->type(FL_MULTI_BROWSER); +else + fileList->type(FL_HOLD_BROWSER); +if (t & CREATE) + newButton->activate(); +else + newButton->deactivate(); +if (t & DIRECTORY) + fileList->filetype(Fl_File_Browser::DIRECTORIES); +else + fileList->filetype(Fl_File_Browser::FILES); +} + +int Fl_File_Chooser::type() { + return (type_); +} + +void * Fl_File_Chooser::user_data() const { + return (data_); +} + +void Fl_File_Chooser::user_data(void *d) { + data_ = d; +} + +int Fl_File_Chooser::visible() { + return window->visible(); +} + +// +// End of "$Id: Fl_File_Chooser.cxx 6092 2008-04-11 12:57:37Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_File_Chooser.fl b/plugins/zynaddsubfx/fltk/src/Fl_File_Chooser.fl new file mode 100644 index 000000000..991b39f70 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_File_Chooser.fl @@ -0,0 +1,426 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0108 +header_name {../FL/Fl_File_Chooser.H} +code_name {.cxx} +comment {// +// "$Id: Fl_File_Chooser.fl 6092 2008-04-11 12:57:37Z matt $" +// +// Fl_File_Chooser dialog for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +} {in_source in_header +} + +decl {\#include } {} + +class FL_EXPORT Fl_File_Chooser {open +} { + decl {enum { SINGLE = 0, MULTI = 1, CREATE = 2, DIRECTORY = 4 };} {public + } + decl {static Fl_Preferences prefs_;} {} + decl {void (*callback_)(Fl_File_Chooser*, void *);} {} + decl {void *data_;} {} + decl {char directory_[1024];} {} + decl {char pattern_[1024];} {} + decl {char preview_text_[2048];} {} + decl {int type_;} {} + decl {void favoritesButtonCB();} {} + decl {void favoritesCB(Fl_Widget *w);} {} + decl {void fileListCB();} {} + decl {void fileNameCB();} {} + decl {void newdir();} {} + decl {static void previewCB(Fl_File_Chooser *fc);} {} + decl {void showChoiceCB();} {} + decl {void update_favorites();} {} + decl {void update_preview();} {} + Function {Fl_File_Chooser(const char *d, const char *p, int t, const char *title)} {open + } { + code {Fl_Group *prev_current = Fl_Group::current();} {} + Fl_Window window { + label {Choose File} + callback {fileName->value(""); +fileList->deselect(); +Fl::remove_timeout((Fl_Timeout_Handler)previewCB, this); +window->hide();} open + private xywh {388 284 490 380} type Double resizable + code0 {if (title) window->label(title);} + code1 {\#include } + code2 {\#include } + code3 {\#include } modal visible + } { + Fl_Group {} { + private xywh {10 10 470 25} + } { + Fl_Choice showChoice { + label {Show:} + callback {showChoiceCB();} open + private xywh {65 10 215 25} down_box BORDER_BOX labelfont 1 resizable + code0 {showChoice->label(show_label);} + } {} + Fl_Menu_Button favoritesButton { + label Favorites + callback {favoritesButtonCB();} open + private xywh {290 10 155 25} down_box BORDER_BOX align 20 + code0 {favoritesButton->label(favorites_label);} + } {} + Fl_Button newButton { + callback {newdir();} + image {new.xbm} xywh {455 10 25 25} labelsize 8 + code0 {\#include } + code1 {o->tooltip(new_directory_tooltip);} + } + } + Fl_Tile {} { + callback {update_preview();} + private xywh {10 45 470 225} resizable + } { + Fl_File_Browser fileList { + callback {fileListCB();} + private xywh {10 45 295 225} type Hold hotspot + code0 {\#include } + } + Fl_Box previewBox { + label {?} selected + private xywh {305 45 175 225} box DOWN_BOX labelsize 100 align 80 + } + } + Fl_Group {} {open + private xywh {10 275 470 95} + } { + Fl_Group {} {open + private xywh {10 275 470 20} + } { + Fl_Check_Button previewButton { + label Preview + callback {preview(previewButton->value());} + xywh {10 275 73 20} down_box DOWN_BOX shortcut 0x80070 value 1 + code0 {previewButton->label(preview_label);} + } + Fl_Box {} { + private xywh {115 275 365 20} resizable + } + } + Fl_File_Input fileName { + callback {fileNameCB();} + private xywh {115 300 365 35} labelfont 1 when 8 resizable + code0 {fileName->when(FL_WHEN_CHANGED | FL_WHEN_ENTER_KEY);} + } + Fl_Box {} { + label {Filename:} + private xywh {10 310 105 25} labelfont 1 align 24 + code0 {o->label(filename_label);} + } + Fl_Group {} {open + private xywh {10 345 470 25} + } { + Fl_Return_Button okButton { + label OK + callback {window->hide(); + +// Do any callback that is registered... +if (callback_) + (*callback_)(this, data_);} + private xywh {313 345 85 25} + code0 {\#include } + code1 {okButton->label(fl_ok);} + } + Fl_Button cancelButton { + label Cancel + callback {fileName->value(""); +fileList->deselect(); +Fl::remove_timeout((Fl_Timeout_Handler)previewCB, this); +window->hide();} + private xywh {408 345 72 25} + code0 {o->label(fl_cancel);} + } + Fl_Box {} { + private xywh {10 345 30 25} resizable + } + } + } + } + Fl_Window favWindow { + label {Manage Favorites} + private xywh {413 100 355 150} type Double resizable + code0 {favWindow->label(manage_favorites_label);} modal size_range {181 150 0 0} visible + } { + Fl_File_Browser favList { + callback {favoritesCB(favList);} + private xywh {10 10 300 95} type Hold resizable + } + Fl_Group {} {open + xywh {320 10 25 95} + } { + Fl_Button favUpButton { + label {@8>} + callback {favoritesCB(favUpButton);} + private xywh {320 10 25 25} + } + Fl_Button favDeleteButton { + label X + callback {favoritesCB(favDeleteButton);} + private xywh {320 45 25 25} labelfont 1 resizable + } + Fl_Button favDownButton { + label {@2>} + callback {favoritesCB(favDownButton);} + private xywh {320 80 25 25} + } + } + Fl_Group {} {open + xywh {10 113 335 29} + } { + Fl_Button favCancelButton { + label Cancel + callback {favWindow->hide();} + private xywh {273 115 72 25} + code0 {favCancelButton->label(fl_cancel);} + } + Fl_Return_Button favOkButton { + label Save + callback {favoritesCB(favOkButton);} + private xywh {181 115 79 25} + code0 {\#include } + code1 {favOkButton->label(save_label);} + } + Fl_Box {} { + xywh {10 115 161 25} resizable + } + } + } + code {callback_ = 0; +data_ = 0; +directory_[0] = 0; +window->size_range(window->w(), window->h(), Fl::w(), Fl::h()); +type(t); +filter(p); +update_favorites(); +value(d); +type(t); +int e; +prefs_.get("preview", e, 1); +preview(e); +Fl_Group::current(prev_current);} {} + } + Function {~Fl_File_Chooser()} {} { + code {Fl::remove_timeout((Fl_Timeout_Handler)previewCB, this); +delete window; +delete favWindow;} {} + } + Function {callback(void (*cb)(Fl_File_Chooser *, void *), void *d = 0)} {return_type void + } { + code {callback_ = cb; +data_ = d;} {} + } + Function {color(Fl_Color c)} {} { + code {fileList->color(c);} {} + } + Function {color()} {return_type Fl_Color + } { + code {return (fileList->color());} {} + } + decl {int count();} {public + } + decl {void directory(const char *d);} {public + } + Function {directory()} {return_type {char *} + } { + code {return directory_;} {} + } + decl {void filter(const char *p);} {public + } + Function {filter()} {return_type {const char *} + } { + code {return (fileList->filter());} {} + } + Function {filter_value()} {return_type int + } { + code {return showChoice->value();} {} + } + Function {filter_value(int f)} {return_type void + } { + code {showChoice->value(f); +showChoiceCB();} {} + } + Function {hide()} {return_type void + } { + code {window->hide();} {} + } + Function {iconsize(uchar s)} {return_type void + } { + code {fileList->iconsize(s);} {} + } + Function {iconsize()} {return_type uchar + } { + code {return (fileList->iconsize());} {} + } + Function {label(const char *l)} {return_type void + } { + code {window->label(l);} {} + } + Function {label()} {return_type {const char *} + } { + code {return (window->label());} {} + } + Function {ok_label(const char *l)} {return_type void + } { + code {okButton->label(l); +int w=0, h=0; +okButton->measure_label(w, h); +okButton->resize(cancelButton->x() - 50 - w, cancelButton->y(), + w + 40, 25); +okButton->parent()->init_sizes();} {} + } + Function {ok_label()} {return_type {const char *} + } { + code {return (okButton->label());} {} + } + decl {void preview(int e);} {public + } + decl {int preview() const { return previewButton->value(); }} {public + } + decl {void rescan();} {public + } + decl {void rescan_keep_filename();} {public + } + Function {show()} {open return_type void + } { + code {window->hotspot(fileList); +window->show(); +Fl::flush(); +fl_cursor(FL_CURSOR_WAIT); +rescan_keep_filename(); +fl_cursor(FL_CURSOR_DEFAULT); +fileName->take_focus();} {} + } + Function {shown()} {return_type int + } { + code {return window->shown();} {} + } + Function {textcolor(Fl_Color c)} {return_type void + } { + code {fileList->textcolor(c);} {} + } + Function {textcolor()} {return_type Fl_Color + } { + code {return (fileList->textcolor());} {} + } + Function {textfont(uchar f)} {return_type void + } { + code {fileList->textfont(f);} {} + } + Function {textfont()} {return_type uchar + } { + code {return (fileList->textfont());} {} + } + Function {textsize(uchar s)} {return_type void + } { + code {fileList->textsize(s);} {} + } + Function {textsize()} {return_type uchar + } { + code {return (fileList->textsize());} {} + } + Function {type(int t)} {return_type void + } { + code {type_ = t; +if (t & MULTI) + fileList->type(FL_MULTI_BROWSER); +else + fileList->type(FL_HOLD_BROWSER); +if (t & CREATE) + newButton->activate(); +else + newButton->deactivate(); +if (t & DIRECTORY) + fileList->filetype(Fl_File_Browser::DIRECTORIES); +else + fileList->filetype(Fl_File_Browser::FILES);} {} + } + Function {type()} {return_type int + } { + code {return (type_);} {} + } + Function {user_data() const} {return_type {void *} + } { + code {return (data_);} {} + } + Function {user_data(void *d)} {return_type void + } { + code {data_ = d;} {} + } + decl {const char *value(int f = 1);} {public + } + decl {void value(const char *filename);} {public + } + Function {visible()} {return_type int + } { + code {return window->visible();} {} + } + decl {static const char *add_favorites_label;} {public + } + decl {static const char *all_files_label;} {public + } + decl {static const char *custom_filter_label;} {public + } + decl {static const char *existing_file_label;} {public + } + decl {static const char *favorites_label;} {public + } + decl {static const char *filename_label;} {public + } + decl {static const char *filesystems_label;} {public + } + decl {static const char *manage_favorites_label;} {public + } + decl {static const char *new_directory_label;} {public + } + decl {static const char *new_directory_tooltip;} {public + } + decl {static const char *preview_label;} {public + } + decl {static const char *save_label;} {public + } + decl {static const char *show_label;} {public + } + decl {static Fl_File_Sort_F *sort;} {public + } +} + +decl {FL_EXPORT char *fl_dir_chooser(const char *message,const char *fname,int relative=0);} {public +} + +decl {FL_EXPORT char *fl_file_chooser(const char *message,const char *pat,const char *fname,int relative=0);} {public +} + +decl {FL_EXPORT void fl_file_chooser_callback(void (*cb)(const char*));} {public +} + +decl {FL_EXPORT void fl_file_chooser_ok_label(const char*l);} {public +} + +comment { +// +// End of "$Id: Fl_File_Chooser.fl 6092 2008-04-11 12:57:37Z matt $". +//} {in_source in_header +} diff --git a/plugins/zynaddsubfx/fltk/src/Fl_File_Chooser2.cxx b/plugins/zynaddsubfx/fltk/src/Fl_File_Chooser2.cxx new file mode 100644 index 000000000..47a9842a4 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_File_Chooser2.cxx @@ -0,0 +1,1308 @@ +// +// "$Id: Fl_File_Chooser2.cxx 6092 2008-04-11 12:57:37Z matt $" +// +// More Fl_File_Chooser routines. +// +// Copyright 1999-2005 by Michael Sweet. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +// Contents: +// +// Fl_File_Chooser::count() - Return the number of selected files. +// Fl_File_Chooser::directory() - Set the directory in the file chooser. +// Fl_File_Chooser::filter() - Set the filter(s) for the chooser. +// Fl_File_Chooser::newdir() - Make a new directory. +// Fl_File_Chooser::value() - Return a selected filename. +// Fl_File_Chooser::rescan() - Rescan the current directory. +// Fl_File_Chooser::favoritesButtonCB() - Handle favorites selections. +// Fl_File_Chooser::fileListCB() - Handle clicks (and double-clicks) +// in the Fl_File_Browser. +// Fl_File_Chooser::fileNameCB() - Handle text entry in the FileBrowser. +// Fl_File_Chooser::showChoiceCB() - Handle show selections. +// compare_dirnames() - Compare two directory names. +// quote_pathname() - Quote a pathname for a menu. +// unquote_pathname() - Unquote a pathname from a menu. +// + +// +// Include necessary headers. +// + +#include +#include +#include +#include +#include + +#include +#include +#include "flstring.h" +#include +#include +#include + +#if defined(WIN32) && ! defined (__CYGWIN__) +# include +# include +// Visual C++ 2005 incorrectly displays a warning about the use of POSIX APIs +// on Windows, which is supposed to be POSIX compliant... +# define access _access +# define mkdir _mkdir +// Apparently Borland C++ defines DIRECTORY in , which +// interfers with the Fl_File_Icon enumeration of the same name. +# ifdef DIRECTORY +# undef DIRECTORY +# endif // DIRECTORY +#else +# include +# include +#endif /* WIN32 */ + + +// +// File chooser label strings and sort function... +// + +Fl_Preferences Fl_File_Chooser::prefs_(Fl_Preferences::USER, "fltk.org", "filechooser"); + +const char *Fl_File_Chooser::add_favorites_label = "Add to Favorites"; +const char *Fl_File_Chooser::all_files_label = "All Files (*)"; +const char *Fl_File_Chooser::custom_filter_label = "Custom Filter"; +const char *Fl_File_Chooser::existing_file_label = "Please choose an existing file!"; +const char *Fl_File_Chooser::favorites_label = "Favorites"; +const char *Fl_File_Chooser::filename_label = "Filename:"; +#ifdef WIN32 +const char *Fl_File_Chooser::filesystems_label = "My Computer"; +#else +const char *Fl_File_Chooser::filesystems_label = "File Systems"; +#endif // WIN32 +const char *Fl_File_Chooser::manage_favorites_label = "Manage Favorites"; +const char *Fl_File_Chooser::new_directory_label = "New Directory?"; +const char *Fl_File_Chooser::new_directory_tooltip = "Create a new directory."; +const char *Fl_File_Chooser::preview_label = "Preview"; +const char *Fl_File_Chooser::save_label = "Save"; +const char *Fl_File_Chooser::show_label = "Show:"; +Fl_File_Sort_F *Fl_File_Chooser::sort = fl_numericsort; + + +// +// Local functions... +// + +static int compare_dirnames(const char *a, const char *b); +static void quote_pathname(char *, const char *, int); +static void unquote_pathname(char *, const char *, int); + + +// +// 'Fl_File_Chooser::count()' - Return the number of selected files. +// + +int // O - Number of selected files +Fl_File_Chooser::count() { + int i; // Looping var + int fcount; // Number of selected files + const char *filename; // Filename in input field or list + + + filename = fileName->value(); + + if (!(type_ & MULTI)) { + // Check to see if the file name input field is blank... + if (!filename || !filename[0]) return 0; + else return 1; + } + + for (i = 1, fcount = 0; i <= fileList->size(); i ++) + if (fileList->selected(i)) { + // See if this file is a directory... + // matt: why would we do that? It is perfectly legal to select multiple + // directories in a DIR chooser. They are visually selected and value(i) + // returns all of them as expected + //filename = (char *)fileList->text(i); + + //if (filename[strlen(filename) - 1] != '/') + fcount ++; + } + + if (fcount) return fcount; + else if (!filename || !filename[0]) return 0; + else return 1; +} + + +// +// 'Fl_File_Chooser::directory()' - Set the directory in the file chooser. +// + +void +Fl_File_Chooser::directory(const char *d)// I - Directory to change to +{ + char *dirptr; // Pointer into directory + + +// printf("Fl_File_Chooser::directory(\"%s\")\n", d == NULL ? "(null)" : d); + + // NULL == current directory + if (d == NULL) + d = "."; + +#ifdef WIN32 + // See if the filename contains backslashes... + char *slash; // Pointer to slashes + char fixpath[1024]; // Path with slashes converted + if (strchr(d, '\\')) { + // Convert backslashes to slashes... + strlcpy(fixpath, d, sizeof(fixpath)); + + for (slash = strchr(fixpath, '\\'); slash; slash = strchr(slash + 1, '\\')) + *slash = '/'; + + d = fixpath; + } +#endif // WIN32 + + if (d[0] != '\0') + { + // Make the directory absolute... +#if (defined(WIN32) && ! defined(__CYGWIN__))|| defined(__EMX__) + if (d[0] != '/' && d[0] != '\\' && d[1] != ':') +#else + if (d[0] != '/' && d[0] != '\\') +#endif /* WIN32 || __EMX__ */ + fl_filename_absolute(directory_, d); + else + strlcpy(directory_, d, sizeof(directory_)); + + // Strip any trailing slash... + dirptr = directory_ + strlen(directory_) - 1; + if ((*dirptr == '/' || *dirptr == '\\') && dirptr > directory_) + *dirptr = '\0'; + + // See if we have a trailing .. or . in the filename... + dirptr = directory_ + strlen(directory_) - 3; + if (dirptr >= directory_ && strcmp(dirptr, "/..") == 0) { + // Yes, we have "..", so strip the trailing path... + *dirptr = '\0'; + while (dirptr > directory_) { + if (*dirptr == '/') break; + dirptr --; + } + + if (dirptr >= directory_ && *dirptr == '/') + *dirptr = '\0'; + } else if ((dirptr + 1) >= directory_ && strcmp(dirptr + 1, "/.") == 0) { + // Strip trailing "."... + dirptr[1] = '\0'; + } + } + else + directory_[0] = '\0'; + + if (shown()) { + // Rescan the directory... + rescan(); + } +} + + +// +// 'Fl_File_Chooser::favoritesButtonCB()' - Handle favorites selections. +// + +void +Fl_File_Chooser::favoritesButtonCB() +{ + int v; // Current selection + char pathname[1024], // Pathname + menuname[2048]; // Menu name + + + v = favoritesButton->value(); + + if (!v) { + // Add current directory to favorites... + if (getenv("HOME")) v = favoritesButton->size() - 5; + else v = favoritesButton->size() - 4; + + sprintf(menuname, "favorite%02d", v); + + prefs_.set(menuname, directory_); + prefs_.flush(); + + quote_pathname(menuname, directory_, sizeof(menuname)); + favoritesButton->add(menuname); + + if (favoritesButton->size() > 104) { + ((Fl_Menu_Item *)favoritesButton->menu())[0].deactivate(); + } + } else if (v == 1) { + // Manage favorites... + favoritesCB(0); + } else if (v == 2) { + // Filesystems/My Computer + directory(""); + } else { + unquote_pathname(pathname, favoritesButton->text(v), sizeof(pathname)); + directory(pathname); + } +} + + +// +// 'Fl_File_Chooser::favoritesCB()' - Handle favorites dialog. +// + +void +Fl_File_Chooser::favoritesCB(Fl_Widget *w) + // I - Widget +{ + int i; // Looping var + char name[32], // Preference name + pathname[1024]; // Directory in list + + + if (!w) { + // Load the favorites list... + favList->clear(); + favList->deselect(); + + for (i = 0; i < 100; i ++) { + // Get favorite directory 0 to 99... + sprintf(name, "favorite%02d", i); + + prefs_.get(name, pathname, "", sizeof(pathname)); + + // Stop on the first empty favorite... + if (!pathname[0]) break; + + // Add the favorite to the list... + favList->add(pathname, + Fl_File_Icon::find(pathname, Fl_File_Icon::DIRECTORY)); + } + + favUpButton->deactivate(); + favDeleteButton->deactivate(); + favDownButton->deactivate(); + favOkButton->deactivate(); + + favWindow->hotspot(favList); + favWindow->show(); + } else if (w == favList) { + i = favList->value(); + if (i) { + if (i > 1) favUpButton->activate(); + else favUpButton->deactivate(); + + favDeleteButton->activate(); + + if (i < favList->size()) favDownButton->activate(); + else favDownButton->deactivate(); + } else { + favUpButton->deactivate(); + favDeleteButton->deactivate(); + favDownButton->deactivate(); + } + } else if (w == favUpButton) { + i = favList->value(); + + favList->insert(i - 1, favList->text(i), favList->data(i)); + favList->remove(i + 1); + favList->select(i - 1); + + if (i == 2) favUpButton->deactivate(); + + favDownButton->activate(); + + favOkButton->activate(); + } else if (w == favDeleteButton) { + i = favList->value(); + + favList->remove(i); + + if (i > favList->size()) i --; + favList->select(i); + + if (i < favList->size()) favDownButton->activate(); + else favDownButton->deactivate(); + + if (i > 1) favUpButton->activate(); + else favUpButton->deactivate(); + + if (!i) favDeleteButton->deactivate(); + + favOkButton->activate(); + } else if (w == favDownButton) { + i = favList->value(); + + favList->insert(i + 2, favList->text(i), favList->data(i)); + favList->remove(i); + favList->select(i + 1); + + if ((i + 1) == favList->size()) favDownButton->deactivate(); + + favUpButton->activate(); + + favOkButton->activate(); + } else if (w == favOkButton) { + // Copy the new list over... + for (i = 0; i < favList->size(); i ++) { + // Set favorite directory 0 to 99... + sprintf(name, "favorite%02d", i); + + prefs_.set(name, favList->text(i + 1)); + } + + // Clear old entries as necessary... + for (; i < 100; i ++) { + // Clear favorite directory 0 to 99... + sprintf(name, "favorite%02d", i); + + prefs_.get(name, pathname, "", sizeof(pathname)); + + if (pathname[0]) prefs_.set(name, ""); + else break; + } + + update_favorites(); + prefs_.flush(); + + favWindow->hide(); + } +} + + +// +// 'Fl_File_Chooser::fileListCB()' - Handle clicks (and double-clicks) in the +// Fl_File_Browser. +// + +void +Fl_File_Chooser::fileListCB() +{ + char *filename, // New filename + pathname[1024]; // Full pathname to file + + + filename = (char *)fileList->text(fileList->value()); + if (!filename) + return; + + if (!directory_[0]) { + strlcpy(pathname, filename, sizeof(pathname)); + } else if (strcmp(directory_, "/") == 0) { + snprintf(pathname, sizeof(pathname), "/%s", filename); + } else { + snprintf(pathname, sizeof(pathname), "%s/%s", directory_, filename); + } + + if (Fl::event_clicks()) { +#if (defined(WIN32) && ! defined(__CYGWIN__)) || defined(__EMX__) + if ((strlen(pathname) == 2 && pathname[1] == ':') || + _fl_filename_isdir_quick(pathname)) +#else + if (_fl_filename_isdir_quick(pathname)) +#endif /* WIN32 || __EMX__ */ + { + // Change directories... + directory(pathname); + + // Reset the click count so that a click in the same spot won't + // be treated as a triple-click. We use a value of -1 because + // the next click will increment click count to 0, which is what + // we really want... + Fl::event_clicks(-1); + } + else + { + // Hide the window - picked the file... + window->hide(); + } + } + else + { + // Check if the user clicks on a directory when picking files; + // if so, make sure only that item is selected... + filename = pathname + strlen(pathname) - 1; + + if ((type_ & MULTI) && !(type_ & DIRECTORY)) { + if (*filename == '/') { + // Clicked on a directory, deselect everything else... + int i = fileList->value(); + fileList->deselect(); + fileList->select(i); + } else { + // Clicked on a file - see if there are other directories selected... + int i; + const char *temp; + for (i = 1; i <= fileList->size(); i ++) { + if (i != fileList->value() && fileList->selected(i)) { + temp = fileList->text(i); + temp += strlen(temp) - 1; + if (*temp == '/') break; // Yes, selected directory + } + } + + if (i <= fileList->size()) { + i = fileList->value(); + fileList->deselect(); + fileList->select(i); + } + } + } + // Strip any trailing slash from the directory name... + if (*filename == '/') *filename = '\0'; + +// puts("Setting fileName from fileListCB..."); + fileName->value(pathname); + + // Update the preview box... + Fl::remove_timeout((Fl_Timeout_Handler)previewCB, this); + Fl::add_timeout(1.0, (Fl_Timeout_Handler)previewCB, this); + + // Do any callback that is registered... + if (callback_) (*callback_)(this, data_); + + // Activate the OK button as needed... + if (!_fl_filename_isdir_quick(pathname) || (type_ & DIRECTORY)) + okButton->activate(); + else + okButton->deactivate(); + } +} + + +// +// 'Fl_File_Chooser::fileNameCB()' - Handle text entry in the FileBrowser. +// + +void +Fl_File_Chooser::fileNameCB() +{ + char *filename, // New filename + *slash, // Pointer to trailing slash + pathname[1024], // Full pathname to file + matchname[256]; // Matching filename + int i, // Looping var + min_match, // Minimum number of matching chars + max_match, // Maximum number of matching chars + num_files, // Number of files in directory + first_line; // First matching line + const char *file; // File from directory + +// puts("fileNameCB()"); +// printf("Event: %s\n", fl_eventnames[Fl::event()]); + + // Get the filename from the text field... + filename = (char *)fileName->value(); + + if (!filename || !filename[0]) { + okButton->deactivate(); + return; + } + + // Expand ~ and $ variables as needed... + if (strchr(filename, '~') || strchr(filename, '$')) { + fl_filename_expand(pathname, sizeof(pathname), filename); + filename = pathname; + value(pathname); + } + + // Make sure we have an absolute path... +#if (defined(WIN32) && !defined(__CYGWIN__)) || defined(__EMX__) + if (directory_[0] != '\0' && filename[0] != '/' && + filename[0] != '\\' && + !(isalpha(filename[0] & 255) && (!filename[1] || filename[1] == ':'))) { +#else + if (directory_[0] != '\0' && filename[0] != '/') { +#endif /* WIN32 || __EMX__ */ + fl_filename_absolute(pathname, sizeof(pathname), filename); + value(pathname); + fileName->mark(fileName->position()); // no selection after expansion + } else if (filename != pathname) { + // Finally, make sure that we have a writable copy... + strlcpy(pathname, filename, sizeof(pathname)); + } + + filename = pathname; + + // Now process things according to the key pressed... + if (Fl::event_key() == FL_Enter || Fl::event_key() == FL_KP_Enter) { + // Enter pressed - select or change directory... +#if (defined(WIN32) && ! defined(__CYGWIN__)) || defined(__EMX__) + if ((isalpha(pathname[0] & 255) && pathname[1] == ':' && !pathname[2]) || + _fl_filename_isdir_quick(pathname) && + compare_dirnames(pathname, directory_)) { +#else + if (_fl_filename_isdir_quick(pathname) && + compare_dirnames(pathname, directory_)) { +#endif /* WIN32 || __EMX__ */ + directory(pathname); + } else if ((type_ & CREATE) || access(pathname, 0) == 0) { + if (!_fl_filename_isdir_quick(pathname) || (type_ & DIRECTORY)) { + // Update the preview box... + update_preview(); + + // Do any callback that is registered... + if (callback_) (*callback_)(this, data_); + + // Hide the window to signal things are done... + window->hide(); + } + } else { + // File doesn't exist, so beep at and alert the user... + fl_alert(existing_file_label); + } + } + else if (Fl::event_key() != FL_Delete && + Fl::event_key() != FL_BackSpace) { + // Check to see if the user has entered a directory... + if ((slash = strrchr(pathname, '/')) == NULL) + slash = strrchr(pathname, '\\'); + + if (!slash) return; + + // Yes, change directories if necessary... + *slash++ = '\0'; + filename = slash; + +#if defined(WIN32) || defined(__EMX__) + if (strcasecmp(pathname, directory_) && + (pathname[0] || strcasecmp("/", directory_))) { +#else + if (strcmp(pathname, directory_) && + (pathname[0] || strcasecmp("/", directory_))) { +#endif // WIN32 || __EMX__ + int p = fileName->position(); + int m = fileName->mark(); + + directory(pathname); + + if (filename[0]) { + char tempname[1024]; + + snprintf(tempname, sizeof(tempname), "%s/%s", directory_, filename); + fileName->value(tempname); + strlcpy(pathname, tempname, sizeof(pathname)); + } + + fileName->position(p, m); + } + + // Other key pressed - do filename completion as possible... + num_files = fileList->size(); + min_match = strlen(filename); + max_match = min_match + 1; + first_line = 0; + + for (i = 1; i <= num_files && max_match > min_match; i ++) { + file = fileList->text(i); + +#if (defined(WIN32) && ! defined(__CYGWIN__)) || defined(__EMX__) + if (strncasecmp(filename, file, min_match) == 0) { +#else + if (strncmp(filename, file, min_match) == 0) { +#endif // WIN32 || __EMX__ + // OK, this one matches; check against the previous match + if (!first_line) { + // First match; copy stuff over... + strlcpy(matchname, file, sizeof(matchname)); + max_match = strlen(matchname); + + // Strip trailing /, if any... + if (matchname[max_match - 1] == '/') { + max_match --; + matchname[max_match] = '\0'; + } + + // And then make sure that the item is visible + fileList->topline(i); + first_line = i; + } else { + // Succeeding match; compare to find maximum string match... + while (max_match > min_match) +#if (defined(WIN32) && ! defined(__CYGWIN__)) || defined(__EMX__) + if (strncasecmp(file, matchname, max_match) == 0) +#else + if (strncmp(file, matchname, max_match) == 0) +#endif // WIN32 || __EMX__ + break; + else + max_match --; + + // Truncate the string as needed... + matchname[max_match] = '\0'; + } + } + } + + // If we have any matches, add them to the input field... + if (first_line > 0 && min_match == max_match && + max_match == (int)strlen(fileList->text(first_line))) { + // This is the only possible match... + fileList->deselect(0); + fileList->select(first_line); + fileList->redraw(); + } else if (max_match > min_match && first_line) { + // Add the matching portion... + fileName->replace(filename - pathname, filename - pathname + min_match, + matchname); + + // Highlight it with the cursor at the end of the selection so + // s/he can press the right arrow to accept the selection + // (Tab and End also do this for both cases.) + fileName->position(filename - pathname + max_match, + filename - pathname + min_match); + } else if (max_match == 0) { + fileList->deselect(0); + fileList->redraw(); + } + + // See if we need to enable the OK button... + if (((type_ & CREATE) || !access(fileName->value(), 0)) && + (!fl_filename_isdir(fileName->value()) || (type_ & DIRECTORY))) { + okButton->activate(); + } else { + okButton->deactivate(); + } + } else { + // FL_Delete or FL_BackSpace + fileList->deselect(0); + fileList->redraw(); + if (((type_ & CREATE) || !access(fileName->value(), 0)) && + (!fl_filename_isdir(fileName->value()) || (type_ & DIRECTORY))) { + okButton->activate(); + } else { + okButton->deactivate(); + } + } +} + + +// +// 'Fl_File_Chooser::filter()' - Set the filter(s) for the chooser. +// + +void +Fl_File_Chooser::filter(const char *p) // I - Pattern(s) +{ + char *copyp, // Copy of pattern + *start, // Start of pattern + *end; // End of pattern + int allfiles; // Do we have a "*" pattern? + char temp[1024]; // Temporary pattern string + + + // Make sure we have a pattern... + if (!p || !*p) p = "*"; + + // Copy the pattern string... + copyp = strdup(p); + + // Separate the pattern string as necessary... + showChoice->clear(); + + for (start = copyp, allfiles = 0; start && *start; start = end) { + end = strchr(start, '\t'); + if (end) *end++ = '\0'; + + if (strcmp(start, "*") == 0) { + showChoice->add(all_files_label); + allfiles = 1; + } else { + quote_pathname(temp, start, sizeof(temp)); + showChoice->add(temp); + if (strstr(start, "(*)") != NULL) allfiles = 1; + } + } + + free(copyp); + + if (!allfiles) showChoice->add(all_files_label); + + showChoice->add(custom_filter_label); + + showChoice->value(0); + showChoiceCB(); +} + + +// +// 'Fl_File_Chooser::newdir()' - Make a new directory. +// + +void +Fl_File_Chooser::newdir() +{ + const char *dir; // New directory name + char pathname[1024]; // Full path of directory + + + // Get a directory name from the user + if ((dir = fl_input(new_directory_label, NULL)) == NULL) + return; + + // Make it relative to the current directory as needed... +#if (defined(WIN32) && ! defined (__CYGWIN__)) || defined(__EMX__) + if (dir[0] != '/' && dir[0] != '\\' && dir[1] != ':') +#else + if (dir[0] != '/' && dir[0] != '\\') +#endif /* WIN32 || __EMX__ */ + snprintf(pathname, sizeof(pathname), "%s/%s", directory_, dir); + else + strlcpy(pathname, dir, sizeof(pathname)); + + // Create the directory; ignore EEXIST errors... +#if defined(WIN32) && ! defined (__CYGWIN__) + if (mkdir(pathname)) +#else + if (mkdir(pathname, 0777)) +#endif /* WIN32 */ + if (errno != EEXIST) + { + fl_alert("%s", strerror(errno)); + return; + } + + // Show the new directory... + directory(pathname); +} + + +// +// 'Fl_File_Chooser::preview()' - Enable or disable the preview tile. +// + +void +Fl_File_Chooser::preview(int e)// I - 1 = enable preview, 0 = disable preview +{ + previewButton->value(e); + prefs_.set("preview", e); + prefs_.flush(); + + Fl_Group *p = previewBox->parent(); + if (e) { + int w = p->w() * 2 / 3; + fileList->resize(fileList->x(), fileList->y(), + w, fileList->h()); + previewBox->resize(fileList->x()+w, previewBox->y(), + p->w()-w, previewBox->h()); + previewBox->show(); + update_preview(); + } else { + fileList->resize(fileList->x(), fileList->y(), + p->w(), fileList->h()); + previewBox->resize(p->x()+p->w(), previewBox->y(), + 0, previewBox->h()); + previewBox->hide(); + } + p->init_sizes(); + + fileList->parent()->redraw(); +} + + +// +// 'Fl_File_Chooser::previewCB()' - Timeout handler for the preview box. +// + +void +Fl_File_Chooser::previewCB(Fl_File_Chooser *fc) { // I - File chooser + fc->update_preview(); +} + + +// +// 'Fl_File_Chooser::rescan()' - Rescan the current directory. +// + +void +Fl_File_Chooser::rescan() +{ + char pathname[1024]; // New pathname for filename field + + + // Clear the current filename + strlcpy(pathname, directory_, sizeof(pathname)); + if (pathname[0] && pathname[strlen(pathname) - 1] != '/') { + strlcat(pathname, "/", sizeof(pathname)); + } +// puts("Setting fileName in rescan()"); + fileName->value(pathname); + + if (type_ & DIRECTORY) + okButton->activate(); + else + okButton->deactivate(); + + // Build the file list... + fileList->load(directory_, sort); + + // Update the preview box... + update_preview(); +} + +// +// 'Fl_File_Chooser::rescan_keep_filename()' - Rescan the current directory +// without clearing the filename, then select the file if it is in the list +// + +void +Fl_File_Chooser::rescan_keep_filename() +{ + // if no filename was set, this is likely a diretory browser + const char *fn = fileName->value(); + if (!fn || !*fn || fn[strlen(fn) - 1]=='/') { + rescan(); + return; + } + + int i; + char pathname[1024]; // New pathname for filename field + strlcpy(pathname, fn, sizeof(pathname)); + + // Build the file list... + fileList->load(directory_, sort); + + // Update the preview box... + update_preview(); + + // and select the chosen file + char found = 0; + char *slash = strrchr(pathname, '/'); + if (slash) + slash++; + else + slash = pathname; + for (i = 1; i <= fileList->size(); i ++) +#if defined(WIN32) || defined(__EMX__) + if (strcasecmp(fileList->text(i), slash) == 0) { +#else + if (strcmp(fileList->text(i), slash) == 0) { +#endif // WIN32 || __EMX__ + fileList->topline(i); + fileList->select(i); + found = 1; + break; + } + + // update OK button activity + if (found || type_ & CREATE) + okButton->activate(); + else + okButton->deactivate(); +} + + +// +// 'Fl_File_Chooser::showChoiceCB()' - Handle show selections. +// + +void +Fl_File_Chooser::showChoiceCB() +{ + const char *item, // Selected item + *patstart; // Start of pattern + char *patend; // End of pattern + char temp[1024]; // Temporary string for pattern + + + item = showChoice->text(showChoice->value()); + + if (strcmp(item, custom_filter_label) == 0) { + if ((item = fl_input(custom_filter_label, pattern_)) != NULL) { + strlcpy(pattern_, item, sizeof(pattern_)); + + quote_pathname(temp, item, sizeof(temp)); + showChoice->add(temp); + showChoice->value(showChoice->size() - 2); + } + } else if ((patstart = strchr(item, '(')) == NULL) { + strlcpy(pattern_, item, sizeof(pattern_)); + } else { + strlcpy(pattern_, patstart + 1, sizeof(pattern_)); + if ((patend = strrchr(pattern_, ')')) != NULL) *patend = '\0'; + } + + fileList->filter(pattern_); + + if (shown()) { + // Rescan the directory... + rescan_keep_filename(); + } +} + + +// +// 'Fl_File_Chooser::update_favorites()' - Update the favorites menu. +// + +void +Fl_File_Chooser::update_favorites() +{ + int i; // Looping var + char pathname[1024], // Pathname + menuname[2048]; // Menu name + const char *home; // Home directory + + + favoritesButton->clear(); + favoritesButton->add("bla"); + favoritesButton->clear(); + favoritesButton->add(add_favorites_label, FL_ALT + 'a', 0); + favoritesButton->add(manage_favorites_label, FL_ALT + 'm', 0, 0, FL_MENU_DIVIDER); + favoritesButton->add(filesystems_label, FL_ALT + 'f', 0); + + if ((home = getenv("HOME")) != NULL) { + quote_pathname(menuname, home, sizeof(menuname)); + favoritesButton->add(menuname, FL_ALT + 'h', 0); + } + + for (i = 0; i < 100; i ++) { + sprintf(menuname, "favorite%02d", i); + prefs_.get(menuname, pathname, "", sizeof(pathname)); + if (!pathname[0]) break; + + quote_pathname(menuname, pathname, sizeof(menuname)); + + if (i < 10) favoritesButton->add(menuname, FL_ALT + '0' + i, 0); + else favoritesButton->add(menuname); + } + + if (i == 100) ((Fl_Menu_Item *)favoritesButton->menu())[0].deactivate(); +} + + +// +// 'Fl_File_Chooser::update_preview()' - Update the preview box... +// + +void +Fl_File_Chooser::update_preview() +{ + const char *filename; // Current filename + Fl_Shared_Image *image, // New image + *oldimage; // Old image + int pbw, pbh; // Width and height of preview box + int w, h; // Width and height of preview image + + + if (!previewButton->value()) return; + + if ((filename = value()) == NULL || fl_filename_isdir(filename)) image = NULL; + else { + window->cursor(FL_CURSOR_WAIT); + Fl::check(); + + image = Fl_Shared_Image::get(filename); + + if (image) { + window->cursor(FL_CURSOR_DEFAULT); + Fl::check(); + } + } + + oldimage = (Fl_Shared_Image *)previewBox->image(); + + if (oldimage) oldimage->release(); + + previewBox->image(0); + + if (!image) { + FILE *fp; + int bytes; + char *ptr; + + if (filename) fp = fopen(filename, "rb"); + else fp = NULL; + + if (fp != NULL) { + // Try reading the first 1k of data for a label... + bytes = fread(preview_text_, 1, sizeof(preview_text_) - 1, fp); + preview_text_[bytes] = '\0'; + fclose(fp); + } else { + // Assume we can't read any data... + preview_text_[0] = '\0'; + } + + window->cursor(FL_CURSOR_DEFAULT); + Fl::check(); + + // Scan the buffer for printable chars... + for (ptr = preview_text_; + *ptr && (isprint(*ptr & 255) || isspace(*ptr & 255)); + ptr ++); + + if (*ptr || ptr == preview_text_) { + // Non-printable file, just show a big ?... + previewBox->label(filename ? "?" : 0); + previewBox->align(FL_ALIGN_CLIP); + previewBox->labelsize(100); + previewBox->labelfont(FL_HELVETICA); + } else { + // Show the first 1k of text... + int size = previewBox->h() / 20; + if (size < 6) size = 6; + else if (size > 14) size = 14; + + previewBox->label(preview_text_); + previewBox->align((Fl_Align)(FL_ALIGN_CLIP | FL_ALIGN_INSIDE | + FL_ALIGN_LEFT | FL_ALIGN_TOP)); + previewBox->labelsize((uchar)size); + previewBox->labelfont(FL_COURIER); + } + } else { + pbw = previewBox->w() - 20; + pbh = previewBox->h() - 20; + + if (image->w() > pbw || image->h() > pbh) { + w = pbw; + h = w * image->h() / image->w(); + + if (h > pbh) { + h = pbh; + w = h * image->w() / image->h(); + } + + oldimage = (Fl_Shared_Image *)image->copy(w, h); + previewBox->image((Fl_Image *)oldimage); + + image->release(); + } else { + previewBox->image((Fl_Image *)image); + } + + previewBox->align(FL_ALIGN_CLIP); + previewBox->label(0); + } + + previewBox->redraw(); +} + + +// +// 'Fl_File_Chooser::value()' - Return a selected filename. +// + +const char * // O - Filename or NULL +Fl_File_Chooser::value(int f) // I - File number +{ + int i; // Looping var + int fcount; // Number of selected files + const char *name; // Current filename + static char pathname[1024]; // Filename + directory + + + name = fileName->value(); + + if (!(type_ & MULTI)) { + // Return the filename in the filename field... + if (!name || !name[0]) return NULL; + else return name; + } + + // Return a filename from the list... + for (i = 1, fcount = 0; i <= fileList->size(); i ++) + if (fileList->selected(i)) { + // See if this file is a selected file/directory... + name = fileList->text(i); + + fcount ++; + + if (fcount == f) { + if (directory_[0]) { + snprintf(pathname, sizeof(pathname), "%s/%s", directory_, name); + } else { + strlcpy(pathname, name, sizeof(pathname)); + } + + return pathname; + } + } + + // If nothing is selected, use the filename field... + if (!name || !name[0]) return NULL; + else return name; +} + + +// +// 'Fl_File_Chooser::value()' - Set the current filename. +// + +void +Fl_File_Chooser::value(const char *filename) + // I - Filename + directory +{ + int i, // Looping var + fcount; // Number of items in list + char *slash; // Directory separator + char pathname[1024]; // Local copy of filename + + +// printf("Fl_File_Chooser::value(\"%s\")\n", filename == NULL ? "(null)" : filename); + + // See if the filename is the "My System" directory... + if (filename == NULL || !filename[0]) { + // Yes, just change the current directory... + directory(filename); + fileName->value(""); + okButton->deactivate(); + return; + } + +#ifdef WIN32 + // See if the filename contains backslashes... + char fixpath[1024]; // Path with slashes converted + if (strchr(filename, '\\')) { + // Convert backslashes to slashes... + strlcpy(fixpath, filename, sizeof(fixpath)); + + for (slash = strchr(fixpath, '\\'); slash; slash = strchr(slash + 1, '\\')) + *slash = '/'; + + filename = fixpath; + } +#endif // WIN32 + + // See if there is a directory in there... + fl_filename_absolute(pathname, sizeof(pathname), filename); + + if ((slash = strrchr(pathname, '/')) != NULL) { + // Yes, change the display to the directory... + if (!fl_filename_isdir(pathname)) *slash++ = '\0'; + + directory(pathname); + if (*slash == '/') slash = pathname; + } else { + directory("."); + slash = pathname; + } + + // Set the input field to the absolute path... + if (slash > pathname) slash[-1] = '/'; + + fileName->value(pathname); + fileName->position(0, strlen(pathname)); + okButton->activate(); + + // Then find the file in the file list and select it... + fcount = fileList->size(); + + fileList->deselect(0); + fileList->redraw(); + + for (i = 1; i <= fcount; i ++) +#if defined(WIN32) || defined(__EMX__) + if (strcasecmp(fileList->text(i), slash) == 0) { +#else + if (strcmp(fileList->text(i), slash) == 0) { +#endif // WIN32 || __EMX__ +// printf("Selecting line %d...\n", i); + fileList->topline(i); + fileList->select(i); + break; + } +} + + +// +// 'compare_dirnames()' - Compare two directory names. +// + +static int +compare_dirnames(const char *a, const char *b) { + int alen, blen; + + // Get length of each string... + alen = strlen(a) - 1; + blen = strlen(b) - 1; + + if (alen < 0 || blen < 0) return alen - blen; + + // Check for trailing slashes... + if (a[alen] != '/') alen ++; + if (b[blen] != '/') blen ++; + + // If the lengths aren't the same, then return the difference... + if (alen != blen) return alen - blen; + + // Do a comparison of the first N chars (alen == blen at this point)... +#ifdef WIN32 + return strncasecmp(a, b, alen); +#else + return strncmp(a, b, alen); +#endif // WIN32 +} + + +// +// 'quote_pathname()' - Quote a pathname for a menu. +// + +static void +quote_pathname(char *dst, // O - Destination string + const char *src, // I - Source string + int dstsize) // I - Size of destination string +{ + dstsize --; + + while (*src && dstsize > 1) { + if (*src == '\\') { + // Convert backslash to forward slash... + *dst++ = '\\'; + *dst++ = '/'; + src ++; + } else { + if (*src == '/') *dst++ = '\\'; + + *dst++ = *src++; + } + } + + *dst = '\0'; +} + + +// +// 'unquote_pathname()' - Unquote a pathname from a menu. +// + +static void +unquote_pathname(char *dst, // O - Destination string + const char *src, // I - Source string + int dstsize) // I - Size of destination string +{ + dstsize --; + + while (*src && dstsize > 1) { + if (*src == '\\') src ++; + *dst++ = *src++; + } + + *dst = '\0'; +} + + +// +// End of "$Id: Fl_File_Chooser2.cxx 6092 2008-04-11 12:57:37Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_File_Icon.cxx b/plugins/zynaddsubfx/fltk/src/Fl_File_Icon.cxx new file mode 100644 index 000000000..ec671c73d --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_File_Icon.cxx @@ -0,0 +1,485 @@ +// +// "$Id: Fl_File_Icon.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Fl_File_Icon routines. +// +// KDE icon code donated by Maarten De Boer. +// +// Copyright 1999-2005 by Michael Sweet. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +// Contents: +// +// Fl_File_Icon::Fl_File_Icon() - Create a new file icon. +// Fl_File_Icon::~Fl_File_Icon() - Remove a file icon. +// Fl_File_Icon::add() - Add data to an icon. +// Fl_File_Icon::find() - Find an icon based upon a given file. +// Fl_File_Icon::draw() - Draw an icon. +// Fl_File_Icon::label() - Set the widgets label to an icon. +// Fl_File_Icon::labeltype() - Draw the icon label. +// + +// +// Include necessary header files... +// + +#include +#include +#include "flstring.h" +#include +#include +#include +#if (defined(WIN32) && ! defined(__CYGWIN__)) || defined(__EMX__) +# include +# define F_OK 0 +#else +# include +#endif /* WIN32 || __EMX__ */ + +#include +#include +#include +#include + + +// +// Define missing POSIX/XPG4 macros as needed... +// + +#ifndef S_ISDIR +# define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK) +# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) +# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) +# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) +#endif /* !S_ISDIR */ + + +// +// Icon cache... +// + +Fl_File_Icon *Fl_File_Icon::first_ = (Fl_File_Icon *)0; + + +// +// 'Fl_File_Icon::Fl_File_Icon()' - Create a new file icon. +// + +Fl_File_Icon::Fl_File_Icon(const char *p, /* I - Filename pattern */ + int t, /* I - File type */ + int nd, /* I - Number of data values */ + short *d) /* I - Data values */ +{ + // Initialize the pattern and type... + pattern_ = p; + type_ = t; + + // Copy icon data as needed... + if (nd) + { + num_data_ = nd; + alloc_data_ = nd + 1; + data_ = (short *)calloc(sizeof(short), nd + 1); + memcpy(data_, d, nd * sizeof(short)); + } + else + { + num_data_ = 0; + alloc_data_ = 0; + } + + // And add the icon to the list of icons... + next_ = first_; + first_ = this; +} + + +// +// 'Fl_File_Icon::~Fl_File_Icon()' - Remove a file icon. +// + +Fl_File_Icon::~Fl_File_Icon() +{ + Fl_File_Icon *current, // Current icon in list + *prev; // Previous icon in list + + + // Find the icon in the list... + for (current = first_, prev = (Fl_File_Icon *)0; + current != this && current != (Fl_File_Icon *)0; + prev = current, current = current->next_); + + // Remove the icon from the list as needed... + if (current) + { + if (prev) + prev->next_ = current->next_; + else + first_ = current->next_; + } + + // Free any memory used... + if (alloc_data_) + free(data_); +} + + +// +// 'Fl_File_Icon::add()' - Add data to an icon. +// + +short * // O - Pointer to new data value +Fl_File_Icon::add(short d) // I - Data to add +{ + short *dptr; // Pointer to new data value + + + // Allocate/reallocate memory as needed + if ((num_data_ + 1) >= alloc_data_) + { + alloc_data_ += 128; + + if (alloc_data_ == 128) + dptr = (short *)malloc(sizeof(short) * alloc_data_); + else + dptr = (short *)realloc(data_, sizeof(short) * alloc_data_); + + if (dptr == NULL) + return (NULL); + + data_ = dptr; + } + + // Store the new data value and return + data_[num_data_++] = d; + data_[num_data_] = END; + + return (data_ + num_data_ - 1); +} + + +// +// 'Fl_File_Icon::find()' - Find an icon based upon a given file. +// + +Fl_File_Icon * // O - Matching file icon or NULL +Fl_File_Icon::find(const char *filename,// I - Name of file */ + int filetype) // I - Enumerated file type +{ + Fl_File_Icon *current; // Current file in list +#ifndef WIN32 + struct stat fileinfo; // Information on file +#endif // !WIN32 + const char *name; // Base name of filename + + + // Get file information if needed... + if (filetype == ANY) + { +#ifdef WIN32 + if (filename[strlen(filename) - 1] == '/') + filetype = DIRECTORY; + else if (fl_filename_isdir(filename)) + filetype = DIRECTORY; + else + filetype = PLAIN; +#else + if (!stat(filename, &fileinfo)) + { + if (S_ISDIR(fileinfo.st_mode)) + filetype = DIRECTORY; +# ifdef S_IFIFO + else if (S_ISFIFO(fileinfo.st_mode)) + filetype = FIFO; +# endif // S_IFIFO +# if defined(S_ICHR) && defined(S_IBLK) + else if (S_ISCHR(fileinfo.st_mode) || S_ISBLK(fileinfo.st_mode)) + filetype = DEVICE; +# endif // S_ICHR && S_IBLK +# ifdef S_ILNK + else if (S_ISLNK(fileinfo.st_mode)) + filetype = LINK; +# endif // S_ILNK + else + filetype = PLAIN; + } + else + filetype = PLAIN; +#endif // WIN32 + } + + // Look at the base name in the filename + name = fl_filename_name(filename); + + // Loop through the available file types and return any match that + // is found... + for (current = first_; current != (Fl_File_Icon *)0; current = current->next_) + if ((current->type_ == filetype || current->type_ == ANY) && + (fl_filename_match(filename, current->pattern_) || + fl_filename_match(name, current->pattern_))) + break; + + // Return the match (if any)... + return (current); +} + + +// +// 'Fl_File_Icon::draw()' - Draw an icon. +// + +void +Fl_File_Icon::draw(int x, // I - Upper-lefthand X + int y, // I - Upper-lefthand Y + int w, // I - Width of bounding box + int h, // I - Height of bounding box + Fl_Color ic, // I - Icon color... + int active) // I - Active or inactive? +{ + Fl_Color c, // Current color + oc; // Outline color + short *d, // Pointer to data + *dend; // End of data... + short *prim; // Pointer to start of primitive... + double scale; // Scale of icon + + + // Don't try to draw a NULL array! + if (num_data_ == 0) + return; + + // Setup the transform matrix as needed... + scale = w < h ? w : h; + + fl_push_matrix(); + fl_translate((float)x + 0.5 * ((float)w - scale), + (float)y + 0.5 * ((float)h + scale)); + fl_scale(scale, -scale); + + // Loop through the array until we see an unmatched END... + d = data_; + dend = data_ + num_data_; + prim = NULL; + c = ic; + + if (active) + fl_color(c); + else + fl_color(fl_inactive(c)); + + while (d < dend) + switch (*d) + { + case END : + if (prim) + switch (*prim) + { + case LINE : + fl_end_line(); + break; + + case CLOSEDLINE : + fl_end_loop(); + break; + + case POLYGON : + fl_end_complex_polygon(); + break; + + case OUTLINEPOLYGON : + fl_end_complex_polygon(); + + oc = (Fl_Color)((((unsigned short *)prim)[1] << 16) | + ((unsigned short *)prim)[2]); + if (active) + { + if (oc == FL_ICON_COLOR) + fl_color(ic); + else + fl_color(oc); + } + else + { + if (oc == FL_ICON_COLOR) + fl_color(fl_inactive(ic)); + else + fl_color(fl_inactive(oc)); + } + + fl_begin_loop(); + + prim += 3; + while (*prim == VERTEX) + { + fl_vertex(prim[1] * 0.0001, prim[2] * 0.0001); + prim += 3; + } + + fl_end_loop(); + fl_color(c); + break; + } + + prim = NULL; + d ++; + break; + + case COLOR : + c = (Fl_Color)((((unsigned short *)d)[1] << 16) | + ((unsigned short *)d)[2]); + + if (c == FL_ICON_COLOR) + c = ic; + + if (!active) + c = fl_inactive(c); + + fl_color(c); + d += 3; + break; + + case LINE : + prim = d; + d ++; + fl_begin_line(); + break; + + case CLOSEDLINE : + prim = d; + d ++; + fl_begin_loop(); + break; + + case POLYGON : + prim = d; + d ++; + fl_begin_complex_polygon(); + break; + + case OUTLINEPOLYGON : + prim = d; + d += 3; + fl_begin_complex_polygon(); + break; + + case VERTEX : + if (prim) + fl_vertex(d[1] * 0.0001, d[2] * 0.0001); + d += 3; + break; + + default : // Ignore invalid data... + d ++; + } + + // If we still have an open primitive, close it... + if (prim) + switch (*prim) + { + case LINE : + fl_end_line(); + break; + + case CLOSEDLINE : + fl_end_loop(); + break; + + case POLYGON : + fl_end_polygon(); + break; + + case OUTLINEPOLYGON : + fl_end_polygon(); + + oc = (Fl_Color)((((unsigned short *)prim)[1] << 16) | + ((unsigned short *)prim)[2]); + if (active) + { + if (oc == FL_ICON_COLOR) + fl_color(ic); + else + fl_color(oc); + } + else + { + if (oc == FL_ICON_COLOR) + fl_color(fl_inactive(ic)); + else + fl_color(fl_inactive(oc)); + } + + fl_begin_loop(); + + prim += 3; + while (*prim == VERTEX) + { + fl_vertex(prim[1] * 0.0001, prim[2] * 0.0001); + prim += 3; + } + + fl_end_loop(); + fl_color(c); + break; + } + + // Restore the transform matrix + fl_pop_matrix(); +} + + +// +// 'Fl_File_Icon::label()' - Set the widget's label to an icon. +// + +void +Fl_File_Icon::label(Fl_Widget *w) // I - Widget to label +{ + Fl::set_labeltype(_FL_ICON_LABEL, labeltype, 0); + w->label(_FL_ICON_LABEL, (const char*)this); +} + + +// +// 'Fl_File_Icon::labeltype()' - Draw the icon label. +// + +void +Fl_File_Icon::labeltype(const Fl_Label *o, // I - Label data + int x, // I - X position of label + int y, // I - Y position of label + int w, // I - Width of label + int h, // I - Height of label + Fl_Align a) // I - Label alignment (not used) +{ + Fl_File_Icon *icon; // Pointer to icon data + + + (void)a; + + icon = (Fl_File_Icon *)(o->value); + if (icon) icon->draw(x, y, w, h, (Fl_Color)(o->color)); +} + + +// +// End of "$Id: Fl_File_Icon.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_File_Input.cxx b/plugins/zynaddsubfx/fltk/src/Fl_File_Input.cxx new file mode 100644 index 000000000..009eaaa69 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_File_Input.cxx @@ -0,0 +1,283 @@ +// +// "$Id: Fl_File_Input.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// File_Input header file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// Original version Copyright 1998 by Curtis Edwards. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include +#include +#include "flstring.h" + + +// +// Height of directory buttons... +// + +#define DIR_HEIGHT 10 + + +// +// Redraw bit for directory bar... +// + +#define FL_DAMAGE_BAR 0x10 + + +// +// 'Fl_File_Input::Fl_File_Input()' - Create a Fl_File_Input widget. +// + +Fl_File_Input::Fl_File_Input(int X, int Y, int W, int H, const char *l) + : Fl_Input(X, Y, W, H, l) { + buttons_[0] = 0; + errorcolor_ = FL_RED; + ok_entry_ = 1; + pressed_ = -1; + + down_box(FL_UP_BOX); +} + +// +// 'Fl_File_Input::draw_buttons()' - Draw directory buttons. +// + +void +Fl_File_Input::draw_buttons() { + int i, // Looping var + X; // Current X position + + + if (damage() & (FL_DAMAGE_BAR | FL_DAMAGE_ALL)) { + update_buttons(); + } + + for (X = 0, i = 0; buttons_[i]; i ++) + { + if ((X + buttons_[i]) > xscroll()) { + if (X < xscroll()) { + draw_box(pressed_ == i ? fl_down(down_box()) : down_box(), + x(), y(), X + buttons_[i] - xscroll(), DIR_HEIGHT, FL_GRAY); + } else if ((X + buttons_[i] - xscroll()) > w()) { + draw_box(pressed_ == i ? fl_down(down_box()) : down_box(), + x() + X - xscroll(), y(), w() - X + xscroll(), DIR_HEIGHT, + FL_GRAY); + } else { + draw_box(pressed_ == i ? fl_down(down_box()) : down_box(), + x() + X - xscroll(), y(), buttons_[i], DIR_HEIGHT, FL_GRAY); + } + } + + X += buttons_[i]; + } + + if (X < w()) { + draw_box(pressed_ == i ? fl_down(down_box()) : down_box(), + x() + X - xscroll(), y(), w() - X + xscroll(), DIR_HEIGHT, FL_GRAY); + } +} + +// +// 'Fl_File_Input::update_buttons()' - Update the sizes of the directory buttons. +// + +void +Fl_File_Input::update_buttons() { + int i; // Looping var + const char *start, // Start of path component + *end; // End of path component + + +// puts("update_buttons()"); + + // Set the current font & size... + fl_font(textfont(), textsize()); + + // Loop through the value string, setting widths... + for (i = 0, start = value(); + start && i < (int)(sizeof(buttons_) / sizeof(buttons_[0]) - 1); + start = end, i ++) { +// printf(" start = \"%s\"\n", start); + if ((end = strchr(start, '/')) == NULL) +#if defined(WIN32) || defined(__EMX__) + if ((end = strchr(start, '\\')) == NULL) +#endif // WIN32 || __EMX__ + break; + + end ++; + + buttons_[i] = (short)fl_width(start, end - start); + if (!i) buttons_[i] += Fl::box_dx(box()) + 6; + } + +// printf(" found %d components/buttons...\n", i); + + buttons_[i] = 0; +} + + +// +// 'Fl_File_Input::value()' - Set the value of the widget... +// + +int // O - TRUE on success +Fl_File_Input::value(const char *str, // I - New string value + int len) { // I - Length of value + damage(FL_DAMAGE_BAR); + return Fl_Input::value(str,len); +} + + +int // O - TRUE on success +Fl_File_Input::value(const char *str) { // I - New string value + damage(FL_DAMAGE_BAR); + return Fl_Input::value(str); +} + + +// +// 'Fl_File_Input::draw()' - Draw the file input widget... +// + +void +Fl_File_Input::draw() { + Fl_Boxtype b = box(); + if (damage() & (FL_DAMAGE_BAR | FL_DAMAGE_ALL)) draw_buttons(); + // this flag keeps Fl_Input_::drawtext from drawing a bogus box! + char must_trick_fl_input_ = + Fl::focus()!=this && !size() && !(damage()&FL_DAMAGE_ALL); + if ((damage() & FL_DAMAGE_ALL) || must_trick_fl_input_) + draw_box(b,x(),y()+DIR_HEIGHT,w(),h()-DIR_HEIGHT,color()); + if (!must_trick_fl_input_) + Fl_Input_::drawtext(x()+Fl::box_dx(b)+3, y()+Fl::box_dy(b)+DIR_HEIGHT, + w()-Fl::box_dw(b)-6, h()-Fl::box_dh(b)-DIR_HEIGHT); +} + + +// +// 'Fl_File_Input::handle()' - Handle events in the widget... +// + +int // O - TRUE if we handled event +Fl_File_Input::handle(int event) // I - Event +{ +// printf("handle(event = %d)\n", event); + + switch (event) { + case FL_MOVE : + case FL_ENTER : + if (active_r()) { + if (Fl::event_y() < (y() + DIR_HEIGHT)) window()->cursor(FL_CURSOR_DEFAULT); + else window()->cursor(FL_CURSOR_INSERT); + } + + return 1; + + case FL_PUSH : + case FL_RELEASE : + case FL_DRAG : + if (Fl::event_y() < (y() + DIR_HEIGHT) || pressed_ >= 0) return handle_button(event); + + return Fl_Input::handle(event); + + default : + if (Fl_Input::handle(event)) { + damage(FL_DAMAGE_BAR); + return 1; + } + + return 0; + } +} + + +// +// 'Fl_File_Input::handle_button()' - Handle button events in the widget... +// + +int // O - TRUE if we handled event +Fl_File_Input::handle_button(int event) // I - Event +{ + int i, // Looping var + X; // Current X position + char *start, // Start of path component + *end; // End of path component + char newvalue[1024]; // New value + + + // Figure out which button is being pressed... + for (X = 0, i = 0; buttons_[i]; i ++) + { + X += buttons_[i]; + + if (X > xscroll() && Fl::event_x() < (x() + X - xscroll())) break; + } + +// printf("handle_button(event = %d), button = %d\n", event, i); + + // Redraw the directory bar... + if (event == FL_RELEASE) pressed_ = -1; + else pressed_ = (short)i; + + window()->make_current(); + draw_buttons(); + + // Return immediately if the user is clicking on the last button or + // has not released the mouse button... + if (!buttons_[i] || event != FL_RELEASE) return 1; + + // Figure out where to truncate the path... + strlcpy(newvalue, value(), sizeof(newvalue)); + + for (start = newvalue, end = start; start && i >= 0; start = end, i --) { +// printf(" start = \"%s\"\n", start); + if ((end = strchr(start, '/')) == NULL) +#if defined(WIN32) || defined(__EMX__) + if ((end = strchr(start, '\\')) == NULL) +#endif // WIN32 || __EMX__ + break; + + end ++; + } + + if (i < 0) { + // Found the end; truncate the value and update the buttons... + *start = '\0'; + value(newvalue, start - newvalue); + + // Then do the callbacks, if necessary... + set_changed(); + if (when() & FL_WHEN_CHANGED) do_callback(); + } + + return 1; +} + + +// +// End of "$Id: Fl_File_Input.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Font.H b/plugins/zynaddsubfx/fltk/src/Fl_Font.H new file mode 100644 index 000000000..4781ae02a --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Font.H @@ -0,0 +1,111 @@ +// +// "$Id: Fl_Font.H 5334 2006-08-19 15:24:55Z matt $" +// +// Font definitions for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Two internal fltk data structures: +// +// Fl_Fontdesc: an entry into the fl_font() table. There is one of these +// for each fltk font number. +// +// Fl_FontSize: a structure for an actual system font, with junk to +// help choose it and info on character sizes. Each Fl_Fontdesc has a +// linked list of these. These are created the first time each system +// font/size combination is used. + +#ifndef FL_FONT_ +#define FL_FONT_ + +#include + +# if USE_XFT +typedef struct _XftFont XftFont; +# endif // USE_XFT + +class Fl_FontSize { +public: + Fl_FontSize *next; // linked list for this Fl_Fontdesc +# ifdef WIN32 + HFONT fid; + int width[256]; + TEXTMETRIC metr; + FL_EXPORT Fl_FontSize(const char* fontname, int size); +# elif defined(__APPLE_QD__) + FL_EXPORT Fl_FontSize(const char* fontname, int size); + short font, face, size; + short ascent, descent; + short width[256]; + bool knowMetrics; +# elif defined(__APPLE_QUARTZ__) + FL_EXPORT Fl_FontSize(const char* fontname, int size); + ATSUTextLayout layout; + ATSUStyle style; + short ascent, descent, q_width; + short width[256]; + bool knowWidths; + char *q_name; + int size; +# elif USE_XFT + XftFont* font; + const char* encoding; + int size; + FL_EXPORT Fl_FontSize(const char* xfontname); +# else + XFontStruct* font; // X font information + FL_EXPORT Fl_FontSize(const char* xfontname); +# endif + int minsize; // smallest point size that should use this + int maxsize; // largest point size that should use this +# if HAVE_GL + unsigned int listbase;// base of display list, 0 = none +# endif + FL_EXPORT ~Fl_FontSize(); +}; + +extern FL_EXPORT Fl_FontSize *fl_fontsize; // the currently selected one + +struct Fl_Fontdesc { + const char *name; + char fontname[128]; // "Pretty" font name + Fl_FontSize *first; // linked list of sizes of this style +# ifndef WIN32 + char **xlist; // matched X font names + int n; // size of xlist, negative = don't free xlist! +# endif +}; + +extern FL_EXPORT Fl_Fontdesc *fl_fonts; // the table + +# ifndef WIN32 +// functions for parsing X font names: +FL_EXPORT const char* fl_font_word(const char *p, int n); +FL_EXPORT char *fl_find_fontsize(char *name); +# endif + +#endif + +// +// End of "$Id: Fl_Font.H 5334 2006-08-19 15:24:55Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Gl_Choice.H b/plugins/zynaddsubfx/fltk/src/Fl_Gl_Choice.H new file mode 100644 index 000000000..68a783044 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Gl_Choice.H @@ -0,0 +1,132 @@ +// +// "$Id: Fl_Gl_Choice.H 4052 2005-02-24 21:55:12Z mike $" +// +// OpenGL definitions for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2001 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to "fltk-bugs@easysw.com". +// + +// Internal interface to set up OpenGL. +// +// A "Fl_Gl_Choice" is created from an OpenGL mode and holds information +// necessary to create a window (on X) and to create an OpenGL "context" +// (on both X and Win32). +// +// fl_create_gl_context takes a window (necessary only on Win32) and an +// Fl_Gl_Choice and returns a new OpenGL context. All contexts share +// display lists with each other. +// +// On X another fl_create_gl_context is provided to create it for any +// X visual. +// +// fl_set_gl_context makes the given OpenGL context current and makes +// it draw into the passed window. It tracks the current one context +// to avoid calling the context switching code when the same context +// is used, though it is a mystery to me why the GLX/WGL libraries +// don't do this themselves... +// +// fl_no_gl_context clears that cache so the next fl_set_gl_context is +// guaranteed to work. +// +// fl_delete_gl_context destroys the context. +// +// This code is used by Fl_Gl_Window, gl_start(), and gl_visual() + +#ifndef Fl_Gl_Choice_H +#define Fl_Gl_Choice_H + +// Warning: whatever GLContext is defined to must take exactly the same +// space in a structure as a void*!!! +#ifdef WIN32 +# include +# define GLContext HGLRC +#elif defined(__APPLE_QD__) +# include +# include +# define GLContext AGLContext +#elif defined(__APPLE_QUARTZ__) +// warning: the Quartz version should probably use Core GL (CGL) instead of AGL +# include +# include +# define GLContext AGLContext +#else +# include +# define GLContext GLXContext +#endif + +// Describes crap needed to create a GLContext. +class Fl_Gl_Choice { + int mode; + const int *alist; + Fl_Gl_Choice *next; +public: +#ifdef WIN32 + int pixelformat; // the visual to use + PIXELFORMATDESCRIPTOR pfd; // some wgl calls need this thing +#elif defined(__APPLE_QD__) + AGLPixelFormat pixelformat; +#elif defined(__APPLE_QUARTZ__) + // warning: the Quartz version should probably use Core GL (CGL) instead of AGL + AGLPixelFormat pixelformat; +#else + XVisualInfo *vis; // the visual to use + Colormap colormap; // a colormap for that visual +#endif + // Return one of these structures for a given gl mode. + // The second argument is a glX attribute list, and is used if mode is + // zero. This is not supported on Win32: + static Fl_Gl_Choice *find(int mode, const int *); +}; + +class Fl_Window; + +#ifdef WIN32 + +GLContext fl_create_gl_context(Fl_Window*, const Fl_Gl_Choice*, int layer=0); + +#elif defined(__APPLE_QD__) + +GLContext fl_create_gl_context(Fl_Window*, const Fl_Gl_Choice*, int layer=0); + +#elif defined(__APPLE_QUARTZ__) +// warning: the Quartz version should probably use Core GL (CGL) instead of AGL + +GLContext fl_create_gl_context(Fl_Window*, const Fl_Gl_Choice*, int layer=0); + +#else + +GLContext fl_create_gl_context(XVisualInfo* vis); + +static inline +GLContext fl_create_gl_context(Fl_Window*, const Fl_Gl_Choice* g) { + return fl_create_gl_context(g->vis); +} + +#endif + +void fl_set_gl_context(Fl_Window*, GLContext); +void fl_no_gl_context(); +void fl_delete_gl_context(GLContext); + +#endif + +// +// End of "$Id: Fl_Gl_Choice.H 4052 2005-02-24 21:55:12Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Group.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Group.cxx new file mode 100644 index 000000000..9a12da2fc --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Group.cxx @@ -0,0 +1,620 @@ +// +// "$Id: Fl_Group.cxx 6030 2008-02-20 17:42:08Z matt $" +// +// Group widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// The Fl_Group is the only defined container type in FLTK. + +// Fl_Window itself is a subclass of this, and most of the event +// handling is designed so windows themselves work correctly. + +#include +#include +#include +#include +#include +#include + +Fl_Group* Fl_Group::current_; + +// Hack: A single child is stored in the pointer to the array, while +// multiple children are stored in an allocated array: +Fl_Widget*const* Fl_Group::array() const { + return children_ <= 1 ? (Fl_Widget**)(&array_) : array_; +} + +int Fl_Group::find(const Fl_Widget* o) const { + Fl_Widget*const* a = array(); + int i; for (i=0; i < children_; i++) if (*a++ == o) break; + return i; +} + +// Metrowerks CodeWarrior and others can't export the static +// class member: current_, so these methods can't be inlined... +void Fl_Group::begin() {current_ = this;} +void Fl_Group::end() {current_ = (Fl_Group*)parent();} +Fl_Group *Fl_Group::current() {return current_;} +void Fl_Group::current(Fl_Group *g) {current_ = g;} + +extern Fl_Widget* fl_oldfocus; // set by Fl::focus + +// For back-compatability, we must adjust all events sent to child +// windows so they are relative to that window. + +static int send(Fl_Widget* o, int event) { + if (o->type() < FL_WINDOW) return o->handle(event); + switch ( event ) + { + case FL_DND_ENTER: + case FL_DND_DRAG: + // figure out correct type of event: + event = (o->contains(Fl::belowmouse())) ? FL_DND_DRAG : FL_DND_ENTER; + } + int save_x = Fl::e_x; Fl::e_x -= o->x(); + int save_y = Fl::e_y; Fl::e_y -= o->y(); + int ret = o->handle(event); + Fl::e_y = save_y; + Fl::e_x = save_x; + switch ( event ) + { + case FL_ENTER: + case FL_DND_ENTER: + // Successful completion of FL_ENTER means the widget is now the + // belowmouse widget, but only call Fl::belowmouse if the child + // widget did not do so: + if (!o->contains(Fl::belowmouse())) Fl::belowmouse(o); + break; + } + return ret; +} + +// translate the current keystroke into up/down/left/right for navigation: +#define ctrl(x) (x^0x40) +static int navkey() { + switch (Fl::event_key()) { + case 0: // not an FL_KEYBOARD/FL_SHORTCUT event + break; + case FL_Tab: + if (!Fl::event_state(FL_SHIFT)) return FL_Right; + case 0xfe20: // XK_ISO_Left_Tab + return FL_Left; + case FL_Right: + return FL_Right; + case FL_Left: + return FL_Left; + case FL_Up: + return FL_Up; + case FL_Down: + return FL_Down; + } + return 0; +} + +int Fl_Group::handle(int event) { + + Fl_Widget*const* a = array(); + int i; + Fl_Widget* o; + + switch (event) { + + case FL_FOCUS: + switch (navkey()) { + default: + if (savedfocus_ && savedfocus_->take_focus()) return 1; + case FL_Right: + case FL_Down: + for (i = children(); i--;) if ((*a++)->take_focus()) return 1; + break; + case FL_Left: + case FL_Up: + for (i = children(); i--;) if (a[i]->take_focus()) return 1; + break; + } + return 0; + + case FL_UNFOCUS: + savedfocus_ = fl_oldfocus; + return 0; + + case FL_KEYBOARD: + return navigation(navkey()); + + case FL_SHORTCUT: + for (i = children(); i--;) { + o = a[i]; + if (o->takesevents() && Fl::event_inside(o) && send(o,FL_SHORTCUT)) + return 1; + } + for (i = children(); i--;) { + o = a[i]; + if (o->takesevents() && !Fl::event_inside(o) && send(o,FL_SHORTCUT)) + return 1; + } + if ((Fl::event_key() == FL_Enter || Fl::event_key() == FL_KP_Enter)) return navigation(FL_Down); + return 0; + + case FL_ENTER: + case FL_MOVE: + for (i = children(); i--;) { + o = a[i]; + if (o->visible() && Fl::event_inside(o)) { + if (o->contains(Fl::belowmouse())) { + return send(o,FL_MOVE); + } else { + Fl::belowmouse(o); + if (send(o,FL_ENTER)) return 1; + } + } + } + Fl::belowmouse(this); + return 1; + + case FL_DND_ENTER: + case FL_DND_DRAG: + for (i = children(); i--;) { + o = a[i]; + if (o->takesevents() && Fl::event_inside(o)) { + if (o->contains(Fl::belowmouse())) { + return send(o,FL_DND_DRAG); + } else if (send(o,FL_DND_ENTER)) { + if (!o->contains(Fl::belowmouse())) Fl::belowmouse(o); + return 1; + } + } + } + Fl::belowmouse(this); + return 0; + + case FL_PUSH: + for (i = children(); i--;) { + o = a[i]; + if (o->takesevents() && Fl::event_inside(o)) { + if (send(o,FL_PUSH)) { + if (Fl::pushed() && !o->contains(Fl::pushed())) Fl::pushed(o); + return 1; + } + } + } + return 0; + + case FL_RELEASE: + case FL_DRAG: + o = Fl::pushed(); + if (o == this) return 0; + else if (o) send(o,event); + else { + for (i = children(); i--;) { + o = a[i]; + if (o->takesevents() && Fl::event_inside(o)) { + if (send(o,event)) return 1; + } + } + } + return 0; + + case FL_MOUSEWHEEL: + for (i = children(); i--;) { + o = a[i]; + if (o->takesevents() && Fl::event_inside(o) && send(o,FL_MOUSEWHEEL)) + return 1; + } + for (i = children(); i--;) { + o = a[i]; + if (o->takesevents() && !Fl::event_inside(o) && send(o,FL_MOUSEWHEEL)) + return 1; + } + return 0; + + case FL_DEACTIVATE: + case FL_ACTIVATE: + for (i = children(); i--;) { + o = *a++; + if (o->active()) o->handle(event); + } + return 1; + + case FL_SHOW: + case FL_HIDE: + for (i = children(); i--;) { + o = *a++; + if (event == FL_HIDE && o == Fl::focus()) { + // Give up input focus... + int old_event = Fl::e_number; + o->handle(Fl::e_number = FL_UNFOCUS); + Fl::e_number = old_event; + Fl::focus(0); + } + if (o->visible()) o->handle(event); + } + return 1; + + default: + // For all other events, try to give to each child, starting at focus: + for (i = 0; i < children(); i ++) + if (Fl::focus_ == a[i]) break; + + if (i >= children()) i = 0; + + if (children()) { + for (int j = i;;) { + if (a[j]->takesevents()) if (send(a[j], event)) return 1; + j++; + if (j >= children()) j = 0; + if (j == i) break; + } + } + + return 0; + } +} + +//void Fl_Group::focus(Fl_Widget *o) {Fl::focus(o); o->handle(FL_FOCUS);} + +#if 0 +const char *nameof(Fl_Widget *o) { + if (!o) return "NULL"; + if (!o->label()) return ""; + return o->label(); +} +#endif + +// try to move the focus in response to a keystroke: +int Fl_Group::navigation(int key) { + if (children() <= 1) return 0; + int i; + for (i = 0; ; i++) { + if (i >= children_) return 0; + if (array_[i]->contains(Fl::focus())) break; + } + Fl_Widget *previous = array_[i]; + + for (;;) { + switch (key) { + case FL_Right: + case FL_Down: + i++; + if (i >= children_) { + if (parent()) return 0; + i = 0; + } + break; + case FL_Left: + case FL_Up: + if (i) i--; + else { + if (parent()) return 0; + i = children_-1; + } + break; + default: + return 0; + } + Fl_Widget* o = array_[i]; + if (o == previous) return 0; + switch (key) { + case FL_Down: + case FL_Up: + // for up/down, the widgets have to overlap horizontally: + if (o->x() >= previous->x()+previous->w() || + o->x()+o->w() <= previous->x()) continue; + } + if (o->take_focus()) return 1; + } +} + +//////////////////////////////////////////////////////////////// + +Fl_Group::Fl_Group(int X,int Y,int W,int H,const char *l) +: Fl_Widget(X,Y,W,H,l) { + align(FL_ALIGN_TOP); + children_ = 0; + array_ = 0; + savedfocus_ = 0; + resizable_ = this; + sizes_ = 0; // this is allocated when first resize() is done + // Subclasses may want to construct child objects as part of their + // constructor, so make sure they are add()'d to this object. + // But you must end() the object! + begin(); +} + +void Fl_Group::clear() { + Fl_Widget*const* old_array = array(); + int old_children = children(); + // clear everything now, in case fl_fix_focus recursively calls us: + children_ = 0; + //array_ = 0; //dont do this, it will clobber old_array if only one child + savedfocus_ = 0; + resizable_ = this; + init_sizes(); + // okay, now it is safe to destroy the children: + Fl_Widget*const* a = old_array; + for (int i=old_children; i--;) { + Fl_Widget* o = *a++; + if (o->parent() == this) delete o; + } + if (old_children > 1) free((void*)old_array); +} + +Fl_Group::~Fl_Group() { + clear(); +} + +void Fl_Group::insert(Fl_Widget &o, int index) { + if (o.parent()) { + Fl_Group* g = (Fl_Group*)(o.parent()); + int n = g->find(o); + if (g == this) { + if (index > n) index--; + if (index == n) return; + } + g->remove(o); + } + o.parent_ = this; + if (children_ == 0) { // use array pointer to point at single child + array_ = (Fl_Widget**)&o; + } else if (children_ == 1) { // go from 1 to 2 children + Fl_Widget* t = (Fl_Widget*)array_; + array_ = (Fl_Widget**)malloc(2*sizeof(Fl_Widget*)); + if (index) {array_[0] = t; array_[1] = &o;} + else {array_[0] = &o; array_[1] = t;} + } else { + if (!(children_ & (children_-1))) // double number of children + array_ = (Fl_Widget**)realloc((void*)array_, + 2*children_*sizeof(Fl_Widget*)); + int j; for (j = children_; j > index; j--) array_[j] = array_[j-1]; + array_[j] = &o; + } + children_++; + init_sizes(); +} + +void Fl_Group::add(Fl_Widget &o) {insert(o, children_);} + +void Fl_Group::remove(Fl_Widget &o) { + if (!children_) return; + int i = find(o); + if (i >= children_) return; + if (&o == savedfocus_) savedfocus_ = 0; + o.parent_ = 0; + children_--; + if (children_ == 1) { // go from 2 to 1 child + Fl_Widget *t = array_[!i]; + free((void*)array_); + array_ = (Fl_Widget**)t; + } else if (children_ > 1) { // delete from array + for (; i < children_; i++) array_[i] = array_[i+1]; + } + init_sizes(); +} + +//////////////////////////////////////////////////////////////// + +// Rather lame kludge here, I need to detect windows and ignore the +// changes to X,Y, since all children are relative to X,Y. That +// is why I check type(): + +// sizes array stores the initial positions of widgets as +// left,right,top,bottom quads. The first quad is the group, the +// second is the resizable (clipped to the group), and the +// rest are the children. This is a convienent order for the +// algorithim. If you change this be sure to fix Fl_Tile which +// also uses this array! + +void Fl_Group::init_sizes() { + delete[] sizes_; sizes_ = 0; +} + +short* Fl_Group::sizes() { + if (!sizes_) { + short* p = sizes_ = new short[4*(children_+2)]; + // first thing in sizes array is the group's size: + if (type() < FL_WINDOW) {p[0] = x(); p[2] = y();} else {p[0] = p[2] = 0;} + p[1] = p[0]+w(); p[3] = p[2]+h(); + // next is the resizable's size: + p[4] = p[0]; // init to the group's size + p[5] = p[1]; + p[6] = p[2]; + p[7] = p[3]; + Fl_Widget* r = resizable(); + if (r && r != this) { // then clip the resizable to it + int t; + t = r->x(); if (t > p[0]) p[4] = t; + t +=r->w(); if (t < p[1]) p[5] = t; + t = r->y(); if (t > p[2]) p[6] = t; + t +=r->h(); if (t < p[3]) p[7] = t; + } + // next is all the children's sizes: + p += 8; + Fl_Widget*const* a = array(); + for (int i=children_; i--;) { + Fl_Widget* o = *a++; + *p++ = o->x(); + *p++ = o->x()+o->w(); + *p++ = o->y(); + *p++ = o->y()+o->h(); + } + } + return sizes_; +} + +void Fl_Group::resize(int X, int Y, int W, int H) { + + if (!resizable() || W==w() && H==h() ) { + + if (type() < FL_WINDOW) { + int dx = X-x(); + int dy = Y-y(); + Fl_Widget*const* a = array(); + for (int i=children_; i--;) { + Fl_Widget* o = *a++; + o->resize(o->x()+dx, o->y()+dy, o->w(), o->h()); + } + } + + } else if (children_) { + + short* p = sizes(); + + // get changes in size/position from the initial size: + int dx = X - p[0]; + int dw = W - (p[1]-p[0]); + int dy = Y - p[2]; + int dh = H - (p[3]-p[2]); + if (type() >= FL_WINDOW) dx = dy = 0; + p += 4; + + // get initial size of resizable(): + int IX = *p++; + int IR = *p++; + int IY = *p++; + int IB = *p++; + + Fl_Widget*const* a = array(); + for (int i=children_; i--;) { + Fl_Widget* o = *a++; +#if 1 + int XX = *p++; + if (XX >= IR) XX += dw; + else if (XX > IX) XX = IX+((XX-IX)*(IR+dw-IX)+(IR-IX)/2)/(IR-IX); + int R = *p++; + if (R >= IR) R += dw; + else if (R > IX) R = IX+((R-IX)*(IR+dw-IX)+(IR-IX)/2)/(IR-IX); + + int YY = *p++; + if (YY >= IB) YY += dh; + else if (YY > IY) YY = IY+((YY-IY)*(IB+dh-IY)+(IB-IY)/2)/(IB-IY); + int B = *p++; + if (B >= IB) B += dh; + else if (B > IY) B = IY+((B-IY)*(IB+dh-IY)+(IB-IY)/2)/(IB-IY); +#else // much simpler code from Francois Ostiguy: + int XX = *p++; + if (XX >= IR) XX += dw; + else if (XX > IX) XX += dw * (XX-IX)/(IR-IX); + int R = *p++; + if (R >= IR) R += dw; + else if (R > IX) R = R + dw * (R-IX)/(IR-IX); + + int YY = *p++; + if (YY >= IB) YY += dh; + else if (YY > IY) YY = YY + dh*(YY-IY)/(IB-IY); + int B = *p++; + if (B >= IB) B += dh; + else if (B > IY) B = B + dh*(B-IY)/(IB-IY); +#endif + o->resize(XX+dx, YY+dy, R-XX, B-YY); + } + } + + Fl_Widget::resize(X,Y,W,H); +} + +void Fl_Group::draw_children() { + Fl_Widget*const* a = array(); + + if (clip_children()) { + fl_push_clip(x() + Fl::box_dx(box()), + y() + Fl::box_dy(box()), + w() - Fl::box_dw(box()), + h() - Fl::box_dh(box())); + } + + if (damage() & ~FL_DAMAGE_CHILD) { // redraw the entire thing: + for (int i=children_; i--;) { + Fl_Widget& o = **a++; + draw_child(o); + draw_outside_label(o); + } + } else { // only redraw the children that need it: + for (int i=children_; i--;) update_child(**a++); + } + + if (clip_children()) fl_pop_clip(); +} + +void Fl_Group::draw() { + if (damage() & ~FL_DAMAGE_CHILD) { // redraw the entire thing: + draw_box(); + draw_label(); + } + draw_children(); +} + +// Draw a child only if it needs it: +void Fl_Group::update_child(Fl_Widget& widget) const { + if (widget.damage() && widget.visible() && widget.type() < FL_WINDOW && + fl_not_clipped(widget.x(), widget.y(), widget.w(), widget.h())) { + widget.draw(); + widget.clear_damage(); + } +} + +// Force a child to redraw: +void Fl_Group::draw_child(Fl_Widget& widget) const { + if (widget.visible() && widget.type() < FL_WINDOW && + fl_not_clipped(widget.x(), widget.y(), widget.w(), widget.h())) { + widget.clear_damage(FL_DAMAGE_ALL); + widget.draw(); + widget.clear_damage(); + } +} + +extern char fl_draw_shortcut; + +// Parents normally call this to draw outside labels: +void Fl_Group::draw_outside_label(const Fl_Widget& widget) const { + if (!widget.visible()) return; + // skip any labels that are inside the widget: + if (!(widget.align()&15) || (widget.align() & FL_ALIGN_INSIDE)) return; + // invent a box that is outside the widget: + int a = widget.align(); + int X = widget.x(); + int Y = widget.y(); + int W = widget.w(); + int H = widget.h(); + if (a & FL_ALIGN_TOP) { + a ^= (FL_ALIGN_BOTTOM|FL_ALIGN_TOP); + Y = y(); + H = widget.y()-Y; + } else if (a & FL_ALIGN_BOTTOM) { + a ^= (FL_ALIGN_BOTTOM|FL_ALIGN_TOP); + Y = Y+H; + H = y()+h()-Y; + } else if (a & FL_ALIGN_LEFT) { + a ^= (FL_ALIGN_LEFT|FL_ALIGN_RIGHT); + X = x(); + W = widget.x()-X-3; + } else if (a & FL_ALIGN_RIGHT) { + a ^= (FL_ALIGN_LEFT|FL_ALIGN_RIGHT); + X = X+W+3; + W = x()+this->w()-X; + } + widget.draw_label(X,Y,W,H,(Fl_Align)a); +} + +// +// End of "$Id: Fl_Group.cxx 6030 2008-02-20 17:42:08Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Help_Dialog.fl b/plugins/zynaddsubfx/fltk/src/Fl_Help_Dialog.fl new file mode 100644 index 000000000..909e2ba37 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Help_Dialog.fl @@ -0,0 +1,265 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0108 +header_name {../FL/Fl_Help_Dialog.H} +code_name {.cxx} +comment {// +// "$Id: Fl_Help_Dialog.fl 5643 2007-01-28 19:36:51Z mike $" +// +// Fl_Help_Dialog dialog for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +} {in_source in_header +} + +decl {\#include "flstring.h"} {} + +decl {\#include } {} + +class FL_EXPORT Fl_Help_Dialog {open +} { + decl {int index_;} {} + decl {int max_;} {} + decl {int line_[100];} {} + decl {char file_[100][256];} {} + decl {int find_pos_;} {} + Function {Fl_Help_Dialog()} {open + } { + Fl_Window window_ { + label {Help Dialog} open + private xywh {398 64 530 385} type Double resizable size_range {260 150 0 0} visible + } { + Fl_Group {} {open selected + xywh {10 10 511 25} + } { + Fl_Button back_ { + label {@<-} + callback {if (index_ > 0) + index_ --; + +if (index_ == 0) + back_->deactivate(); + +forward_->activate(); + +int l = line_[index_]; + +if (strcmp(view_->filename(), file_[index_]) != 0) + view_->load(file_[index_]); + +view_->topline(l);} + private tooltip {Show the previous help page.} xywh {10 10 25 25} shortcut 0xff51 labelcolor 2 + } + Fl_Button forward_ { + label {@->} + callback {if (index_ < max_) + index_ ++; + +if (index_ >= max_) + forward_->deactivate(); + +back_->activate(); + +int l = view_->topline(); + +if (strcmp(view_->filename(), file_[index_]) != 0) + view_->load(file_[index_]); + +view_->topline(l);} + private tooltip {Show the next help page.} xywh {45 10 25 25} shortcut 0xff53 labelcolor 2 + } + Fl_Button smaller_ { + label F + callback {if (view_->textsize() > 8) + view_->textsize(view_->textsize() - 2); + +if (view_->textsize() <= 8) + smaller_->deactivate(); +larger_->activate();} + private tooltip {Make the help text smaller.} xywh {80 10 25 25} labelfont 1 labelsize 10 + } + Fl_Button larger_ { + label F + callback {if (view_->textsize() < 18) + view_->textsize(view_->textsize() + 2); + +if (view_->textsize() >= 18) + larger_->deactivate(); +smaller_->activate();} + private tooltip {Make the help text larger.} xywh {115 10 25 25} labelfont 1 labelsize 16 + } + Fl_Group {} {open + xywh {350 10 171 25} box DOWN_BOX color 7 + } { + Fl_Input find_ { + label {@search} + callback {find_pos_ = view_->find(find_->value(), find_pos_);} + private tooltip {find text in document} xywh {375 12 143 21} box FLAT_BOX labelsize 13 when 10 textfont 4 + } + } + Fl_Box {} { + xywh {150 10 190 25} resizable + } + } + Fl_Help_View view_ { + callback {if (view_->filename()) +{ + if (view_->changed()) + { + index_ ++; + + if (index_ >= 100) + { + memmove(line_, line_ + 10, sizeof(line_[0]) * 90); + memmove(file_, file_ + 10, sizeof(file_[0]) * 90); + index_ -= 10; + } + + max_ = index_; + + strlcpy(file_[index_], view_->filename(),sizeof(file_[0])); + line_[index_] = view_->topline(); + + if (index_ > 0) + back_->activate(); + else + back_->deactivate(); + + forward_->deactivate(); + window_->label(view_->title()); + } + else // if ! view_->changed() + { + strlcpy(file_[index_], view_->filename(), sizeof(file_[0])); + line_[index_] = view_->topline(); + } +} else { // if ! view_->filename() + index_ = 0; // hitting an internal page will disable the back/fwd buffer + file_[index_][0] = 0; // unnamed internal page + line_[index_] = view_->topline(); + back_->deactivate(); + forward_->deactivate(); +}} + private xywh {10 45 510 330} box DOWN_BOX resizable + } + } + code {back_->deactivate(); +forward_->deactivate(); + +index_ = -1; +max_ = 0; +find_pos_ = 0; + +fl_register_images();} {} + } + Function {~Fl_Help_Dialog()} {} { + code {delete window_;} {} + } + Function {h()} {return_type int + } { + code {return (window_->h());} {} + } + Function {hide()} {return_type void + } { + code {window_->hide();} {} + } + Function {load(const char *f)} {return_type void + } { + code {view_->set_changed(); +view_->load(f); +window_->label(view_->title());} {} + } + Function {position(int xx, int yy)} {return_type void + } { + code {window_->position(xx, yy);} {} + } + Function {resize(int xx, int yy, int ww, int hh)} {return_type void + } { + code {window_->resize(xx, yy, ww, hh);} {} + } + Function {show()} {return_type void + } { + code {window_->show();} {} + } + Function {show(int argc, char **argv)} {return_type void + } { + code {window_->show(argc, argv);} {} + } + Function {textsize(uchar s)} {return_type void + } { + code {view_->textsize(s); + +if (s <= 8) + smaller_->deactivate(); +else + smaller_->activate(); + +if (s >= 18) + larger_->deactivate(); +else + larger_->activate();} {} + } + Function {textsize()} {return_type uchar + } { + code {return (view_->textsize());} {} + } + Function {topline(const char *n)} {return_type void + } { + code {view_->topline(n);} {} + } + Function {topline(int n)} {return_type void + } { + code {view_->topline(n);} {} + } + Function {value(const char *f)} {return_type void + } { + code {view_->set_changed(); +view_->value(f); +window_->label(view_->title());} {} + } + Function {value() const} {return_type {const char *} + } { + code {return view_->value();} {} + } + Function {visible()} {return_type int + } { + code {return (window_->visible());} {} + } + Function {w()} {return_type int + } { + code {return (window_->w());} {} + } + Function {x()} {return_type int + } { + code {return (window_->x());} {} + } + Function {y()} {return_type int + } { + code {return (window_->y());} {} + } +} + +comment { +// +// End of "$Id: Fl_Help_Dialog.fl 5643 2007-01-28 19:36:51Z mike $". +//} {in_source in_header +} diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Help_View.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Help_View.cxx new file mode 100644 index 000000000..d8e9d35b6 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Help_View.cxx @@ -0,0 +1,3454 @@ +// +// "$Id: Fl_Help_View.cxx 6091 2008-04-11 11:12:16Z matt $" +// +// Fl_Help_View widget routines. +// +// Copyright 1997-2007 by Easy Software Products. +// Image support donated by Matthias Melcher, Copyright 2000. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +// Contents: +// +// Fl_Help_View::add_block() - Add a text block to the list. +// Fl_Help_View::add_link() - Add a new link to the list. +// Fl_Help_View::add_target() - Add a new target to the list. +// Fl_Help_View::compare_targets() - Compare two targets. +// Fl_Help_View::do_align() - Compute the alignment for a line in +// a block. +// Fl_Help_View::draw() - Draw the Fl_Help_View widget. +// Fl_Help_View::format() - Format the help text. +// Fl_Help_View::format_table() - Format a table... +// Fl_Help_View::free_data() - Free memory used for the document. +// Fl_Help_View::get_align() - Get an alignment attribute. +// Fl_Help_View::get_attr() - Get an attribute value from the string. +// Fl_Help_View::get_color() - Get an alignment attribute. +// Fl_Help_View::handle() - Handle events in the widget. +// Fl_Help_View::Fl_Help_View() - Build a Fl_Help_View widget. +// Fl_Help_View::~Fl_Help_View() - Destroy a Fl_Help_View widget. +// Fl_Help_View::load() - Load the specified file. +// Fl_Help_View::resize() - Resize the help widget. +// Fl_Help_View::topline() - Set the top line to the named target. +// Fl_Help_View::topline() - Set the top line by number. +// Fl_Help_View::value() - Set the help text directly. +// scrollbar_callback() - A callback for the scrollbar. +// + +// +// Include necessary header files... +// + +#include +#include +#include +#include +#include +#include +#include "flstring.h" +#include +#include +#include + +#if defined(WIN32) && ! defined(__CYGWIN__) +# include +# include +// Visual C++ 2005 incorrectly displays a warning about the use of POSIX APIs +// on Windows, which is supposed to be POSIX compliant... +# define getcwd _getcwd +#else +# include +#endif // WIN32 + +#define MAX_COLUMNS 200 + + +// +// Typedef the C API sort function type the only way I know how... +// + +extern "C" +{ + typedef int (*compare_func_t)(const void *, const void *); +} + + +// +// Local functions... +// + +static int quote_char(const char *); +static void scrollbar_callback(Fl_Widget *s, void *); +static void hscrollbar_callback(Fl_Widget *s, void *); + + +// +// Broken image... +// + +static const char *broken_xpm[] = + { + "16 24 4 1", + "@ c #000000", + " c #ffffff", + "+ c none", + "x c #ff0000", + // pixels + "@@@@@@@+++++++++", + "@ @++++++++++", + "@ @+++++++++++", + "@ @++@++++++++", + "@ @@+++++++++", + "@ @+++@+++++", + "@ @++@@++++@", + "@ xxx @@ @++@@", + "@ xxx xx@@ @", + "@ xxx xxx @", + "@ xxxxxx @", + "@ xxxx @", + "@ xxxxxx @", + "@ xxx xxx @", + "@ xxx xxx @", + "@ xxx xxx @", + "@ @", + "@ @", + "@ @", + "@ @", + "@ @", + "@ @", + "@ @", + "@@@@@@@@@@@@@@@@", + NULL + }; + +static Fl_Pixmap broken_image(broken_xpm); + +// +// Simple margin stack for Fl_Help_View::format()... +// + +struct fl_margins { + int depth_; + int margins_[100]; + + fl_margins() { clear(); } + + int clear() { +// puts("fl_margins::clear()"); + + depth_ = 0; + return margins_[0] = 4; + } + + int current() { return margins_[depth_]; } + + int pop() { +// printf("fl_margins::pop(): depth_=%d, xx=%d\n", depth_, +// depth_ > 0 ? margins_[depth_ - 1] : 4); + + if (depth_ > 0) { + depth_ --; + return margins_[depth_]; + } else return 4; + } + + int push(int indent) { + int xx; + + xx = margins_[depth_] + indent; + +// printf("fl_margins::push(indent=%d): depth_=%d, xx=%d\n", indent, +// depth_ + 1, xx); + + if (depth_ < 99) { + depth_ ++; + margins_[depth_] = xx; + } + + return xx; + } +}; + +// +// All the stuff needed to implement text selection in Fl_Help_View +// + +/* matt: + * We are trying to keep binary compatibility with previous versions + * of FLTK. This means that we are limited to adding static variables + * only to not enlarge the Fl_Help_View class. Lucky for us, only one + * text can be selected system wide, so we can remember the selection + * in a single set of variables. + * + * Still to do: + * - &word; style characters mess up our count inside a word boundary + * - we can only select words, no individual characters + * - no dragging of the selection into another widget + * - selection must be cleared if another widget get focus! + * - write a comment for every new function + */ + +/* +The following functions are also used to draw stuff and should be replaced with +local copies that are much faster when merely counting: + +fl_color(Fl_Color); +fl_rectf(int, int, int, int); +fl_push_clip(int, int, int, int); +fl_xyline(int, int, int); +fl_rect() +fl_line() +img->draw() +*/ + +// We don't put the offscreen buffer in the help view class because +// we'd need to include x.H in the header... +static Fl_Offscreen fl_help_view_buffer; +int Fl_Help_View::selection_first = 0; +int Fl_Help_View::selection_last = 0; +int Fl_Help_View::selection_push_first = 0; +int Fl_Help_View::selection_push_last = 0; +int Fl_Help_View::selection_drag_first = 0; +int Fl_Help_View::selection_drag_last = 0; +int Fl_Help_View::selected = 0; +int Fl_Help_View::draw_mode = 0; +int Fl_Help_View::mouse_x = 0; +int Fl_Help_View::mouse_y = 0; +int Fl_Help_View::current_pos = 0; +Fl_Help_View *Fl_Help_View::current_view = 0L; +Fl_Color Fl_Help_View::hv_selection_color; +Fl_Color Fl_Help_View::hv_selection_text_color; + +/* + * Limitation: if a word contains &code; notations, we will calculate a wrong length. + * + * This function must be optimized for speed! + */ +void Fl_Help_View::hv_draw(const char *t, int x, int y) +{ + if (selected && current_view==this && current_pos=selection_first) { + Fl_Color c = fl_color(); + fl_color(hv_selection_color); + int w = (int)fl_width(t); + if (current_pos+(int)strlen(t)=x && mouse_x=y-fl_height()+fl_descent()&&mouse_y<=y+fl_descent()) { + int f = current_pos; + int l = f+strlen(t); // use 'quote_char' to calculate the true length of the HTML string + if (draw_mode==1) { + selection_push_first = f; + selection_push_last = l; + } else { + selection_drag_first = f; + selection_drag_last = l; + } + } + } + } +} + + +// +// 'Fl_Help_View::add_block()' - Add a text block to the list. +// + +Fl_Help_Block * // O - Pointer to new block +Fl_Help_View::add_block(const char *s, // I - Pointer to start of block text + int xx, // I - X position of block + int yy, // I - Y position of block + int ww, // I - Right margin of block + int hh, // I - Height of block + unsigned char border) // I - Draw border? +{ + Fl_Help_Block *temp; // New block + + +// printf("add_block(s = %p, xx = %d, yy = %d, ww = %d, hh = %d, border = %d)\n", +// s, xx, yy, ww, hh, border); + + if (nblocks_ >= ablocks_) + { + ablocks_ += 16; + + if (ablocks_ == 16) + blocks_ = (Fl_Help_Block *)malloc(sizeof(Fl_Help_Block) * ablocks_); + else + blocks_ = (Fl_Help_Block *)realloc(blocks_, sizeof(Fl_Help_Block) * ablocks_); + } + + temp = blocks_ + nblocks_; + memset(temp, 0, sizeof(Fl_Help_Block)); + temp->start = s; + temp->end = s; + temp->x = xx; + temp->y = yy; + temp->w = ww; + temp->h = hh; + temp->border = border; + temp->bgcolor = bgcolor_; + nblocks_ ++; + + return (temp); +} + + +// +// 'Fl_Help_View::add_link()' - Add a new link to the list. +// + +void +Fl_Help_View::add_link(const char *n, // I - Name of link + int xx, // I - X position of link + int yy, // I - Y position of link + int ww, // I - Width of link text + int hh) // I - Height of link text +{ + Fl_Help_Link *temp; // New link + char *target; // Pointer to target name + + + if (nlinks_ >= alinks_) + { + alinks_ += 16; + + if (alinks_ == 16) + links_ = (Fl_Help_Link *)malloc(sizeof(Fl_Help_Link) * alinks_); + else + links_ = (Fl_Help_Link *)realloc(links_, sizeof(Fl_Help_Link) * alinks_); + } + + temp = links_ + nlinks_; + + temp->x = xx; + temp->y = yy; + temp->w = xx + ww; + temp->h = yy + hh; + + strlcpy(temp->filename, n, sizeof(temp->filename)); + + if ((target = strrchr(temp->filename, '#')) != NULL) + { + *target++ = '\0'; + strlcpy(temp->name, target, sizeof(temp->name)); + } + else + temp->name[0] = '\0'; + + nlinks_ ++; +} + + +// +// 'Fl_Help_View::add_target()' - Add a new target to the list. +// + +void +Fl_Help_View::add_target(const char *n, // I - Name of target + int yy) // I - Y position of target +{ + Fl_Help_Target *temp; // New target + + + if (ntargets_ >= atargets_) + { + atargets_ += 16; + + if (atargets_ == 16) + targets_ = (Fl_Help_Target *)malloc(sizeof(Fl_Help_Target) * atargets_); + else + targets_ = (Fl_Help_Target *)realloc(targets_, sizeof(Fl_Help_Target) * atargets_); + } + + temp = targets_ + ntargets_; + + temp->y = yy; + strlcpy(temp->name, n, sizeof(temp->name)); + + ntargets_ ++; +} + + +// +// 'Fl_Help_View::compare_targets()' - Compare two targets. +// + +int // O - Result of comparison +Fl_Help_View::compare_targets(const Fl_Help_Target *t0, // I - First target + const Fl_Help_Target *t1) // I - Second target +{ + return (strcasecmp(t0->name, t1->name)); +} + + +// +// 'Fl_Help_View::do_align()' - Compute the alignment for a line in a block. +// + +int // O - New line +Fl_Help_View::do_align(Fl_Help_Block *block, // I - Block to add to + int line, // I - Current line + int xx, // I - Current X position + int a, // I - Current alignment + int &l) // IO - Starting link +{ + int offset; // Alignment offset + + + switch (a) + { + case RIGHT : // Right align + offset = block->w - xx; + break; + case CENTER : // Center + offset = (block->w - xx) / 2; + break; + default : // Left align + offset = 0; + break; + } + + block->line[line] = block->x + offset; + + if (line < 31) + line ++; + + while (l < nlinks_) + { + links_[l].x += offset; + links_[l].w += offset; + l ++; + } + + return (line); +} + + +// +// 'Fl_Help_View::draw()' - Draw the Fl_Help_View widget. +// + +void +Fl_Help_View::draw() +{ + int i; // Looping var + const Fl_Help_Block *block; // Pointer to current block + const char *ptr, // Pointer to text in block + *attrs; // Pointer to start of element attributes + char *s, // Pointer into buffer + buf[1024], // Text buffer + attr[1024]; // Attribute buffer + int xx, yy, ww, hh; // Current positions and sizes + int line; // Current line + unsigned char font, fsize; // Current font and size + int head, pre, // Flags for text + needspace; // Do we need whitespace? + Fl_Boxtype b = box() ? box() : FL_DOWN_BOX; + // Box to draw... + int underline, // Underline text? + xtra_ww; // Extra width for underlined space between words + + + // Draw the scrollbar(s) and box first... + ww = w() ; + hh = h(); + i = 0; + + draw_box(b, x(), y(), ww, hh, bgcolor_); + + int ss = Fl::scrollbar_size(); + if (hscrollbar_.visible()) { + draw_child(hscrollbar_); + hh -= ss; + i ++; + } + if (scrollbar_.visible()) { + draw_child(scrollbar_); + ww -= ss; + i ++; + } + if (i == 2) { + fl_color(FL_GRAY); + fl_rectf(x() + ww - Fl::box_dw(b) + Fl::box_dx(b), + y() + hh - Fl::box_dh(b) + Fl::box_dy(b), ss, ss); + } + + if (!value_) + return; + + if (current_view == this && selected) { + hv_selection_color = FL_SELECTION_COLOR; + hv_selection_text_color = fl_contrast(textcolor_, FL_SELECTION_COLOR); + } + current_pos = 0; + + // Clip the drawing to the inside of the box... + fl_push_clip(x() + Fl::box_dx(b), y() + Fl::box_dy(b), + ww - Fl::box_dw(b), hh - Fl::box_dh(b)); + fl_color(textcolor_); + + // Draw all visible blocks... + for (i = 0, block = blocks_; i < nblocks_; i ++, block ++) + if ((block->y + block->h) >= topline_ && block->y < (topline_ + h())) + { + line = 0; + xx = block->line[line]; + yy = block->y - topline_; + hh = 0; + pre = 0; + head = 0; + needspace = 0; + underline = 0; + + initfont(font, fsize); + + for (ptr = block->start, s = buf; ptr < block->end;) + { + if ((*ptr == '<' || isspace((*ptr)&255)) && s > buf) + { + if (!head && !pre) + { + // Check width... + *s = '\0'; + s = buf; + ww = (int)fl_width(buf); + + if (needspace && xx > block->x) + xx += (int)fl_width(' '); + + if ((xx + ww) > block->w) + { + if (line < 31) + line ++; + xx = block->line[line]; + yy += hh; + hh = 0; + } + + hv_draw(buf, xx + x() - leftline_, yy + y()); + if (underline) { + xtra_ww = isspace((*ptr)&255)?(int)fl_width(' '):0; + fl_xyline(xx + x() - leftline_, yy + y() + 1, + xx + x() - leftline_ + ww + xtra_ww); + } + current_pos = ptr-value_; + + xx += ww; + if ((fsize + 2) > hh) + hh = fsize + 2; + + needspace = 0; + } + else if (pre) + { + while (isspace((*ptr)&255)) + { + if (*ptr == '\n') + { + *s = '\0'; + s = buf; + + hv_draw(buf, xx + x() - leftline_, yy + y()); + if (underline) fl_xyline(xx + x() - leftline_, yy + y() + 1, + xx + x() - leftline_ + + (int)fl_width(buf)); + + current_pos = ptr-value_; + if (line < 31) + line ++; + xx = block->line[line]; + yy += hh; + hh = fsize + 2; + } + else if (*ptr == '\t') + { + // Do tabs every 8 columns... + while (((s - buf) & 7)) + *s++ = ' '; + } + else + *s++ = ' '; + + if ((fsize + 2) > hh) + hh = fsize + 2; + + ptr ++; + } + + if (s > buf) + { + *s = '\0'; + s = buf; + + hv_draw(buf, xx + x() - leftline_, yy + y()); + ww = (int)fl_width(buf); + if (underline) fl_xyline(xx + x() - leftline_, yy + y() + 1, + xx + x() - leftline_ + ww); + xx += ww; + current_pos = ptr-value_; + } + + needspace = 0; + } + else + { + s = buf; + + while (isspace((*ptr)&255)) + ptr ++; + current_pos = ptr-value_; + } + } + + if (*ptr == '<') + { + ptr ++; + + if (strncmp(ptr, "!--", 3) == 0) + { + // Comment... + ptr += 3; + if ((ptr = strstr(ptr, "-->")) != NULL) + { + ptr += 3; + continue; + } + else + break; + } + + while (*ptr && *ptr != '>' && !isspace((*ptr)&255)) + if (s < (buf + sizeof(buf) - 1)) + *s++ = *ptr++; + else + ptr ++; + + *s = '\0'; + s = buf; + + attrs = ptr; + while (*ptr && *ptr != '>') + ptr ++; + + if (*ptr == '>') + ptr ++; + + // end of command reached, set the supposed start of printed eord here + current_pos = ptr-value_; + if (strcasecmp(buf, "HEAD") == 0) + head = 1; + else if (strcasecmp(buf, "BR") == 0) + { + if (line < 31) + line ++; + xx = block->line[line]; + yy += hh; + hh = 0; + } + else if (strcasecmp(buf, "HR") == 0) + { + fl_line(block->x + x(), yy + y(), block->w + x(), + yy + y()); + + if (line < 31) + line ++; + xx = block->line[line]; + yy += 2 * hh; + hh = 0; + } + else if (strcasecmp(buf, "CENTER") == 0 || + strcasecmp(buf, "P") == 0 || + strcasecmp(buf, "H1") == 0 || + strcasecmp(buf, "H2") == 0 || + strcasecmp(buf, "H3") == 0 || + strcasecmp(buf, "H4") == 0 || + strcasecmp(buf, "H5") == 0 || + strcasecmp(buf, "H6") == 0 || + strcasecmp(buf, "UL") == 0 || + strcasecmp(buf, "OL") == 0 || + strcasecmp(buf, "DL") == 0 || + strcasecmp(buf, "LI") == 0 || + strcasecmp(buf, "DD") == 0 || + strcasecmp(buf, "DT") == 0 || + strcasecmp(buf, "PRE") == 0) + { + if (tolower(buf[0]) == 'h') + { + font = FL_HELVETICA_BOLD; + fsize = (uchar)(textsize_ + '7' - buf[1]); + } + else if (strcasecmp(buf, "DT") == 0) + { + font = (uchar)(textfont_ | FL_ITALIC); + fsize = textsize_; + } + else if (strcasecmp(buf, "PRE") == 0) + { + font = FL_COURIER; + fsize = textsize_; + pre = 1; + } + + if (strcasecmp(buf, "LI") == 0) + { +#ifdef __APPLE_QUARTZ__ + fl_font(FL_SYMBOL, fsize); + hv_draw("\245", xx - fsize + x() - leftline_, yy + y()); +#else + fl_font(FL_SYMBOL, fsize); + hv_draw("\267", xx - fsize + x() - leftline_, yy + y()); +#endif + } + + pushfont(font, fsize); + } + else if (strcasecmp(buf, "A") == 0 && + get_attr(attrs, "HREF", attr, sizeof(attr)) != NULL) + { + fl_color(linkcolor_); + underline = 1; + } + else if (strcasecmp(buf, "/A") == 0) + { + fl_color(textcolor_); + underline = 0; + } + else if (strcasecmp(buf, "FONT") == 0) + { + if (get_attr(attrs, "COLOR", attr, sizeof(attr)) != NULL) { + fl_color(get_color(attr, textcolor_)); + } + + if (get_attr(attrs, "FACE", attr, sizeof(attr)) != NULL) { + if (!strncasecmp(attr, "helvetica", 9) || + !strncasecmp(attr, "arial", 5) || + !strncasecmp(attr, "sans", 4)) font = FL_HELVETICA; + else if (!strncasecmp(attr, "times", 5) || + !strncasecmp(attr, "serif", 5)) font = FL_TIMES; + else if (!strncasecmp(attr, "symbol", 6)) font = FL_SYMBOL; + else font = FL_COURIER; + } + + if (get_attr(attrs, "SIZE", attr, sizeof(attr)) != NULL) { + if (isdigit(attr[0] & 255)) { + // Absolute size + fsize = (int)(textsize_ * pow(1.2, atof(attr) - 3.0)); + } else { + // Relative size + fsize = (int)(fsize * pow(1.2, atof(attr) - 3.0)); + } + } + + pushfont(font, fsize); + } + else if (strcasecmp(buf, "/FONT") == 0) + { + fl_color(textcolor_); + popfont(font, fsize); + } + else if (strcasecmp(buf, "U") == 0) + underline = 1; + else if (strcasecmp(buf, "/U") == 0) + underline = 0; + else if (strcasecmp(buf, "B") == 0 || + strcasecmp(buf, "STRONG") == 0) + pushfont(font |= FL_BOLD, fsize); + else if (strcasecmp(buf, "TD") == 0 || + strcasecmp(buf, "TH") == 0) + { + int tx, ty, tw, th; + + if (tolower(buf[1]) == 'h') + pushfont(font |= FL_BOLD, fsize); + else + pushfont(font = textfont_, fsize); + + tx = block->x - 4 - leftline_; + ty = block->y - topline_ - fsize - 3; + tw = block->w - block->x + 7; + th = block->h + fsize - 5; + + if (tx < 0) + { + tw += tx; + tx = 0; + } + + if (ty < 0) + { + th += ty; + ty = 0; + } + + tx += x(); + ty += y(); + + if (block->bgcolor != bgcolor_) + { + fl_color(block->bgcolor); + fl_rectf(tx, ty, tw, th); + fl_color(textcolor_); + } + + if (block->border) + fl_rect(tx, ty, tw, th); + } + else if (strcasecmp(buf, "I") == 0 || + strcasecmp(buf, "EM") == 0) + pushfont(font |= FL_ITALIC, fsize); + else if (strcasecmp(buf, "CODE") == 0 || + strcasecmp(buf, "TT") == 0) + pushfont(font = FL_COURIER, fsize); + else if (strcasecmp(buf, "KBD") == 0) + pushfont(font = FL_COURIER_BOLD, fsize); + else if (strcasecmp(buf, "VAR") == 0) + pushfont(font = FL_COURIER_ITALIC, fsize); + else if (strcasecmp(buf, "/HEAD") == 0) + head = 0; + else if (strcasecmp(buf, "/H1") == 0 || + strcasecmp(buf, "/H2") == 0 || + strcasecmp(buf, "/H3") == 0 || + strcasecmp(buf, "/H4") == 0 || + strcasecmp(buf, "/H5") == 0 || + strcasecmp(buf, "/H6") == 0 || + strcasecmp(buf, "/B") == 0 || + strcasecmp(buf, "/STRONG") == 0 || + strcasecmp(buf, "/I") == 0 || + strcasecmp(buf, "/EM") == 0 || + strcasecmp(buf, "/CODE") == 0 || + strcasecmp(buf, "/TT") == 0 || + strcasecmp(buf, "/KBD") == 0 || + strcasecmp(buf, "/VAR") == 0) + popfont(font, fsize); + else if (strcasecmp(buf, "/PRE") == 0) + { + popfont(font, fsize); + pre = 0; + } + else if (strcasecmp(buf, "IMG") == 0) + { + Fl_Shared_Image *img = 0; + int width, height; + char wattr[8], hattr[8]; + + + get_attr(attrs, "WIDTH", wattr, sizeof(wattr)); + get_attr(attrs, "HEIGHT", hattr, sizeof(hattr)); + width = get_length(wattr); + height = get_length(hattr); + + if (get_attr(attrs, "SRC", attr, sizeof(attr))) { + img = get_image(attr, width, height); + if (!width) width = img->w(); + if (!height) height = img->h(); + } + + if (!width || !height) { + if (get_attr(attrs, "ALT", attr, sizeof(attr)) == NULL) { + strcpy(attr, "IMG"); + } + } + + ww = width; + + if (needspace && xx > block->x) + xx += (int)fl_width(' '); + + if ((xx + ww) > block->w) + { + if (line < 31) + line ++; + + xx = block->line[line]; + yy += hh; + hh = 0; + } + + if (img) { + img->draw(xx + x() - leftline_, + yy + y() - fl_height() + fl_descent() + 2); + img->release(); + } + + xx += ww; + if ((height + 2) > hh) + hh = height + 2; + + needspace = 0; + } + } + else if (*ptr == '\n' && pre) + { + *s = '\0'; + s = buf; + + hv_draw(buf, xx + x() - leftline_, yy + y()); + + if (line < 31) + line ++; + xx = block->line[line]; + yy += hh; + hh = fsize + 2; + needspace = 0; + + ptr ++; + current_pos = ptr-value_; + } + else if (isspace((*ptr)&255)) + { + if (pre) + { + if (*ptr == ' ') + *s++ = ' '; + else + { + // Do tabs every 8 columns... + while (((s - buf) & 7)) + *s++ = ' '; + } + } + + ptr ++; + if (!pre) current_pos = ptr-value_; + needspace = 1; + } + else if (*ptr == '&') + { + ptr ++; + + int qch = quote_char(ptr); + + if (qch < 0) + *s++ = '&'; + else { + *s++ = qch; + ptr = strchr(ptr, ';') + 1; + } + + if ((fsize + 2) > hh) + hh = fsize + 2; + } + else + { + *s++ = *ptr++; + + if ((fsize + 2) > hh) + hh = fsize + 2; + } + } + + *s = '\0'; + + if (s > buf && !pre && !head) + { + ww = (int)fl_width(buf); + + if (needspace && xx > block->x) + xx += (int)fl_width(' '); + + if ((xx + ww) > block->w) + { + if (line < 31) + line ++; + xx = block->line[line]; + yy += hh; + hh = 0; + } + } + + if (s > buf && !head) + { + hv_draw(buf, xx + x() - leftline_, yy + y()); + if (underline) fl_xyline(xx + x() - leftline_, yy + y() + 1, + xx + x() - leftline_ + ww); + current_pos = ptr-value_; + } + } + + fl_pop_clip(); +} + + +// +// 'Fl_Help_View::find()' - Find the specified string... +// + +int // O - Matching position or -1 if not found +Fl_Help_View::find(const char *s, // I - String to find + int p) // I - Starting position +{ + int i, // Looping var + c; // Current character + Fl_Help_Block *b; // Current block + const char *bp, // Block matching pointer + *bs, // Start of current comparison + *sp; // Search string pointer + + + // Range check input and value... + if (!s || !value_) return -1; + + if (p < 0 || p >= (int)strlen(value_)) p = 0; + else if (p > 0) p ++; + + // Look for the string... + for (i = nblocks_, b = blocks_; i > 0; i --, b ++) { + if (b->end < (value_ + p)) + continue; + + if (b->start < (value_ + p)) bp = value_ + p; + else bp = b->start; + + for (sp = s, bs = bp; *sp && *bp && bp < b->end; bp ++) { + if (*bp == '<') { + // skip to end of element... + while (*bp && bp < b->end && *bp != '>') bp ++; + continue; + } else if (*bp == '&') { + // decode HTML entity... + if ((c = quote_char(bp + 1)) < 0) c = '&'; + else bp = strchr(bp + 1, ';') + 1; + } else c = *bp; + + if (tolower(*sp) == tolower(c)) sp ++; + else { + // No match, so reset to start of search... + sp = s; + bs ++; + bp = bs; + } + } + + if (!*sp) { + // Found a match! + topline(b->y - b->h); + return (b->end - value_); + } + } + + // No match! + return (-1); +} + + +// +// 'Fl_Help_View::format()' - Format the help text. +// + +void +Fl_Help_View::format() +{ + int i; // Looping var + int done; // Are we done yet? + Fl_Help_Block *block, // Current block + *cell; // Current table cell + int cells[MAX_COLUMNS], + // Cells in the current row... + row; // Current table row (block number) + const char *ptr, // Pointer into block + *start, // Pointer to start of element + *attrs; // Pointer to start of element attributes + char *s, // Pointer into buffer + buf[1024], // Text buffer + attr[1024], // Attribute buffer + wattr[1024], // Width attribute buffer + hattr[1024], // Height attribute buffer + linkdest[1024]; // Link destination + int xx, yy, ww, hh; // Size of current text fragment + int line; // Current line in block + int links; // Links for current line + unsigned char font, fsize; // Current font and size + unsigned char border; // Draw border? + int talign, // Current alignment + newalign, // New alignment + head, // In the section? + pre, //
 text?
+		needspace;	// Do we need whitespace?
+  int		table_width,	// Width of table
+		table_offset;	// Offset of table
+  int		column,		// Current table column number
+		columns[MAX_COLUMNS];
+				// Column widths
+  Fl_Color	tc, rc;		// Table/row background color
+  Fl_Boxtype	b = box() ? box() : FL_DOWN_BOX;
+				// Box to draw...
+  fl_margins	margins;	// Left margin stack...
+
+
+  // Reset document width...
+  hsize_ = w() - Fl::scrollbar_size() - Fl::box_dw(b);
+
+  done = 0;
+  while (!done)
+  {
+    // Reset state variables...
+    done       = 1;
+    nblocks_   = 0;
+    nlinks_    = 0;
+    ntargets_  = 0;
+    size_      = 0;
+    bgcolor_   = color();
+    textcolor_ = textcolor();
+    linkcolor_ = fl_contrast(FL_BLUE, color());
+
+    tc = rc = bgcolor_;
+
+    strcpy(title_, "Untitled");
+
+    if (!value_)
+      return;
+
+    // Setup for formatting...
+    initfont(font, fsize);
+
+    line         = 0;
+    links        = 0;
+    xx           = margins.clear();
+    yy           = fsize + 2;
+    ww           = 0;
+    column       = 0;
+    border       = 0;
+    hh           = 0;
+    block        = add_block(value_, xx, yy, hsize_, 0);
+    row          = 0;
+    head         = 0;
+    pre          = 0;
+    talign       = LEFT;
+    newalign     = LEFT;
+    needspace    = 0;
+    linkdest[0]  = '\0';
+    table_offset = 0;
+
+    for (ptr = value_, s = buf; *ptr;)
+    {
+      if ((*ptr == '<' || isspace((*ptr)&255)) && s > buf)
+      {
+        // Get width...
+        *s = '\0';
+        ww = (int)fl_width(buf);
+
+	if (!head && !pre)
+	{
+          // Check width...
+          if (ww > hsize_) {
+	    hsize_ = ww;
+	    done   = 0;
+	    break;
+	  }
+
+          if (needspace && xx > block->x)
+	    ww += (int)fl_width(' ');
+
+  //        printf("line = %d, xx = %d, ww = %d, block->x = %d, block->w = %d\n",
+  //	       line, xx, ww, block->x, block->w);
+
+          if ((xx + ww) > block->w)
+	  {
+            line     = do_align(block, line, xx, newalign, links);
+	    xx       = block->x;
+	    yy       += hh;
+	    block->h += hh;
+	    hh       = 0;
+	  }
+
+          if (linkdest[0])
+	    add_link(linkdest, xx, yy - fsize, ww, fsize);
+
+	  xx += ww;
+	  if ((fsize + 2) > hh)
+	    hh = fsize + 2;
+
+	  needspace = 0;
+	}
+	else if (pre)
+	{
+          // Add a link as needed...
+          if (linkdest[0])
+	    add_link(linkdest, xx, yy - hh, ww, hh);
+
+	  xx += ww;
+	  if ((fsize + 2) > hh)
+	    hh = fsize + 2;
+
+          // Handle preformatted text...
+	  while (isspace((*ptr)&255))
+	  {
+	    if (*ptr == '\n')
+	    {
+              if (xx > hsize_) break;
+
+              line     = do_align(block, line, xx, newalign, links);
+              xx       = block->x;
+	      yy       += hh;
+	      block->h += hh;
+	      hh       = fsize + 2;
+	    }
+	    else
+              xx += (int)fl_width(' ');
+
+            if ((fsize + 2) > hh)
+	      hh = fsize + 2;
+
+            ptr ++;
+	  }
+
+          if (xx > hsize_) {
+	    hsize_ = xx;
+	    done   = 0;
+	    break;
+	  }
+
+	  needspace = 0;
+	}
+	else
+	{
+          // Handle normal text or stuff in the  section...
+	  while (isspace((*ptr)&255))
+            ptr ++;
+	}
+
+	s = buf;
+      }
+
+      if (*ptr == '<')
+      {
+	start = ptr;
+	ptr ++;
+
+        if (strncmp(ptr, "!--", 3) == 0)
+	{
+	  // Comment...
+	  ptr += 3;
+	  if ((ptr = strstr(ptr, "-->")) != NULL)
+	  {
+	    ptr += 3;
+	    continue;
+	  }
+	  else
+	    break;
+	}
+
+	while (*ptr && *ptr != '>' && !isspace((*ptr)&255))
+          if (s < (buf + sizeof(buf) - 1))
+            *s++ = *ptr++;
+	  else
+	    ptr ++;
+
+	*s = '\0';
+	s = buf;
+
+//        puts(buf);
+
+	attrs = ptr;
+	while (*ptr && *ptr != '>')
+          ptr ++;
+
+	if (*ptr == '>')
+          ptr ++;
+
+	if (strcasecmp(buf, "HEAD") == 0)
+          head = 1;
+	else if (strcasecmp(buf, "/HEAD") == 0)
+          head = 0;
+	else if (strcasecmp(buf, "TITLE") == 0)
+	{
+          // Copy the title in the document...
+          for (s = title_;
+	       *ptr != '<' && *ptr && s < (title_ + sizeof(title_) - 1);
+	       *s++ = *ptr++);
+
+	  *s = '\0';
+	  s = buf;
+	}
+	else if (strcasecmp(buf, "A") == 0)
+	{
+          if (get_attr(attrs, "NAME", attr, sizeof(attr)) != NULL)
+	    add_target(attr, yy - fsize - 2);
+
+	  if (get_attr(attrs, "HREF", attr, sizeof(attr)) != NULL)
+	    strlcpy(linkdest, attr, sizeof(linkdest));
+	}
+	else if (strcasecmp(buf, "/A") == 0)
+          linkdest[0] = '\0';
+	else if (strcasecmp(buf, "BODY") == 0)
+	{
+          bgcolor_   = get_color(get_attr(attrs, "BGCOLOR", attr, sizeof(attr)),
+	                	 color());
+          textcolor_ = get_color(get_attr(attrs, "TEXT", attr, sizeof(attr)),
+	                	 textcolor());
+          linkcolor_ = get_color(get_attr(attrs, "LINK", attr, sizeof(attr)),
+	                	 fl_contrast(FL_BLUE, color()));
+	}
+	else if (strcasecmp(buf, "BR") == 0)
+	{
+          line     = do_align(block, line, xx, newalign, links);
+          xx       = block->x;
+	  block->h += hh;
+          yy       += hh;
+	  hh       = 0;
+	}
+	else if (strcasecmp(buf, "CENTER") == 0 ||
+        	 strcasecmp(buf, "P") == 0 ||
+        	 strcasecmp(buf, "H1") == 0 ||
+		 strcasecmp(buf, "H2") == 0 ||
+		 strcasecmp(buf, "H3") == 0 ||
+		 strcasecmp(buf, "H4") == 0 ||
+		 strcasecmp(buf, "H5") == 0 ||
+		 strcasecmp(buf, "H6") == 0 ||
+		 strcasecmp(buf, "UL") == 0 ||
+		 strcasecmp(buf, "OL") == 0 ||
+		 strcasecmp(buf, "DL") == 0 ||
+		 strcasecmp(buf, "LI") == 0 ||
+		 strcasecmp(buf, "DD") == 0 ||
+		 strcasecmp(buf, "DT") == 0 ||
+		 strcasecmp(buf, "HR") == 0 ||
+		 strcasecmp(buf, "PRE") == 0 ||
+		 strcasecmp(buf, "TABLE") == 0)
+	{
+          block->end = start;
+          line       = do_align(block, line, xx, newalign, links);
+	  newalign   = strcasecmp(buf, "CENTER") ? LEFT : CENTER;
+          xx         = block->x;
+          block->h   += hh;
+
+          if (strcasecmp(buf, "UL") == 0 ||
+	      strcasecmp(buf, "OL") == 0 ||
+	      strcasecmp(buf, "DL") == 0)
+          {
+	    block->h += fsize + 2;
+	    xx       = margins.push(4 * fsize);
+	  }
+          else if (strcasecmp(buf, "TABLE") == 0)
+	  {
+	    if (get_attr(attrs, "BORDER", attr, sizeof(attr)))
+	      border = (uchar)atoi(attr);
+	    else
+	      border = 0;
+
+            tc = rc = get_color(get_attr(attrs, "BGCOLOR", attr, sizeof(attr)), bgcolor_);
+
+	    block->h += fsize + 2;
+
+            format_table(&table_width, columns, start);
+
+            if ((xx + table_width) > hsize_) {
+#ifdef DEBUG
+              printf("xx=%d, table_width=%d, hsize_=%d\n", xx, table_width,
+	             hsize_);
+#endif // DEBUG
+	      hsize_ = xx + table_width;
+	      done   = 0;
+	      break;
+	    }
+
+            switch (get_align(attrs, talign))
+	    {
+	      default :
+	          table_offset = 0;
+	          break;
+
+	      case CENTER :
+	          table_offset = (hsize_ - table_width) / 2 - textsize_;
+	          break;
+
+	      case RIGHT :
+	          table_offset = hsize_ - table_width - textsize_;
+	          break;
+	    }
+
+	    column = 0;
+	  }
+
+          if (tolower(buf[0]) == 'h' && isdigit(buf[1]))
+	  {
+	    font  = FL_HELVETICA_BOLD;
+	    fsize = (uchar)(textsize_ + '7' - buf[1]);
+	  }
+	  else if (strcasecmp(buf, "DT") == 0)
+	  {
+	    font  = (uchar)(textfont_ | FL_ITALIC);
+	    fsize = textsize_;
+	  }
+	  else if (strcasecmp(buf, "PRE") == 0)
+	  {
+	    font  = FL_COURIER;
+	    fsize = textsize_;
+	    pre   = 1;
+	  }
+	  else
+	  {
+	    font  = textfont_;
+	    fsize = textsize_;
+	  }
+
+	  pushfont(font, fsize);
+
+          yy = block->y + block->h;
+          hh = 0;
+
+          if ((tolower(buf[0]) == 'h' && isdigit(buf[1])) ||
+	      strcasecmp(buf, "DD") == 0 ||
+	      strcasecmp(buf, "DT") == 0 ||
+	      strcasecmp(buf, "P") == 0)
+            yy += fsize + 2;
+	  else if (strcasecmp(buf, "HR") == 0)
+	  {
+	    hh += 2 * fsize;
+	    yy += fsize;
+	  }
+
+          if (row)
+	    block = add_block(start, xx, yy, block->w, 0);
+	  else
+	    block = add_block(start, xx, yy, hsize_, 0);
+
+	  needspace = 0;
+	  line      = 0;
+
+	  if (strcasecmp(buf, "CENTER") == 0)
+	    newalign = talign = CENTER;
+	  else
+	    newalign = get_align(attrs, talign);
+	}
+	else if (strcasecmp(buf, "/CENTER") == 0 ||
+		 strcasecmp(buf, "/P") == 0 ||
+		 strcasecmp(buf, "/H1") == 0 ||
+		 strcasecmp(buf, "/H2") == 0 ||
+		 strcasecmp(buf, "/H3") == 0 ||
+		 strcasecmp(buf, "/H4") == 0 ||
+		 strcasecmp(buf, "/H5") == 0 ||
+		 strcasecmp(buf, "/H6") == 0 ||
+		 strcasecmp(buf, "/PRE") == 0 ||
+		 strcasecmp(buf, "/UL") == 0 ||
+		 strcasecmp(buf, "/OL") == 0 ||
+		 strcasecmp(buf, "/DL") == 0 ||
+		 strcasecmp(buf, "/TABLE") == 0)
+	{
+          line       = do_align(block, line, xx, newalign, links);
+          xx         = block->x;
+          block->end = ptr;
+
+          if (strcasecmp(buf, "/UL") == 0 ||
+	      strcasecmp(buf, "/OL") == 0 ||
+	      strcasecmp(buf, "/DL") == 0)
+	  {
+	    xx       = margins.pop();
+	    block->h += fsize + 2;
+	  }
+          else if (strcasecmp(buf, "/TABLE") == 0) 
+          {
+	    block->h += fsize + 2;
+            xx       = margins.current();
+          }
+	  else if (strcasecmp(buf, "/PRE") == 0)
+	  {
+	    pre = 0;
+	    hh  = 0;
+	  }
+	  else if (strcasecmp(buf, "/CENTER") == 0)
+	    talign = LEFT;
+
+          popfont(font, fsize);
+
+          while (isspace((*ptr)&255))
+	    ptr ++;
+
+          block->h += hh;
+          yy       += hh;
+
+          if (tolower(buf[2]) == 'l')
+            yy += fsize + 2;
+
+          if (row)
+	    block = add_block(ptr, xx, yy, block->w, 0);
+	  else
+	    block = add_block(ptr, xx, yy, hsize_, 0);
+
+	  needspace = 0;
+	  hh        = 0;
+	  line      = 0;
+	  newalign  = talign;
+	}
+	else if (strcasecmp(buf, "TR") == 0)
+	{
+          block->end = start;
+          line       = do_align(block, line, xx, newalign, links);
+          xx         = block->x;
+          block->h   += hh;
+
+          if (row)
+	  {
+            yy = blocks_[row].y + blocks_[row].h;
+
+	    for (cell = blocks_ + row + 1; cell <= block; cell ++)
+	      if ((cell->y + cell->h) > yy)
+		yy = cell->y + cell->h;
+
+            block = blocks_ + row;
+
+            block->h = yy - block->y + 2;
+
+	    for (i = 0; i < column; i ++)
+	      if (cells[i])
+	      {
+		cell = blocks_ + cells[i];
+		cell->h = block->h;
+	      }
+	  }
+
+          memset(cells, 0, sizeof(cells));
+
+	  yy        = block->y + block->h - 4;
+	  hh        = 0;
+          block     = add_block(start, xx, yy, hsize_, 0);
+	  row       = block - blocks_;
+	  needspace = 0;
+	  column    = 0;
+	  line      = 0;
+
+          rc = get_color(get_attr(attrs, "BGCOLOR", attr, sizeof(attr)), tc);
+	}
+	else if (strcasecmp(buf, "/TR") == 0 && row)
+	{
+          line       = do_align(block, line, xx, newalign, links);
+          block->end = start;
+	  block->h   += hh;
+	  talign     = LEFT;
+
+          xx = blocks_[row].x;
+          yy = blocks_[row].y + blocks_[row].h;
+
+	  for (cell = blocks_ + row + 1; cell <= block; cell ++)
+	    if ((cell->y + cell->h) > yy)
+	      yy = cell->y + cell->h;
+
+          block = blocks_ + row;
+
+          block->h = yy - block->y + 2;
+
+	  for (i = 0; i < column; i ++)
+	    if (cells[i])
+	    {
+	      cell = blocks_ + cells[i];
+	      cell->h = block->h;
+	    }
+
+	  yy        = block->y + block->h /*- 4*/;
+          block     = add_block(start, xx, yy, hsize_, 0);
+	  needspace = 0;
+	  row       = 0;
+	  line      = 0;
+	}
+	else if ((strcasecmp(buf, "TD") == 0 ||
+                  strcasecmp(buf, "TH") == 0) && row)
+	{
+          int	colspan;		// COLSPAN attribute
+
+
+          line       = do_align(block, line, xx, newalign, links);
+          block->end = start;
+	  block->h   += hh;
+
+          if (strcasecmp(buf, "TH") == 0)
+	    font = (uchar)(textfont_ | FL_BOLD);
+	  else
+	    font = textfont_;
+
+          fsize = textsize_;
+
+          xx = blocks_[row].x + fsize + 3 + table_offset;
+	  for (i = 0; i < column; i ++)
+	    xx += columns[i] + 6;
+
+          margins.push(xx - margins.current());
+
+          if (get_attr(attrs, "COLSPAN", attr, sizeof(attr)) != NULL)
+	    colspan = atoi(attr);
+	  else
+	    colspan = 1;
+
+          for (i = 0, ww = -6; i < colspan; i ++)
+	    ww += columns[column + i] + 6;
+
+          if (block->end == block->start && nblocks_ > 1)
+	  {
+	    nblocks_ --;
+	    block --;
+	  }
+
+	  pushfont(font, fsize);
+
+	  yy        = blocks_[row].y;
+	  hh        = 0;
+          block     = add_block(start, xx, yy, xx + ww, 0, border);
+	  needspace = 0;
+	  line      = 0;
+	  newalign  = get_align(attrs, tolower(buf[1]) == 'h' ? CENTER : LEFT);
+	  talign    = newalign;
+
+          cells[column] = block - blocks_;
+
+	  column += colspan;
+
+          block->bgcolor = get_color(get_attr(attrs, "BGCOLOR", attr,
+	                                      sizeof(attr)), rc);
+	}
+	else if ((strcasecmp(buf, "/TD") == 0 ||
+                  strcasecmp(buf, "/TH") == 0) && row)
+	{
+          line = do_align(block, line, xx, newalign, links);
+          popfont(font, fsize);
+	  xx = margins.pop();
+	  talign = LEFT;
+	}
+	else if (strcasecmp(buf, "FONT") == 0)
+	{
+          if (get_attr(attrs, "FACE", attr, sizeof(attr)) != NULL) {
+	    if (!strncasecmp(attr, "helvetica", 9) ||
+	        !strncasecmp(attr, "arial", 5) ||
+		!strncasecmp(attr, "sans", 4)) font = FL_HELVETICA;
+            else if (!strncasecmp(attr, "times", 5) ||
+	             !strncasecmp(attr, "serif", 5)) font = FL_TIMES;
+            else if (!strncasecmp(attr, "symbol", 6)) font = FL_SYMBOL;
+	    else font = FL_COURIER;
+          }
+
+          if (get_attr(attrs, "SIZE", attr, sizeof(attr)) != NULL) {
+            if (isdigit(attr[0] & 255)) {
+	      // Absolute size
+	      fsize = (int)(textsize_ * pow(1.2, atoi(attr) - 3.0));
+	    } else {
+	      // Relative size
+	      fsize = (int)(fsize * pow(1.2, atoi(attr)));
+	    }
+	  }
+
+          pushfont(font, fsize);
+	}
+	else if (strcasecmp(buf, "/FONT") == 0)
+	  popfont(font, fsize);
+	else if (strcasecmp(buf, "B") == 0 ||
+        	 strcasecmp(buf, "STRONG") == 0)
+	  pushfont(font |= FL_BOLD, fsize);
+	else if (strcasecmp(buf, "I") == 0 ||
+        	 strcasecmp(buf, "EM") == 0)
+	  pushfont(font |= FL_ITALIC, fsize);
+	else if (strcasecmp(buf, "CODE") == 0 ||
+	         strcasecmp(buf, "TT") == 0)
+	  pushfont(font = FL_COURIER, fsize);
+	else if (strcasecmp(buf, "KBD") == 0)
+	  pushfont(font = FL_COURIER_BOLD, fsize);
+	else if (strcasecmp(buf, "VAR") == 0)
+	  pushfont(font = FL_COURIER_ITALIC, fsize);
+	else if (strcasecmp(buf, "/B") == 0 ||
+		 strcasecmp(buf, "/STRONG") == 0 ||
+		 strcasecmp(buf, "/I") == 0 ||
+		 strcasecmp(buf, "/EM") == 0 ||
+		 strcasecmp(buf, "/CODE") == 0 ||
+		 strcasecmp(buf, "/TT") == 0 ||
+		 strcasecmp(buf, "/KBD") == 0 ||
+		 strcasecmp(buf, "/VAR") == 0)
+	  popfont(font, fsize);
+	else if (strcasecmp(buf, "IMG") == 0)
+	{
+	  Fl_Shared_Image	*img = 0;
+	  int		width;
+	  int		height;
+
+
+          get_attr(attrs, "WIDTH", wattr, sizeof(wattr));
+          get_attr(attrs, "HEIGHT", hattr, sizeof(hattr));
+	  width  = get_length(wattr);
+	  height = get_length(hattr);
+
+	  if (get_attr(attrs, "SRC", attr, sizeof(attr))) {
+	    img    = get_image(attr, width, height);
+	    width  = img->w();
+	    height = img->h();
+	  }
+
+	  ww = width;
+
+          if (ww > hsize_) {
+	    hsize_ = ww;
+	    done   = 0;
+	    break;
+	  }
+
+	  if (needspace && xx > block->x)
+	    ww += (int)fl_width(' ');
+
+	  if ((xx + ww) > block->w)
+	  {
+	    line     = do_align(block, line, xx, newalign, links);
+	    xx       = block->x;
+	    yy       += hh;
+	    block->h += hh;
+	    hh       = 0;
+	  }
+
+	  if (linkdest[0])
+	    add_link(linkdest, xx, yy - height, ww, height);
+
+	  xx += ww;
+	  if ((height + 2) > hh)
+	    hh = height + 2;
+
+	  needspace = 0;
+	}
+      }
+      else if (*ptr == '\n' && pre)
+      {
+	if (linkdest[0])
+	  add_link(linkdest, xx, yy - hh, ww, hh);
+
+        if (xx > hsize_) {
+	  hsize_ = xx;
+          done   = 0;
+	  break;
+	}
+
+	line      = do_align(block, line, xx, newalign, links);
+	xx        = block->x;
+	yy        += hh;
+	block->h  += hh;
+	needspace = 0;
+	ptr ++;
+      }
+      else if (isspace((*ptr)&255))
+      {
+	needspace = 1;
+
+	ptr ++;
+      }
+      else if (*ptr == '&' && s < (buf + sizeof(buf) - 1))
+      {
+	ptr ++;
+
+        int qch = quote_char(ptr);
+
+	if (qch < 0)
+	  *s++ = '&';
+	else {
+	  *s++ = qch;
+	  ptr = strchr(ptr, ';') + 1;
+	}
+
+	if ((fsize + 2) > hh)
+          hh = fsize + 2;
+      }
+      else
+      {
+	if (s < (buf + sizeof(buf) - 1))
+          *s++ = *ptr++;
+	else
+          ptr ++;
+
+	if ((fsize + 2) > hh)
+          hh = fsize + 2;
+      }
+    }
+
+    if (s > buf && !head)
+    {
+      *s = '\0';
+      ww = (int)fl_width(buf);
+
+  //    printf("line = %d, xx = %d, ww = %d, block->x = %d, block->w = %d\n",
+  //	   line, xx, ww, block->x, block->w);
+
+      if (ww > hsize_) {
+	hsize_ = ww;
+	done   = 0;
+	break;
+      }
+
+      if (needspace && xx > block->x)
+	ww += (int)fl_width(' ');
+
+      if ((xx + ww) > block->w)
+      {
+	line     = do_align(block, line, xx, newalign, links);
+	xx       = block->x;
+	yy       += hh;
+	block->h += hh;
+	hh       = 0;
+      }
+
+      if (linkdest[0])
+	add_link(linkdest, xx, yy - fsize, ww, fsize);
+
+      xx += ww;
+    }
+
+    do_align(block, line, xx, newalign, links);
+
+    block->end = ptr;
+    size_      = yy + hh;
+  }
+
+//  printf("margins.depth_=%d\n", margins.depth_);
+
+  if (ntargets_ > 1)
+    qsort(targets_, ntargets_, sizeof(Fl_Help_Target),
+          (compare_func_t)compare_targets);
+
+  int dx = Fl::box_dw(b) - Fl::box_dx(b);
+  int dy = Fl::box_dh(b) - Fl::box_dy(b);
+  int ss = Fl::scrollbar_size();
+  int dw = Fl::box_dw(b) + ss;
+  int dh = Fl::box_dh(b);
+
+  if (hsize_ > (w() - dw)) {
+    hscrollbar_.show();
+
+    dh += ss;
+
+    if (size_ < (h() - dh)) {
+      scrollbar_.hide();
+      hscrollbar_.resize(x() + Fl::box_dx(b), y() + h() - ss - dy,
+                         w() - Fl::box_dw(b), ss);
+    } else {
+      scrollbar_.show();
+      scrollbar_.resize(x() + w() - ss - dx, y() + Fl::box_dy(b),
+                        ss, h() - ss - Fl::box_dh(b));
+      hscrollbar_.resize(x() + Fl::box_dx(b), y() + h() - ss - dy,
+                         w() - ss - Fl::box_dw(b), ss);
+    }
+  } else {
+    hscrollbar_.hide();
+
+    if (size_ < (h() - dh)) scrollbar_.hide();
+    else {
+      scrollbar_.resize(x() + w() - ss - dx, y() + Fl::box_dy(b),
+                        ss, h() - Fl::box_dh(b));
+      scrollbar_.show();
+    }
+  }
+
+  // Reset scrolling if it needs to be...
+  if (scrollbar_.visible()) {
+    int temph = h() - Fl::box_dh(b);
+    if (hscrollbar_.visible()) temph -= ss;
+    if ((topline_ + temph) > size_) topline(size_ - temph);
+    else topline(topline_);
+  } else topline(0);
+
+  if (hscrollbar_.visible()) {
+    int tempw = w() - ss - Fl::box_dw(b);
+    if ((leftline_ + tempw) > hsize_) leftline(hsize_ - tempw);
+    else leftline(leftline_);
+  } else leftline(0);
+}
+
+
+//
+// 'Fl_Help_View::format_table()' - Format a table...
+//
+
+void
+Fl_Help_View::format_table(int        *table_width,	// O - Total table width
+                           int        *columns,		// O - Column widths
+	                   const char *table)		// I - Pointer to start of table
+{
+  int		column,					// Current column
+		num_columns,				// Number of columns
+		colspan,				// COLSPAN attribute
+		width,					// Current width
+		temp_width,				// Temporary width
+		max_width,				// Maximum width
+		incell,					// In a table cell?
+		pre,					// 
 text?
+		needspace;				// Need whitespace?
+  char		*s,					// Pointer into buffer
+		buf[1024],				// Text buffer
+		attr[1024],				// Other attribute
+		wattr[1024],				// WIDTH attribute
+		hattr[1024];				// HEIGHT attribute
+  const char	*ptr,					// Pointer into table
+		*attrs,					// Pointer to attributes
+		*start;					// Start of element
+  int		minwidths[MAX_COLUMNS];			// Minimum widths for each column
+  unsigned char	font, fsize;				// Current font and size
+
+
+  // Clear widths...
+  *table_width = 0;
+  for (column = 0; column < MAX_COLUMNS; column ++)
+  {
+    columns[column]   = 0;
+    minwidths[column] = 0;
+  }
+
+  num_columns = 0;
+  colspan     = 0;
+  max_width   = 0;
+  pre         = 0;
+  needspace   = 0;
+  font        = fonts_[nfonts_][0];
+  fsize       = fonts_[nfonts_][1];
+
+  // Scan the table...
+  for (ptr = table, column = -1, width = 0, s = buf, incell = 0; *ptr;)
+  {
+    if ((*ptr == '<' || isspace((*ptr)&255)) && s > buf && incell)
+    {
+      // Check width...
+      if (needspace)
+      {
+        *s++      = ' ';
+	needspace = 0;
+      }
+
+      *s         = '\0';
+      temp_width = (int)fl_width(buf);
+      s          = buf;
+
+      if (temp_width > minwidths[column])
+        minwidths[column] = temp_width;
+
+      width += temp_width;
+
+      if (width > max_width)
+        max_width = width;
+    }
+
+    if (*ptr == '<')
+    {
+      start = ptr;
+
+      for (s = buf, ptr ++; *ptr && *ptr != '>' && !isspace((*ptr)&255);)
+        if (s < (buf + sizeof(buf) - 1))
+          *s++ = *ptr++;
+	else
+	  ptr ++;
+
+      *s = '\0';
+      s = buf;
+
+      attrs = ptr;
+      while (*ptr && *ptr != '>')
+        ptr ++;
+
+      if (*ptr == '>')
+        ptr ++;
+
+      if (strcasecmp(buf, "BR") == 0 ||
+	  strcasecmp(buf, "HR") == 0)
+      {
+        width     = 0;
+	needspace = 0;
+      }
+      else if (strcasecmp(buf, "TABLE") == 0 && start > table)
+        break;
+      else if (strcasecmp(buf, "CENTER") == 0 ||
+               strcasecmp(buf, "P") == 0 ||
+               strcasecmp(buf, "H1") == 0 ||
+	       strcasecmp(buf, "H2") == 0 ||
+	       strcasecmp(buf, "H3") == 0 ||
+	       strcasecmp(buf, "H4") == 0 ||
+	       strcasecmp(buf, "H5") == 0 ||
+	       strcasecmp(buf, "H6") == 0 ||
+	       strcasecmp(buf, "UL") == 0 ||
+	       strcasecmp(buf, "OL") == 0 ||
+	       strcasecmp(buf, "DL") == 0 ||
+	       strcasecmp(buf, "LI") == 0 ||
+	       strcasecmp(buf, "DD") == 0 ||
+	       strcasecmp(buf, "DT") == 0 ||
+	       strcasecmp(buf, "PRE") == 0)
+      {
+        width     = 0;
+	needspace = 0;
+
+        if (tolower(buf[0]) == 'h' && isdigit(buf[1]))
+	{
+	  font  = FL_HELVETICA_BOLD;
+	  fsize = (uchar)(textsize_ + '7' - buf[1]);
+	}
+	else if (strcasecmp(buf, "DT") == 0)
+	{
+	  font  = (uchar)(textfont_ | FL_ITALIC);
+	  fsize = textsize_;
+	}
+	else if (strcasecmp(buf, "PRE") == 0)
+	{
+	  font  = FL_COURIER;
+	  fsize = textsize_;
+	  pre   = 1;
+	}
+	else if (strcasecmp(buf, "LI") == 0)
+	{
+	  width  += 4 * fsize;
+	  font   = textfont_;
+	  fsize  = textsize_;
+	}
+	else
+	{
+	  font  = textfont_;
+	  fsize = textsize_;
+	}
+
+	pushfont(font, fsize);
+      }
+      else if (strcasecmp(buf, "/CENTER") == 0 ||
+	       strcasecmp(buf, "/P") == 0 ||
+	       strcasecmp(buf, "/H1") == 0 ||
+	       strcasecmp(buf, "/H2") == 0 ||
+	       strcasecmp(buf, "/H3") == 0 ||
+	       strcasecmp(buf, "/H4") == 0 ||
+	       strcasecmp(buf, "/H5") == 0 ||
+	       strcasecmp(buf, "/H6") == 0 ||
+	       strcasecmp(buf, "/PRE") == 0 ||
+	       strcasecmp(buf, "/UL") == 0 ||
+	       strcasecmp(buf, "/OL") == 0 ||
+	       strcasecmp(buf, "/DL") == 0)
+      {
+        width     = 0;
+	needspace = 0;
+
+        popfont(font, fsize);
+      }
+      else if (strcasecmp(buf, "TR") == 0 || strcasecmp(buf, "/TR") == 0 ||
+               strcasecmp(buf, "/TABLE") == 0)
+      {
+//        printf("%s column = %d, colspan = %d, num_columns = %d\n",
+//	       buf, column, colspan, num_columns);
+
+        if (column >= 0)
+	{
+	  // This is a hack to support COLSPAN...
+	  max_width /= colspan;
+
+	  while (colspan > 0)
+	  {
+	    if (max_width > columns[column])
+	      columns[column] = max_width;
+
+	    column ++;
+	    colspan --;
+	  }
+	}
+
+	if (strcasecmp(buf, "/TABLE") == 0)
+	  break;
+
+	needspace = 0;
+	column    = -1;
+	width     = 0;
+	max_width = 0;
+	incell    = 0;
+      }
+      else if (strcasecmp(buf, "TD") == 0 ||
+               strcasecmp(buf, "TH") == 0)
+      {
+//        printf("BEFORE column = %d, colspan = %d, num_columns = %d\n",
+//	       column, colspan, num_columns);
+
+        if (column >= 0)
+	{
+	  // This is a hack to support COLSPAN...
+	  max_width /= colspan;
+
+	  while (colspan > 0)
+	  {
+	    if (max_width > columns[column])
+	      columns[column] = max_width;
+
+	    column ++;
+	    colspan --;
+	  }
+	}
+	else
+	  column ++;
+
+        if (get_attr(attrs, "COLSPAN", attr, sizeof(attr)) != NULL)
+	  colspan = atoi(attr);
+	else
+	  colspan = 1;
+
+//        printf("AFTER column = %d, colspan = %d, num_columns = %d\n",
+//	       column, colspan, num_columns);
+
+        if ((column + colspan) >= num_columns)
+	  num_columns = column + colspan;
+
+	needspace = 0;
+	width     = 0;
+	incell    = 1;
+
+        if (strcasecmp(buf, "TH") == 0)
+	  font = (uchar)(textfont_ | FL_BOLD);
+	else
+	  font = textfont_;
+
+        fsize = textsize_;
+
+	pushfont(font, fsize);
+
+        if (get_attr(attrs, "WIDTH", attr, sizeof(attr)) != NULL)
+	  max_width = get_length(attr);
+	else
+	  max_width = 0;
+
+//        printf("max_width = %d\n", max_width);
+      }
+      else if (strcasecmp(buf, "/TD") == 0 ||
+               strcasecmp(buf, "/TH") == 0)
+      {
+	incell = 0;
+        popfont(font, fsize);
+      }
+      else if (strcasecmp(buf, "B") == 0 ||
+               strcasecmp(buf, "STRONG") == 0)
+	pushfont(font |= FL_BOLD, fsize);
+      else if (strcasecmp(buf, "I") == 0 ||
+               strcasecmp(buf, "EM") == 0)
+	pushfont(font |= FL_ITALIC, fsize);
+      else if (strcasecmp(buf, "CODE") == 0 ||
+               strcasecmp(buf, "TT") == 0)
+	pushfont(font = FL_COURIER, fsize);
+      else if (strcasecmp(buf, "KBD") == 0)
+	pushfont(font = FL_COURIER_BOLD, fsize);
+      else if (strcasecmp(buf, "VAR") == 0)
+	pushfont(font = FL_COURIER_ITALIC, fsize);
+      else if (strcasecmp(buf, "/B") == 0 ||
+	       strcasecmp(buf, "/STRONG") == 0 ||
+	       strcasecmp(buf, "/I") == 0 ||
+	       strcasecmp(buf, "/EM") == 0 ||
+	       strcasecmp(buf, "/CODE") == 0 ||
+	       strcasecmp(buf, "/TT") == 0 ||
+	       strcasecmp(buf, "/KBD") == 0 ||
+	       strcasecmp(buf, "/VAR") == 0)
+	popfont(font, fsize);
+      else if (strcasecmp(buf, "IMG") == 0 && incell)
+      {
+	Fl_Shared_Image	*img = 0;
+	int		iwidth, iheight;
+
+
+        get_attr(attrs, "WIDTH", wattr, sizeof(wattr));
+        get_attr(attrs, "HEIGHT", hattr, sizeof(hattr));
+	iwidth  = get_length(wattr);
+	iheight = get_length(hattr);
+
+        if (get_attr(attrs, "SRC", attr, sizeof(attr))) {
+	  img     = get_image(attr, iwidth, iheight);
+	  iwidth  = img->w();
+	  iheight = img->h();
+	}
+
+	if (iwidth > minwidths[column])
+          minwidths[column] = iwidth;
+
+        width += iwidth;
+	if (needspace)
+	  width += (int)fl_width(' ');
+
+	if (width > max_width)
+          max_width = width;
+
+	needspace = 0;
+      }
+    }
+    else if (*ptr == '\n' && pre)
+    {
+      width     = 0;
+      needspace = 0;
+      ptr ++;
+    }
+    else if (isspace((*ptr)&255))
+    {
+      needspace = 1;
+
+      ptr ++;
+    }
+    else if (*ptr == '&' && s < (buf + sizeof(buf) - 1))
+    {
+      ptr ++;
+
+      int qch = quote_char(ptr);
+
+      if (qch < 0)
+	*s++ = '&';
+      else {
+	*s++ = qch;
+	ptr = strchr(ptr, ';') + 1;
+      }
+    }
+    else
+    {
+      if (s < (buf + sizeof(buf) - 1))
+        *s++ = *ptr++;
+      else
+        ptr ++;
+    }
+  }
+
+  // Now that we have scanned the entire table, adjust the table and
+  // cell widths to fit on the screen...
+  if (get_attr(table + 6, "WIDTH", attr, sizeof(attr)))
+    *table_width = get_length(attr);
+  else
+    *table_width = 0;
+
+#ifdef DEBUG
+  printf("num_columns = %d, table_width = %d\n", num_columns, *table_width);
+#endif // DEBUG
+
+  if (num_columns == 0)
+    return;
+
+  // Add up the widths...
+  for (column = 0, width = 0; column < num_columns; column ++)
+    width += columns[column];
+
+#ifdef DEBUG
+  printf("width = %d, w() = %d\n", width, w());
+  for (column = 0; column < num_columns; column ++)
+    printf("    columns[%d] = %d, minwidths[%d] = %d\n", column, columns[column],
+           column, minwidths[column]);
+#endif // DEBUG
+
+  // Adjust the width if needed...
+  int scale_width = *table_width;
+
+  if (scale_width == 0) {
+    if (width > (hsize_ - Fl::scrollbar_size())) scale_width = hsize_ - Fl::scrollbar_size();
+    else scale_width = width;
+  }
+
+  if (width < scale_width) {
+#ifdef DEBUG
+    printf("Scaling table up to %d from %d...\n", scale_width, width);
+#endif // DEBUG
+
+    *table_width = 0;
+
+    scale_width = (scale_width - width) / num_columns;
+
+#ifdef DEBUG
+    printf("adjusted scale_width = %d\n", scale_width);
+#endif // DEBUG
+
+    for (column = 0; column < num_columns; column ++) {
+      columns[column] += scale_width;
+
+      (*table_width) += columns[column];
+    }
+  }
+  else if (width > scale_width) {
+#ifdef DEBUG
+    printf("Scaling table down to %d from %d...\n", scale_width, width);
+#endif // DEBUG
+
+    for (column = 0; column < num_columns; column ++) {
+      width       -= minwidths[column];
+      scale_width -= minwidths[column];
+    }
+
+#ifdef DEBUG
+    printf("adjusted width = %d, scale_width = %d\n", width, scale_width);
+#endif // DEBUG
+
+    if (width > 0) {
+      for (column = 0; column < num_columns; column ++) {
+	columns[column] -= minwidths[column];
+	columns[column] = scale_width * columns[column] / width;
+	columns[column] += minwidths[column];
+      }
+    }
+
+    *table_width = 0;
+    for (column = 0; column < num_columns; column ++) {
+      (*table_width) += columns[column];
+    }
+  }
+  else if (*table_width == 0)
+    *table_width = width;
+
+#ifdef DEBUG
+  printf("FINAL table_width = %d\n", *table_width);
+  for (column = 0; column < num_columns; column ++)
+    printf("    columns[%d] = %d\n", column, columns[column]);
+#endif // DEBUG
+}
+
+
+//
+// 'Fl_Help_View::free_data()' - Free memory used for the document.
+//
+
+void
+Fl_Help_View::free_data() {
+  // Releae all images...
+  if (value_) {
+    const char	*ptr,		// Pointer into block
+		*attrs;		// Pointer to start of element attributes
+    char	*s,		// Pointer into buffer
+		buf[1024],	// Text buffer
+		attr[1024],	// Attribute buffer
+		wattr[1024],	// Width attribute buffer
+		hattr[1024];	// Height attribute buffer
+
+
+    for (ptr = value_; *ptr;)
+    {
+      if (*ptr == '<')
+      {
+	ptr ++;
+
+        if (strncmp(ptr, "!--", 3) == 0)
+	{
+	  // Comment...
+	  ptr += 3;
+	  if ((ptr = strstr(ptr, "-->")) != NULL)
+	  {
+	    ptr += 3;
+	    continue;
+	  }
+	  else
+	    break;
+	}
+
+        s = buf;
+
+	while (*ptr && *ptr != '>' && !isspace((*ptr)&255))
+          if (s < (buf + sizeof(buf) - 1))
+            *s++ = *ptr++;
+	  else
+	    ptr ++;
+
+	*s = '\0';
+
+	attrs = ptr;
+	while (*ptr && *ptr != '>')
+          ptr ++;
+
+	if (*ptr == '>')
+          ptr ++;
+
+	if (strcasecmp(buf, "IMG") == 0)
+	{
+	  Fl_Shared_Image	*img;
+	  int		width;
+	  int		height;
+
+
+          get_attr(attrs, "WIDTH", wattr, sizeof(wattr));
+          get_attr(attrs, "HEIGHT", hattr, sizeof(hattr));
+	  width  = get_length(wattr);
+	  height = get_length(hattr);
+
+	  if (get_attr(attrs, "SRC", attr, sizeof(attr))) {
+	    // Release the image twice to free it from memory...
+	    img = get_image(attr, width, height);
+	    img->release();
+	    img->release();
+	  }
+	}
+      }
+      else
+        ptr ++;
+    }
+
+    free((void *)value_);
+    value_ = 0;
+  }
+
+  // Free all of the arrays...
+  if (nblocks_) {
+    free(blocks_);
+
+    ablocks_ = 0;
+    nblocks_ = 0;
+    blocks_  = 0;
+  }
+
+  if (nlinks_) {
+    free(links_);
+
+    alinks_ = 0;
+    nlinks_ = 0;
+    links_  = 0;
+  }
+
+  if (ntargets_) {
+    free(targets_);
+
+    atargets_ = 0;
+    ntargets_ = 0;
+    targets_  = 0;
+  }
+}
+
+//
+// 'Fl_Help_View::get_align()' - Get an alignment attribute.
+//
+
+int					// O - Alignment
+Fl_Help_View::get_align(const char *p,	// I - Pointer to start of attrs
+                        int        a)	// I - Default alignment
+{
+  char	buf[255];			// Alignment value
+
+
+  if (get_attr(p, "ALIGN", buf, sizeof(buf)) == NULL)
+    return (a);
+
+  if (strcasecmp(buf, "CENTER") == 0)
+    return (CENTER);
+  else if (strcasecmp(buf, "RIGHT") == 0)
+    return (RIGHT);
+  else
+    return (LEFT);
+}
+
+
+//
+// 'Fl_Help_View::get_attr()' - Get an attribute value from the string.
+//
+
+const char *					// O - Pointer to buf or NULL
+Fl_Help_View::get_attr(const char *p,		// I - Pointer to start of attributes
+                      const char *n,		// I - Name of attribute
+		      char       *buf,		// O - Buffer for attribute value
+		      int        bufsize)	// I - Size of buffer
+{
+  char	name[255],				// Name from string
+	*ptr,					// Pointer into name or value
+	quote;					// Quote
+
+
+  buf[0] = '\0';
+
+  while (*p && *p != '>')
+  {
+    while (isspace((*p)&255))
+      p ++;
+
+    if (*p == '>' || !*p)
+      return (NULL);
+
+    for (ptr = name; *p && !isspace((*p)&255) && *p != '=' && *p != '>';)
+      if (ptr < (name + sizeof(name) - 1))
+        *ptr++ = *p++;
+      else
+        p ++;
+
+    *ptr = '\0';
+
+    if (isspace((*p)&255) || !*p || *p == '>')
+      buf[0] = '\0';
+    else
+    {
+      if (*p == '=')
+        p ++;
+
+      for (ptr = buf; *p && !isspace((*p)&255) && *p != '>';)
+        if (*p == '\'' || *p == '\"')
+	{
+	  quote = *p++;
+
+	  while (*p && *p != quote)
+	    if ((ptr - buf + 1) < bufsize)
+	      *ptr++ = *p++;
+	    else
+	      p ++;
+
+          if (*p == quote)
+	    p ++;
+	}
+	else if ((ptr - buf + 1) < bufsize)
+	  *ptr++ = *p++;
+	else
+	  p ++;
+
+      *ptr = '\0';
+    }
+
+    if (strcasecmp(n, name) == 0)
+      return (buf);
+    else
+      buf[0] = '\0';
+
+    if (*p == '>')
+      return (NULL);
+  }
+
+  return (NULL);
+}
+
+
+//
+// 'Fl_Help_View::get_color()' - Get an alignment attribute.
+//
+
+Fl_Color				// O - Color value
+Fl_Help_View::get_color(const char *n,	// I - Color name
+                        Fl_Color   c)	// I - Default color value
+{
+  int	i;				// Looping var
+  int	rgb, r, g, b;			// RGB values
+  static const struct {			// Color name table
+    const char *name;
+    int r, g, b;
+  }	colors[] = {
+    { "black",		0x00, 0x00, 0x00 },
+    { "red",		0xff, 0x00, 0x00 },
+    { "green",		0x00, 0x80, 0x00 },
+    { "yellow",		0xff, 0xff, 0x00 },
+    { "blue",		0x00, 0x00, 0xff },
+    { "magenta",	0xff, 0x00, 0xff },
+    { "fuchsia",	0xff, 0x00, 0xff },
+    { "cyan",		0x00, 0xff, 0xff },
+    { "aqua",		0x00, 0xff, 0xff },
+    { "white",		0xff, 0xff, 0xff },
+    { "gray",		0x80, 0x80, 0x80 },
+    { "grey",		0x80, 0x80, 0x80 },
+    { "lime",		0x00, 0xff, 0x00 },
+    { "maroon",		0x80, 0x00, 0x00 },
+    { "navy",		0x00, 0x00, 0x80 },
+    { "olive",		0x80, 0x80, 0x00 },
+    { "purple",		0x80, 0x00, 0x80 },
+    { "silver",		0xc0, 0xc0, 0xc0 },
+    { "teal",		0x00, 0x80, 0x80 }
+  };
+
+
+  if (!n || !n[0]) return c;
+
+  if (n[0] == '#') {
+    // Do hex color lookup
+    rgb = strtol(n + 1, NULL, 16);
+
+    if (strlen(n) > 4) {
+      r = rgb >> 16;
+      g = (rgb >> 8) & 255;
+      b = rgb & 255;
+    } else {
+      r = (rgb >> 8) * 17;
+      g = ((rgb >> 4) & 15) * 17;
+      b = (rgb & 15) * 17;
+    }
+    return (fl_rgb_color((uchar)r, (uchar)g, (uchar)b));
+  } else {
+    for (i = 0; i < (int)(sizeof(colors) / sizeof(colors[0])); i ++)
+      if (!strcasecmp(n, colors[i].name)) {
+        return fl_rgb_color(colors[i].r, colors[i].g, colors[i].b);
+      }
+    return c;
+  }
+}
+
+
+//
+// 'Fl_Help_View::get_image()' - Get an inline image.
+//
+
+Fl_Shared_Image *
+Fl_Help_View::get_image(const char *name, int W, int H) {
+  const char	*localname;		// Local filename
+  char		dir[1024];		// Current directory
+  char		temp[1024],		// Temporary filename
+		*tempptr;		// Pointer into temporary name
+  Fl_Shared_Image *ip;			// Image pointer...
+
+  // See if the image can be found...
+  if (strchr(directory_, ':') != NULL && strchr(name, ':') == NULL) {
+    if (name[0] == '/') {
+      strlcpy(temp, directory_, sizeof(temp));
+
+      if ((tempptr = strrchr(strchr(directory_, ':') + 3, '/')) != NULL) {
+        strlcpy(tempptr, name, sizeof(temp) - (tempptr - temp));
+      } else {
+        strlcat(temp, name, sizeof(temp));
+      }
+    } else {
+      snprintf(temp, sizeof(temp), "%s/%s", directory_, name);
+    }
+
+    if (link_) localname = (*link_)(this, temp);
+    else localname = temp;
+  } else if (name[0] != '/' && strchr(name, ':') == NULL) {
+    if (directory_[0]) snprintf(temp, sizeof(temp), "%s/%s", directory_, name);
+    else {
+      getcwd(dir, sizeof(dir));
+      snprintf(temp, sizeof(temp), "file:%s/%s", dir, name);
+    }
+
+    if (link_) localname = (*link_)(this, temp);
+    else localname = temp;
+  } else if (link_) localname = (*link_)(this, name);
+  else localname = name;
+
+  if (!localname) return 0;
+
+  if (strncmp(localname, "file:", 5) == 0) localname += 5;
+
+  if ((ip = Fl_Shared_Image::get(localname, W, H)) == NULL)
+    ip = (Fl_Shared_Image *)&broken_image;
+
+  return ip;
+}
+
+
+//
+// 'Fl_Help_View::get_length()' - Get a length value, either absolute or %.
+//
+
+int
+Fl_Help_View::get_length(const char *l) {	// I - Value
+  int	val;					// Integer value
+
+  if (!l[0]) return 0;
+
+  val = atoi(l);
+  if (l[strlen(l) - 1] == '%') {
+    if (val > 100) val = 100;
+    else if (val < 0) val = 0;
+
+    val = val * (hsize_ - Fl::scrollbar_size()) / 100;
+  }
+
+  return val;
+}
+
+
+Fl_Help_Link *Fl_Help_View::find_link(int xx, int yy)
+{
+  int		i;
+  Fl_Help_Link	*linkp;
+  for (i = nlinks_, linkp = links_; i > 0; i --, linkp ++) {
+    if (xx >= linkp->x && xx < linkp->w &&
+        yy >= linkp->y && yy < linkp->h)
+      break;
+  }
+  return i ? linkp : 0L;
+}
+
+void Fl_Help_View::follow_link(Fl_Help_Link *linkp)
+{
+  char		target[32];	// Current target
+
+  clear_selection();
+
+  strlcpy(target, linkp->name, sizeof(target));
+
+  set_changed();
+
+  if (strcmp(linkp->filename, filename_) != 0 && linkp->filename[0])
+  {
+    char	dir[1024];	// Current directory
+    char	temp[1024],	// Temporary filename
+	      *tempptr;	// Pointer into temporary filename
+
+
+    if (strchr(directory_, ':') != NULL &&
+        strchr(linkp->filename, ':') == NULL)
+    {
+      if (linkp->filename[0] == '/')
+      {
+        strlcpy(temp, directory_, sizeof(temp));
+        if ((tempptr = strrchr(strchr(directory_, ':') + 3, '/')) != NULL)
+	  strlcpy(tempptr, linkp->filename, sizeof(temp));
+	else
+	  strlcat(temp, linkp->filename, sizeof(temp));
+      }
+      else
+	snprintf(temp, sizeof(temp), "%s/%s", directory_, linkp->filename);
+    }
+    else if (linkp->filename[0] != '/' && strchr(linkp->filename, ':') == NULL)
+    {
+      if (directory_[0])
+	snprintf(temp, sizeof(temp), "%s/%s", directory_, linkp->filename);
+      else
+      {
+	getcwd(dir, sizeof(dir));
+	snprintf(temp, sizeof(temp), "file:%s/%s", dir, linkp->filename);
+      }
+    }
+    else
+      strlcpy(temp, linkp->filename, sizeof(temp));
+
+    if (linkp->name[0])
+      snprintf(temp + strlen(temp), sizeof(temp) - strlen(temp), "#%s",
+	       linkp->name);
+
+    load(temp);
+  }
+  else if (target[0])
+    topline(target);
+  else
+    topline(0);
+
+  leftline(0);
+}
+
+void Fl_Help_View::clear_selection()
+{
+  if (current_view==this)
+    clear_global_selection();
+}
+
+void Fl_Help_View::select_all()
+{
+  clear_global_selection();
+  if (!value_) return;
+  current_view = this;
+  selection_drag_last = selection_last = strlen(value_);
+  selected = 1;
+}
+
+void Fl_Help_View::clear_global_selection()
+{
+  if (selected) redraw();
+  selection_push_first = selection_push_last = 0;
+  selection_drag_first = selection_drag_last = 0;
+  selection_first = selection_last = 0;
+  selected = 0;
+}
+
+char Fl_Help_View::begin_selection()
+{
+  clear_global_selection();
+
+  if (!fl_help_view_buffer) fl_help_view_buffer = fl_create_offscreen(1, 1);
+
+  mouse_x = Fl::event_x();
+  mouse_y = Fl::event_y();
+  draw_mode = 1;
+
+    current_view = this;
+    fl_begin_offscreen(fl_help_view_buffer);
+    draw();
+    fl_end_offscreen();
+
+  draw_mode = 0;
+
+  if (selection_push_last) return 1;
+  else return 0;
+}
+
+char Fl_Help_View::extend_selection()
+{
+  if (Fl::event_is_click())
+    return 0;
+
+//  printf("old selection_first=%d, selection_last=%d\n",
+//         selection_first, selection_last);
+
+  int sf = selection_first, sl = selection_last;
+
+  selected = 1;
+  mouse_x = Fl::event_x();
+  mouse_y = Fl::event_y();
+  draw_mode = 2;
+
+    fl_begin_offscreen(fl_help_view_buffer);
+    draw();
+    fl_end_offscreen();
+
+  draw_mode = 0;
+
+  if (selection_push_first < selection_drag_first) {
+    selection_first = selection_push_first;
+  } else {
+    selection_first = selection_drag_first;
+  }
+
+  if (selection_push_last > selection_drag_last) {
+    selection_last = selection_push_last;
+  } else {
+    selection_last = selection_drag_last;
+  }
+
+//  printf("new selection_first=%d, selection_last=%d\n",
+//         selection_first, selection_last);
+
+  if (sf!=selection_first || sl!=selection_last) {
+//    puts("REDRAW!!!\n");
+    return 1;
+  } else {
+//    puts("");
+    return 0;
+  }
+}
+
+// convert a command with up to four letters into an unsigned int
+static unsigned int command(const char *cmd)
+{
+  unsigned int ret = (tolower(cmd[0])<<24);
+  char c = cmd[1];
+  if (c=='>' || c==' ' || c==0) return ret;
+  ret |= (tolower(c)<<16);
+  c = cmd[2];
+  if (c=='>' || c==' ' || c==0) return ret;
+  ret |= (tolower(c)<<8);
+  c = cmd[3];
+  if (c=='>' || c==' ' || c==0) return ret;
+  ret |= tolower(c);
+  c = cmd[4];
+  if (c=='>' || c==' ' || c==0) return ret;
+  return 0;
+}
+
+#define CMD(a, b, c, d) ((a<<24)|(b<<16)|(c<<8)|d)
+
+void Fl_Help_View::end_selection(int clipboard) 
+{
+  if (!selected || current_view!=this) 
+    return;
+  // convert the select part of our html text into some kind of somewhat readable ASCII
+  // and store it in the selection buffer
+  char p = 0, pre = 0;;
+  int len = strlen(value_);
+  char *txt = (char*)malloc(len+1), *d = txt;
+  const char *s = value_, *cmd, *src;
+  for (;;) {
+    char c = *s++;
+    if (c==0) break;
+    if (c=='<') { // begin of some html command. Skip until we find a '>'
+      cmd = s;
+      for (;;) {
+        c = *s++;
+        if (c==0 || c=='>') break;
+      }
+      if (c==0) break;
+      // do something with this command... .
+      // the replacement string must not be longer that the command itself plus '<' and '>'
+      src = 0;
+      switch (command(cmd)) {
+        case CMD('p','r','e', 0 ): pre = 1; break;
+        case CMD('/','p','r','e'): pre = 0; break;
+        case CMD('t','d', 0 , 0 ):
+        case CMD('p', 0 , 0 , 0 ):
+        case CMD('/','p', 0 , 0 ):
+        case CMD('b','r', 0 , 0 ): src = "\n"; break;
+        case CMD('l','i', 0 , 0 ): src = "\n * "; break;
+        case CMD('/','h','1', 0 ):
+        case CMD('/','h','2', 0 ):
+        case CMD('/','h','3', 0 ):
+        case CMD('/','h','4', 0 ):
+        case CMD('/','h','5', 0 ):
+        case CMD('/','h','6', 0 ): src = "\n\n"; break;
+        case CMD('t','r', 0 , 0 ):
+        case CMD('h','1', 0 , 0 ):
+        case CMD('h','2', 0 , 0 ):
+        case CMD('h','3', 0 , 0 ):
+        case CMD('h','4', 0 , 0 ):
+        case CMD('h','5', 0 , 0 ):
+        case CMD('h','6', 0 , 0 ): src = "\n\n"; break;
+        case CMD('d','t', 0 , 0 ): src = "\n "; break;
+        case CMD('d','d', 0 , 0 ): src = "\n - "; break;
+      }
+      int n = s-value_;
+      if (src && n>selection_first && n<=selection_last) {
+        while (*src) {
+          *d++ = *src++;
+        }
+        c = src[-1];
+        p = isspace(c&255) ? ' ' : c;
+      }
+      continue;
+    }
+    if (c=='&') { // special characters
+      int xx = quote_char(s);
+      if (xx>=0) {
+        c = (char)xx;
+        for (;;) {
+          char cc = *s++;
+          if (!cc || cc==';') break;
+        }
+      }
+    }
+    int n = s-value_;
+    if (n>selection_first && n<=selection_last) {
+      if (!pre && isspace(c&255)) c = ' ';
+      if (p!=' '||c!=' ')
+        *d++ = c;
+      p = c;
+    }
+  }
+  *d = 0;
+  Fl::copy(txt, strlen(txt), clipboard);
+  free(txt);
+}
+
+#define ctrl(x) ((x)&0x1f)
+
+//
+// 'Fl_Help_View::handle()' - Handle events in the widget.
+//
+
+int				// O - 1 if we handled it, 0 otherwise
+Fl_Help_View::handle(int event)	// I - Event to handle
+{
+  static Fl_Help_Link *linkp;   // currently clicked link
+
+  int xx = Fl::event_x() - x() + leftline_;
+  int yy = Fl::event_y() - y() + topline_;
+
+  switch (event)
+  {
+    case FL_FOCUS:
+      redraw();
+      return 1;
+    case FL_UNFOCUS:
+      clear_selection();
+      redraw();
+      return 1;
+    case FL_ENTER :
+      Fl_Group::handle(event);
+      return 1;
+    case FL_LEAVE :
+      fl_cursor(FL_CURSOR_DEFAULT);
+      break;
+    case FL_MOVE:
+      if (find_link(xx, yy)) fl_cursor(FL_CURSOR_HAND);
+      else fl_cursor(FL_CURSOR_DEFAULT);
+      return 1;
+    case FL_PUSH:
+      if (Fl_Group::handle(event)) return 1;
+      linkp = find_link(xx, yy);
+      if (linkp) {
+        fl_cursor(FL_CURSOR_HAND);
+        return 1;
+      }
+      if (begin_selection()) {
+        fl_cursor(FL_CURSOR_INSERT);
+        return 1;
+      }
+      fl_cursor(FL_CURSOR_DEFAULT);
+      return 1;
+    case FL_DRAG:
+      if (linkp) {
+        if (Fl::event_is_click()) {
+          fl_cursor(FL_CURSOR_HAND);
+        } else {
+          fl_cursor(FL_CURSOR_DEFAULT); // should be "FL_CURSOR_CANCEL" if we had it
+        }
+        return 1;
+      }
+      if (current_view==this && selection_push_last) {
+        if (extend_selection()) redraw();
+        fl_cursor(FL_CURSOR_INSERT);
+        return 1;
+      }
+      fl_cursor(FL_CURSOR_DEFAULT);
+      return 1;
+    case FL_RELEASE:
+      if (linkp) {
+        if (Fl::event_is_click()) {
+          follow_link(linkp);
+        }
+        fl_cursor(FL_CURSOR_DEFAULT);
+        linkp = 0;
+        return 1;
+      }
+      if (current_view==this && selection_push_last) {
+        end_selection();
+        return 1;
+      }
+      return 1;
+    case FL_SHORTCUT: {
+      char ascii = Fl::event_text()[0];
+      switch (ascii) {
+        case ctrl('A'): select_all(); redraw(); return 1;
+        case ctrl('C'):
+        case ctrl('X'): end_selection(1); return 1;
+      }
+      break; }
+  }
+  return (Fl_Group::handle(event));
+}
+
+//
+// 'Fl_Help_View::Fl_Help_View()' - Build a Fl_Help_View widget.
+//
+
+Fl_Help_View::Fl_Help_View(int        xx,	// I - Left position
+                	   int        yy,	// I - Top position
+			   int        ww,	// I - Width in pixels
+			   int        hh,	// I - Height in pixels
+			   const char *l)
+    : Fl_Group(xx, yy, ww, hh, l),
+      scrollbar_(xx + ww - Fl::scrollbar_size(), yy,
+                 Fl::scrollbar_size(), hh - Fl::scrollbar_size()),
+      hscrollbar_(xx, yy + hh - Fl::scrollbar_size(),
+                  ww - Fl::scrollbar_size(), Fl::scrollbar_size())
+{
+  color(FL_BACKGROUND2_COLOR, FL_SELECTION_COLOR);
+
+  title_[0]     = '\0';
+  defcolor_     = FL_FOREGROUND_COLOR;
+  bgcolor_      = FL_BACKGROUND_COLOR;
+  textcolor_    = FL_FOREGROUND_COLOR;
+  linkcolor_    = FL_SELECTION_COLOR;
+  textfont_     = FL_TIMES;
+  textsize_     = 12;
+  value_        = NULL;
+
+  ablocks_      = 0;
+  nblocks_      = 0;
+  blocks_       = (Fl_Help_Block *)0;
+
+  nfonts_       = 0;
+
+  link_         = (Fl_Help_Func *)0;
+
+  alinks_       = 0;
+  nlinks_       = 0;
+  links_        = (Fl_Help_Link *)0;
+
+  atargets_     = 0;
+  ntargets_     = 0;
+  targets_      = (Fl_Help_Target *)0;
+
+  directory_[0] = '\0';
+  filename_[0]  = '\0';
+
+  topline_      = 0;
+  leftline_     = 0;
+  size_         = 0;
+  hsize_        = 0;
+
+  scrollbar_.value(0, hh, 0, 1);
+  scrollbar_.step(8.0);
+  scrollbar_.show();
+  scrollbar_.callback(scrollbar_callback);
+
+  hscrollbar_.value(0, ww, 0, 1);
+  hscrollbar_.step(8.0);
+  hscrollbar_.show();
+  hscrollbar_.callback(hscrollbar_callback);
+  hscrollbar_.type(FL_HORIZONTAL);
+  end();
+
+  resize(xx, yy, ww, hh);
+}
+
+
+//
+// 'Fl_Help_View::~Fl_Help_View()' - Destroy a Fl_Help_View widget.
+//
+
+Fl_Help_View::~Fl_Help_View()
+{
+  clear_selection();
+  free_data();
+}
+
+
+//
+// 'Fl_Help_View::load()' - Load the specified file.
+//
+
+int				// O - 0 on success, -1 on error
+Fl_Help_View::load(const char *f)// I - Filename to load (may also have target)
+{
+  FILE		*fp;		// File to read from
+  long		len;		// Length of file
+  char		*target;	// Target in file
+  char		*slash;		// Directory separator
+  const char	*localname;	// Local filename
+  char		error[1024];	// Error buffer
+  char		newname[1024];	// New filename buffer
+
+
+  clear_selection();
+
+  strlcpy(newname, f, sizeof(newname));
+  if ((target = strrchr(newname, '#')) != NULL)
+    *target++ = '\0';
+
+  if (link_)
+    localname = (*link_)(this, newname);
+  else
+    localname = filename_;
+
+  if (!localname)
+    return (0);
+
+  strlcpy(filename_, newname, sizeof(filename_));
+  strlcpy(directory_, newname, sizeof(directory_));
+
+  // Note: We do not support Windows backslashes, since they are illegal
+  //       in URLs...
+  if ((slash = strrchr(directory_, '/')) == NULL)
+    directory_[0] = '\0';
+  else if (slash > directory_ && slash[-1] != '/')
+    *slash = '\0';
+
+  if (value_ != NULL)
+  {
+    free((void *)value_);
+    value_ = NULL;
+  }
+
+  if (strncmp(localname, "ftp:", 4) == 0 ||
+      strncmp(localname, "http:", 5) == 0 ||
+      strncmp(localname, "https:", 6) == 0 ||
+      strncmp(localname, "ipp:", 4) == 0 ||
+      strncmp(localname, "mailto:", 7) == 0 ||
+      strncmp(localname, "news:", 5) == 0)
+  {
+    // Remote link wasn't resolved...
+    snprintf(error, sizeof(error),
+             "Error"
+             "

Error

" + "

Unable to follow the link \"%s\" - " + "no handler exists for this URI scheme.

", + localname); + value_ = strdup(error); + } + else + { + if (strncmp(localname, "file:", 5) == 0) + localname += 5; // Adjust for local filename... + + if ((fp = fopen(localname, "rb")) != NULL) + { + fseek(fp, 0, SEEK_END); + len = ftell(fp); + rewind(fp); + + value_ = (const char *)calloc(len + 1, 1); + fread((void *)value_, 1, len, fp); + fclose(fp); + } + else + { + snprintf(error, sizeof(error), + "Error" + "

Error

" + "

Unable to follow the link \"%s\" - " + "%s.

", + localname, strerror(errno)); + value_ = strdup(error); + } + } + + format(); + + if (target) + topline(target); + else + topline(0); + + return (0); +} + + +// +// 'Fl_Help_View::resize()' - Resize the help widget. +// + +void +Fl_Help_View::resize(int xx, // I - New left position + int yy, // I - New top position + int ww, // I - New width + int hh) // I - New height +{ + Fl_Boxtype b = box() ? box() : FL_DOWN_BOX; + // Box to draw... + + + Fl_Widget::resize(xx, yy, ww, hh); + + int ss = Fl::scrollbar_size(); + scrollbar_.resize(x() + w() - ss - Fl::box_dw(b) + Fl::box_dx(b), + y() + Fl::box_dy(b), ss, h() - ss - Fl::box_dh(b)); + hscrollbar_.resize(x() + Fl::box_dx(b), + y() + h() - ss - Fl::box_dh(b) + Fl::box_dy(b), + w() - ss - Fl::box_dw(b), ss); + + format(); +} + + +// +// 'Fl_Help_View::topline()' - Set the top line to the named target. +// + +void +Fl_Help_View::topline(const char *n) // I - Target name +{ + Fl_Help_Target key, // Target name key + *target; // Pointer to matching target + + + if (ntargets_ == 0) + return; + + strlcpy(key.name, n, sizeof(key.name)); + + target = (Fl_Help_Target *)bsearch(&key, targets_, ntargets_, sizeof(Fl_Help_Target), + (compare_func_t)compare_targets); + + if (target != NULL) + topline(target->y); +} + + +// +// 'Fl_Help_View::topline()' - Set the top line by number. +// + +void +Fl_Help_View::topline(int t) // I - Top line number +{ + if (!value_) + return; + + if (size_ < (h() - Fl::scrollbar_size()) || t < 0) + t = 0; + else if (t > size_) + t = size_; + + topline_ = t; + + scrollbar_.value(topline_, h() - Fl::scrollbar_size(), 0, size_); + + do_callback(); + + redraw(); +} + + +// +// 'Fl_Help_View::leftline()' - Set the left position. +// + +void +Fl_Help_View::leftline(int l) // I - Left position +{ + if (!value_) + return; + + if (hsize_ < (w() - Fl::scrollbar_size()) || l < 0) + l = 0; + else if (l > hsize_) + l = hsize_; + + leftline_ = l; + + hscrollbar_.value(leftline_, w() - Fl::scrollbar_size(), 0, hsize_); + + redraw(); +} + + +// +// 'Fl_Help_View::value()' - Set the help text directly. +// + +void +Fl_Help_View::value(const char *v) // I - Text to view +{ + clear_selection(); + free_data(); + set_changed(); + + if (!v) + return; + + value_ = strdup(v); + + format(); + + topline(0); + leftline(0); +} + +#ifdef ENC +# undef ENC +#endif +#ifdef __APPLE__ +# define ENC(a, b) b +#else +# define ENC(a, b) a +#endif + +// +// 'quote_char()' - Return the character code associated with a quoted char. +// + +static int // O - Code or -1 on error +quote_char(const char *p) { // I - Quoted string + int i; // Looping var + static struct { + const char *name; + int namelen; + int code; + } *nameptr, // Pointer into name array + names[] = { // Quoting names + { "Aacute;", 7, ENC(193,231) }, + { "aacute;", 7, ENC(225,135) }, + { "Acirc;", 6, ENC(194,229) }, + { "acirc;", 6, ENC(226,137) }, + { "acute;", 6, ENC(180,171) }, + { "AElig;", 6, ENC(198,174) }, + { "aelig;", 6, ENC(230,190) }, + { "Agrave;", 7, ENC(192,203) }, + { "agrave;", 7, ENC(224,136) }, + { "amp;", 4, ENC('&','&') }, + { "Aring;", 6, ENC(197,129) }, + { "aring;", 6, ENC(229,140) }, + { "Atilde;", 7, ENC(195,204) }, + { "atilde;", 7, ENC(227,139) }, + { "Auml;", 5, ENC(196,128) }, + { "auml;", 5, ENC(228,138) }, + { "brvbar;", 7, ENC(166, -1) }, + { "bull;", 5, ENC(149,165) }, + { "Ccedil;", 7, ENC(199,199) }, + { "ccedil;", 7, ENC(231,141) }, + { "cedil;", 6, ENC(184,252) }, + { "cent;", 5, ENC(162,162) }, + { "copy;", 5, ENC(169,169) }, + { "curren;", 7, ENC(164, -1) }, + { "deg;", 4, ENC(176,161) }, + { "divide;", 7, ENC(247,214) }, + { "Eacute;", 7, ENC(201,131) }, + { "eacute;", 7, ENC(233,142) }, + { "Ecirc;", 6, ENC(202,230) }, + { "ecirc;", 6, ENC(234,144) }, + { "Egrave;", 7, ENC(200,233) }, + { "egrave;", 7, ENC(232,143) }, + { "ETH;", 4, ENC(208, -1) }, + { "eth;", 4, ENC(240, -1) }, + { "Euml;", 5, ENC(203,232) }, + { "euml;", 5, ENC(235,145) }, + { "euro;", 5, ENC(128,219) }, + { "frac12;", 7, ENC(189, -1) }, + { "frac14;", 7, ENC(188, -1) }, + { "frac34;", 7, ENC(190, -1) }, + { "gt;", 3, ENC('>','>') }, + { "Iacute;", 7, ENC(205,234) }, + { "iacute;", 7, ENC(237,146) }, + { "Icirc;", 6, ENC(206,235) }, + { "icirc;", 6, ENC(238,148) }, + { "iexcl;", 6, ENC(161,193) }, + { "Igrave;", 7, ENC(204,237) }, + { "igrave;", 7, ENC(236,147) }, + { "iquest;", 7, ENC(191,192) }, + { "Iuml;", 5, ENC(207,236) }, + { "iuml;", 5, ENC(239,149) }, + { "laquo;", 6, ENC(171,199) }, + { "lt;", 3, ENC('<','<') }, + { "macr;", 5, ENC(175,248) }, + { "micro;", 6, ENC(181,181) }, + { "middot;", 7, ENC(183,225) }, + { "nbsp;", 5, ENC(' ',' ') }, + { "not;", 4, ENC(172,194) }, + { "Ntilde;", 7, ENC(209,132) }, + { "ntilde;", 7, ENC(241,150) }, + { "Oacute;", 7, ENC(211,238) }, + { "oacute;", 7, ENC(243,151) }, + { "Ocirc;", 6, ENC(212,239) }, + { "ocirc;", 6, ENC(244,153) }, + { "Ograve;", 7, ENC(210,241) }, + { "ograve;", 7, ENC(242,152) }, + { "ordf;", 5, ENC(170,187) }, + { "ordm;", 5, ENC(186,188) }, + { "Oslash;", 7, ENC(216,175) }, + { "oslash;", 7, ENC(248,191) }, + { "Otilde;", 7, ENC(213,205) }, + { "otilde;", 7, ENC(245,155) }, + { "Ouml;", 5, ENC(214,133) }, + { "ouml;", 5, ENC(246,154) }, + { "para;", 5, ENC(182,166) }, + { "premil;", 7, ENC(137,228) }, + { "plusmn;", 7, ENC(177,177) }, + { "pound;", 6, ENC(163,163) }, + { "quot;", 5, ENC('\"','\"') }, + { "raquo;", 6, ENC(187,200) }, + { "reg;", 4, ENC(174,168) }, + { "sect;", 5, ENC(167,164) }, + { "shy;", 4, ENC(173,'-') }, + { "sup1;", 5, ENC(185, -1) }, + { "sup2;", 5, ENC(178, -1) }, + { "sup3;", 5, ENC(179, -1) }, + { "szlig;", 6, ENC(223,167) }, + { "THORN;", 6, ENC(222, -1) }, + { "thorn;", 6, ENC(254, -1) }, + { "times;", 6, ENC(215,'x') }, + { "trade;", 6, ENC(153,170) }, + { "Uacute;", 7, ENC(218,242) }, + { "uacute;", 7, ENC(250,156) }, + { "Ucirc;", 6, ENC(219,243) }, + { "ucirc;", 6, ENC(251,158) }, + { "Ugrave;", 7, ENC(217,244) }, + { "ugrave;", 7, ENC(249,157) }, + { "uml;", 4, ENC(168,172) }, + { "Uuml;", 5, ENC(220,134) }, + { "uuml;", 5, ENC(252,159) }, + { "Yacute;", 7, ENC(221, -1) }, + { "yacute;", 7, ENC(253, -1) }, + { "yen;", 4, ENC(165,180) }, + { "Yuml;", 5, ENC(159,217) }, + { "yuml;", 5, ENC(255,216) } + }; + + if (!strchr(p, ';')) return -1; + if (*p == '#') { + if (*(p+1) == 'x' || *(p+1) == 'X') return strtol(p+2, NULL, 16); + else return atoi(p+1); + } + for (i = (int)(sizeof(names) / sizeof(names[0])), nameptr = names; i > 0; i --, nameptr ++) + if (strncmp(p, nameptr->name, nameptr->namelen) == 0) + return nameptr->code; + + return -1; +} + + +// +// 'scrollbar_callback()' - A callback for the scrollbar. +// + +static void +scrollbar_callback(Fl_Widget *s, void *) +{ + ((Fl_Help_View *)(s->parent()))->topline(int(((Fl_Scrollbar*)s)->value())); +} + + +// +// 'hscrollbar_callback()' - A callback for the horizontal scrollbar. +// + +static void +hscrollbar_callback(Fl_Widget *s, void *) +{ + ((Fl_Help_View *)(s->parent()))->leftline(int(((Fl_Scrollbar*)s)->value())); +} + + +// +// End of "$Id: Fl_Help_View.cxx 6091 2008-04-11 11:12:16Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Image.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Image.cxx new file mode 100644 index 000000000..35ddcae35 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Image.cxx @@ -0,0 +1,525 @@ +// +// "$Id: Fl_Image.cxx 5888 2007-06-07 17:23:41Z matt $" +// +// Image drawing code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2006 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include +#include +#include +#include "flstring.h" + +#ifdef WIN32 +void fl_release_dc(HWND, HDC); // from Fl_win32.cxx +#endif + +void fl_restore_clip(); // from fl_rect.cxx + +// +// Base image class... +// + +Fl_Image::~Fl_Image() { +} + +void Fl_Image::uncache() { +} + +void Fl_Image::draw(int XP, int YP, int, int, int, int) { + draw_empty(XP, YP); +} + +void Fl_Image::draw_empty(int X, int Y) { + if (w() > 0 && h() > 0) { + fl_color(FL_FOREGROUND_COLOR); + fl_rect(X, Y, w(), h()); + fl_line(X, Y, X + w() - 1, Y + h() - 1); + fl_line(X, Y + h() - 1, X + w() - 1, Y); + } +} + +Fl_Image *Fl_Image::copy(int W, int H) { + return new Fl_Image(W, H, d()); +} + +void Fl_Image::color_average(Fl_Color, float) { +} + +void Fl_Image::desaturate() { +} + +void Fl_Image::label(Fl_Widget* widget) { + widget->image(this); +} + +void Fl_Image::label(Fl_Menu_Item* m) { + Fl::set_labeltype(_FL_IMAGE_LABEL, labeltype, measure); + m->label(_FL_IMAGE_LABEL, (const char*)this); +} + +void +Fl_Image::labeltype(const Fl_Label *lo, // I - Label + int lx, // I - X position + int ly, // I - Y position + int lw, // I - Width of label + int lh, // I - Height of label + Fl_Align la) { // I - Alignment + Fl_Image *img; // Image pointer + int cx, cy; // Image position + + img = (Fl_Image *)(lo->value); + + if (la & FL_ALIGN_LEFT) cx = 0; + else if (la & FL_ALIGN_RIGHT) cx = img->w() - lw; + else cx = (img->w() - lw) / 2; + + if (la & FL_ALIGN_TOP) cy = 0; + else if (la & FL_ALIGN_BOTTOM) cy = img->h() - lh; + else cy = (img->h() - lh) / 2; + + fl_color((Fl_Color)lo->color); + + img->draw(lx, ly, lw, lh, cx, cy); +} + +void +Fl_Image::measure(const Fl_Label *lo, // I - Label + int &lw, // O - Width of image + int &lh) { // O - Height of image + Fl_Image *img; // Image pointer + + img = (Fl_Image *)(lo->value); + + lw = img->w(); + lh = img->h(); +} + + +// +// RGB image class... +// + +Fl_RGB_Image::~Fl_RGB_Image() { + uncache(); + if (alloc_array) delete[] (uchar *)array; +} + +void Fl_RGB_Image::uncache() { +#ifdef __APPLE_QUARTZ__ + if (id) { + CGImageRelease((CGImageRef)id); + id = 0; + } +#else + if (id) { + fl_delete_offscreen((Fl_Offscreen)id); + id = 0; + } + + if (mask) { + fl_delete_bitmask((Fl_Bitmask)mask); + mask = 0; + } +#endif +} + +Fl_Image *Fl_RGB_Image::copy(int W, int H) { + Fl_RGB_Image *new_image; // New RGB image + uchar *new_array; // New array for image data + + // Optimize the simple copy where the width and height are the same, + // or when we are copying an empty image... + if ((W == w() && H == h()) || + !w() || !h() || !d() || !array) { + if (array) { + // Make a copy of the image data and return a new Fl_RGB_Image... + new_array = new uchar[w() * h() * d()]; + if (ld() && ld()!=w()*d()) { + const uchar *src = array; + uchar *dst = new_array; + int dy, dh = h(), wd = w()*d(), wld = ld(); + for (dy=0; dyalloc_array = 1; + + return new_image; + } else return new Fl_RGB_Image(array, w(), h(), d(), ld()); + } + if (W <= 0 || H <= 0) return 0; + + // OK, need to resize the image data; allocate memory and + uchar *new_ptr; // Pointer into new array + const uchar *old_ptr; // Pointer into old array + int c, // Channel number + sy, // Source coordinate + dx, dy, // Destination coordinates + xerr, yerr, // X & Y errors + xmod, ymod, // X & Y moduli + xstep, ystep, // X & Y step increments + line_d; // stride from line to line + + + // Figure out Bresenheim step/modulus values... + xmod = w() % W; + xstep = (w() / W) * d(); + ymod = h() % H; + ystep = h() / H; + line_d = ld() ? ld() : w() * d(); + + // Allocate memory for the new image... + new_array = new uchar [W * H * d()]; + new_image = new Fl_RGB_Image(new_array, W, H, d()); + new_image->alloc_array = 1; + + // Scale the image using a nearest-neighbor algorithm... + for (dy = H, sy = 0, yerr = H, new_ptr = new_array; dy > 0; dy --) { + for (dx = W, xerr = W, old_ptr = array + sy * line_d; dx > 0; dx --) { + for (c = 0; c < d(); c ++) *new_ptr++ = old_ptr[c]; + + old_ptr += xstep; + xerr -= xmod; + + if (xerr <= 0) { + xerr += W; + old_ptr += d(); + } + } + + sy += ystep; + yerr -= ymod; + if (yerr <= 0) { + yerr += H; + sy ++; + } + } + + return new_image; +} + +void Fl_RGB_Image::color_average(Fl_Color c, float i) { + // Don't average an empty image... + if (!w() || !h() || !d() || !array) return; + + // Delete any existing pixmap/mask objects... + uncache(); + + // Allocate memory as needed... + uchar *new_array, + *new_ptr; + + if (!alloc_array) new_array = new uchar[h() * w() * d()]; + else new_array = (uchar *)array; + + // Get the color to blend with... + uchar r, g, b; + unsigned ia, ir, ig, ib; + + Fl::get_color(c, r, g, b); + if (i < 0.0f) i = 0.0f; + else if (i > 1.0f) i = 1.0f; + + ia = (unsigned)(256 * i); + ir = r * (256 - ia); + ig = g * (256 - ia); + ib = b * (256 - ia); + + // Update the image data to do the blend... + const uchar *old_ptr; + int x, y; + int line_i = ld() ? ld() - (w()*d()) : 0; // increment from line end to beginning of next line + + if (d() < 3) { + ig = (r * 31 + g * 61 + b * 8) / 100 * (256 - ia); + + for (new_ptr = new_array, old_ptr = array, y = 0; y < h(); y ++, old_ptr += line_i) + for (x = 0; x < w(); x ++) { + *new_ptr++ = (*old_ptr++ * ia + ig) >> 8; + if (d() > 1) *new_ptr++ = *old_ptr++; + } + } else { + for (new_ptr = new_array, old_ptr = array, y = 0; y < h(); y ++, old_ptr += line_i) + for (x = 0; x < w(); x ++) { + *new_ptr++ = (*old_ptr++ * ia + ir) >> 8; + *new_ptr++ = (*old_ptr++ * ia + ig) >> 8; + *new_ptr++ = (*old_ptr++ * ia + ib) >> 8; + if (d() > 3) *new_ptr++ = *old_ptr++; + } + } + + // Set the new pointers/values as needed... + if (!alloc_array) { + array = new_array; + alloc_array = 1; + + ld(0); + } +} + +void Fl_RGB_Image::desaturate() { + // Don't desaturate an empty image... + if (!w() || !h() || !d() || !array) return; + + // Can only desaturate color images... + if (d() < 3) return; + + // Delete any existing pixmap/mask objects... + uncache(); + + // Allocate memory for a grayscale image... + uchar *new_array, + *new_ptr; + int new_d; + + new_d = d() - 2; + new_array = new uchar[h() * w() * new_d]; + + // Copy the image data, converting to grayscale... + const uchar *old_ptr; + int x, y; + int line_i = ld() ? ld() - (w()*d()) : 0; // increment from line end to beginning of next line + + for (new_ptr = new_array, old_ptr = array, y = 0; y < h(); y ++, old_ptr += line_i) + for (x = 0; x < w(); x ++, old_ptr += d()) { + *new_ptr++ = (uchar)((31 * old_ptr[0] + 61 * old_ptr[1] + 8 * old_ptr[2]) / 100); + if (d() > 3) *new_ptr++ = old_ptr[3]; + } + + // Free the old array as needed, and then set the new pointers/values... + if (alloc_array) delete[] (uchar *)array; + + array = new_array; + alloc_array = 1; + + ld(0); + d(new_d); +} + +#if !defined(WIN32) && !USE_QUARTZ +// Composite an image with alpha on systems that don't have accelerated +// alpha compositing... +static void alpha_blend(Fl_RGB_Image *img, int X, int Y, int W, int H, int cx, int cy) { + uchar *srcptr = (uchar*)img->array + img->d() * (img->w() * cy + cx); + int srcskip = img->d() * (img->w() - W); + + uchar *dst = new uchar[W * H * 3]; + uchar *dstptr = dst; + + fl_read_image(dst, X, Y, W, H, 0); + + uchar srcr, srcg, srcb, srca; + uchar dstr, dstg, dstb, dsta; + + if (img->d() == 2) { + // Composite grayscale + alpha over RGB... + // Composite RGBA over RGB... + for (int y = H; y > 0; y--, srcptr+=srcskip) + for (int x = W; x > 0; x--) { + srcg = *srcptr++; + srca = *srcptr++; + + dstr = dstptr[0]; + dstg = dstptr[1]; + dstb = dstptr[2]; + dsta = 255 - srca; + + *dstptr++ = (srcg * srca + dstr * dsta) >> 8; + *dstptr++ = (srcg * srca + dstg * dsta) >> 8; + *dstptr++ = (srcg * srca + dstb * dsta) >> 8; + } + } else { + // Composite RGBA over RGB... + for (int y = H; y > 0; y--, srcptr+=srcskip) + for (int x = W; x > 0; x--) { + srcr = *srcptr++; + srcg = *srcptr++; + srcb = *srcptr++; + srca = *srcptr++; + + dstr = dstptr[0]; + dstg = dstptr[1]; + dstb = dstptr[2]; + dsta = 255 - srca; + + *dstptr++ = (srcr * srca + dstr * dsta) >> 8; + *dstptr++ = (srcg * srca + dstg * dsta) >> 8; + *dstptr++ = (srcb * srca + dstb * dsta) >> 8; + } + } + + fl_draw_image(dst, X, Y, W, H, 3, 0); + + delete[] dst; +} +#endif // !WIN32 && !USE_QUARTZ + +void Fl_RGB_Image::draw(int XP, int YP, int WP, int HP, int cx, int cy) { + // Don't draw an empty image... + if (!d() || !array) { + draw_empty(XP, YP); + return; + } + + // account for current clip region (faster on Irix): + int X,Y,W,H; fl_clip_box(XP,YP,WP,HP,X,Y,W,H); + cx += X-XP; cy += Y-YP; + // clip the box down to the size of image, quit if empty: + if (cx < 0) {W += cx; X -= cx; cx = 0;} + if (cx+W > w()) W = w()-cx; + if (W <= 0) return; + if (cy < 0) {H += cy; Y -= cy; cy = 0;} + if (cy+H > h()) H = h()-cy; + if (H <= 0) return; + if (!id) { +#ifdef __APPLE_QUARTZ__ + CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB(); + CGDataProviderRef src = CGDataProviderCreateWithData( 0L, array, w()*h()*d(), 0L); + id = CGImageCreate( w(), h(), 8, d()*8, ld()?ld():w()*d(), + lut, (d()&1)?kCGImageAlphaNone:kCGImageAlphaLast, + src, 0L, false, kCGRenderingIntentDefault); + CGColorSpaceRelease(lut); + CGDataProviderRelease(src); +#elif defined(WIN32) + id = fl_create_offscreen(w(), h()); + if (d() == 2 || d() == 4 && fl_can_do_alpha_blending()) { + fl_begin_offscreen((Fl_Offscreen)id); + fl_draw_image(array, 0, 0, w(), h(), d()|FL_IMAGE_WITH_ALPHA, ld()); + fl_end_offscreen(); + } else { + fl_begin_offscreen((Fl_Offscreen)id); + fl_draw_image(array, 0, 0, w(), h(), d(), ld()); + fl_end_offscreen(); + if (d() == 2 || d() == 4) { + mask = fl_create_alphamask(w(), h(), d(), ld(), array); + } + } +#else + if (d() == 1 || d() == 3) { + id = fl_create_offscreen(w(), h()); + fl_begin_offscreen((Fl_Offscreen)id); + fl_draw_image(array, 0, 0, w(), h(), d(), ld()); + fl_end_offscreen(); + } +#endif + } +#ifdef WIN32 + if (mask) { + HDC new_gc = CreateCompatibleDC(fl_gc); + int save = SaveDC(new_gc); + SelectObject(new_gc, (void*)mask); + BitBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, SRCAND); + SelectObject(new_gc, (void*)id); + BitBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, SRCPAINT); + RestoreDC(new_gc,save); + DeleteDC(new_gc); + } else if (d()==2 || d()==4) { + fl_copy_offscreen_with_alpha(X, Y, W, H, (Fl_Offscreen)id, cx, cy); + } else { + fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)id, cx, cy); + } +#elif defined(__APPLE_QD__) + if (mask) { + Rect src, dst; + // MRS: STR #114 says we should be using cx, cy, W, and H... +// src.left = 0; src.right = w(); +// src.top = 0; src.bottom = h(); +// dst.left = X; dst.right = X+w(); +// dst.top = Y; dst.bottom = Y+h(); + src.left = cx; src.right = cx+W; + src.top = cy; src.bottom = cy+H; + dst.left = X; dst.right = X+W; + dst.top = Y; dst.bottom = Y+H; + RGBColor rgb; + rgb.red = 0xffff; rgb.green = 0xffff; rgb.blue = 0xffff; + RGBBackColor(&rgb); + rgb.red = 0x0000; rgb.green = 0x0000; rgb.blue = 0x0000; + RGBForeColor(&rgb); + + CopyMask(GetPortBitMapForCopyBits((GrafPtr)id), + GetPortBitMapForCopyBits((GrafPtr)mask), + GetPortBitMapForCopyBits(GetWindowPort(fl_window)), + &src, &src, &dst); + } else if (id) fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)id, cx, cy); + else { + // Composite image with alpha manually each time... + alpha_blend(this, X, Y, W, H, cx, cy); + } +#elif defined(__APPLE_QUARTZ__) + if (id && fl_gc) { + CGRect rect = { { X, Y }, { W, H } }; + Fl_X::q_begin_image(rect, cx, cy, w(), h()); + CGContextDrawImage(fl_gc, rect, (CGImageRef)id); + Fl_X::q_end_image(); + } +#else + if (id) { + if (mask) { + // I can't figure out how to combine a mask with existing region, + // so cut the image down to a clipped rectangle: + int nx, ny; fl_clip_box(X,Y,W,H,nx,ny,W,H); + cx += nx-X; X = nx; + cy += ny-Y; Y = ny; + // make X use the bitmap as a mask: + XSetClipMask(fl_display, fl_gc, mask); + int ox = X-cx; if (ox < 0) ox += w(); + int oy = Y-cy; if (oy < 0) oy += h(); + XSetClipOrigin(fl_display, fl_gc, X-cx, Y-cy); + } + + fl_copy_offscreen(X, Y, W, H, id, cx, cy); + + if (mask) { + // put the old clip region back + XSetClipOrigin(fl_display, fl_gc, 0, 0); + fl_restore_clip(); + } + } else { + // Composite image with alpha manually each time... + alpha_blend(this, X, Y, W, H, cx, cy); + } +#endif +} + +void Fl_RGB_Image::label(Fl_Widget* widget) { + widget->image(this); +} + +void Fl_RGB_Image::label(Fl_Menu_Item* m) { + Fl::set_labeltype(_FL_IMAGE_LABEL, labeltype, measure); + m->label(_FL_IMAGE_LABEL, (const char*)this); +} + + +// +// End of "$Id: Fl_Image.cxx 5888 2007-06-07 17:23:41Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Input.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Input.cxx new file mode 100644 index 000000000..ae3e8d33d --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Input.cxx @@ -0,0 +1,474 @@ +// +// "$Id: Fl_Input.cxx 6103 2008-04-21 20:42:51Z matt $" +// +// Input widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2006 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// This is the "user interface", it decodes user actions into what to +// do to the text. See also Fl_Input_.cxx, where the text is actually +// manipulated (and some ui, in particular the mouse, is done...). +// In theory you can replace this code with another subclass to change +// the keybindings. + +#include +#include +#include +#include +#include +#include +#include +#include "flstring.h" + +#ifdef HAVE_LOCALE_H +# include +#endif + + +void Fl_Input::draw() { + if (input_type() == FL_HIDDEN_INPUT) return; + Fl_Boxtype b = box(); + if (damage() & FL_DAMAGE_ALL) draw_box(b, color()); + Fl_Input_::drawtext(x()+Fl::box_dx(b), y()+Fl::box_dy(b), + w()-Fl::box_dw(b), h()-Fl::box_dh(b)); +} + +// kludge so shift causes selection to extend: +int Fl_Input::shift_position(int p) { + return position(p, Fl::event_state(FL_SHIFT) ? mark() : p); +} +int Fl_Input::shift_up_down_position(int p) { + return up_down_position(p, Fl::event_state(FL_SHIFT)); +} + +// If you define this symbol as zero you will get the peculiar fltk +// behavior where moving off the end of an input field will move the +// cursor into the next field: +// define it as 1 to prevent cursor movement from going to next field: +#define NORMAL_INPUT_MOVE 0 + +#define ctrl(x) ((x)^0x40) + +// List of characters that are legal in a floating point input field. +// This text string is created at run-time to take the current locale +// into account (for example, continental Europe uses a comma instead +// of a decimal point). For back compatibility reasons, we always +// allow the decimal point. +#ifdef HAVE_LOCALECONV +static const char *standard_fp_chars = ".eE+-"; +static const char *legal_fp_chars = 0L; +#else +static const char *legal_fp_chars = ".eE+-"; +#endif + +int Fl_Input::handle_key() { + + char ascii = Fl::event_text()[0]; + + int repeat_num=1; + + int del; + if (Fl::compose(del)) { + + // Insert characters into numeric fields after checking for legality: + if (input_type() == FL_FLOAT_INPUT || input_type() == FL_INT_INPUT) { + Fl::compose_reset(); // ignore any foreign letters... + + // initialize the list of legal characters inside a floating point number +#ifdef HAVE_LOCALECONV + if (!legal_fp_chars) { + int len = strlen(standard_fp_chars); + struct lconv *lc = localeconv(); + if (lc) { + if (lc->decimal_point) len += strlen(lc->decimal_point); + if (lc->mon_decimal_point) len += strlen(lc->mon_decimal_point); + if (lc->positive_sign) len += strlen(lc->positive_sign); + if (lc->negative_sign) len += strlen(lc->negative_sign); + } + // the following line is not a true memory leak because the array is only + // allocated once if required, and automatically freed when the program quits + char *chars = (char*)malloc(len+1); + legal_fp_chars = chars; + strcpy(chars, standard_fp_chars); + if (lc) { + if (lc->decimal_point) strcat(chars, lc->decimal_point); + if (lc->mon_decimal_point) strcat(chars, lc->mon_decimal_point); + if (lc->positive_sign) strcat(chars, lc->positive_sign); + if (lc->negative_sign) strcat(chars, lc->negative_sign); + } + } +#endif // HAVE_LOCALECONV + + // This is complex to allow "0xff12" hex to be typed: + if (!position() && (ascii == '+' || ascii == '-') || + (ascii >= '0' && ascii <= '9') || + (position()==1 && index(0)=='0' && (ascii=='x' || ascii == 'X')) || + (position()>1 && index(0)=='0' && (index(1)=='x'||index(1)=='X') + && (ascii>='A'&& ascii<='F' || ascii>='a'&& ascii<='f')) || + input_type()==FL_FLOAT_INPUT && ascii && strchr(legal_fp_chars, ascii)) { + if (readonly()) fl_beep(); + else replace(position(), mark(), &ascii, 1); + } + return 1; + } + + if (del || Fl::event_length()) { + if (readonly()) fl_beep(); + else replace(position(), del ? position()-del : mark(), + Fl::event_text(), Fl::event_length()); + } + return 1; + } + + switch (Fl::event_key()) { + case FL_Insert: + if (Fl::event_state() & FL_CTRL) ascii = ctrl('C'); + else if (Fl::event_state() & FL_SHIFT) ascii = ctrl('V'); + break; + case FL_Delete: + if (Fl::event_state() & FL_SHIFT) ascii = ctrl('X'); + else ascii = ctrl('D'); + break; + case FL_Left: + ascii = ctrl('B'); break; + case FL_Right: + ascii = ctrl('F'); break; + case FL_Page_Up: + fl_font(textfont(),textsize()); //ensure current font is set to ours + repeat_num=h()/fl_height(); // number of lines to scroll + if (!repeat_num) repeat_num=1; + case FL_Up: + ascii = ctrl('P'); break; + case FL_Page_Down: + fl_font(textfont(),textsize()); + repeat_num=h()/fl_height(); + if (!repeat_num) repeat_num=1; + case FL_Down: + ascii = ctrl('N'); break; + case FL_Home: + if (Fl::event_state() & FL_CTRL) { + shift_position(0); + return 1; + } + ascii = ctrl('A'); + break; + case FL_End: + if (Fl::event_state() & FL_CTRL) { + shift_position(size()); + return 1; + } + ascii = ctrl('E'); break; + + case FL_BackSpace: + ascii = ctrl('H'); break; + case FL_Enter: + case FL_KP_Enter: + if (when() & FL_WHEN_ENTER_KEY) { + position(size(), 0); + maybe_do_callback(); + return 1; + } else if (input_type() == FL_MULTILINE_INPUT && !readonly()) + return replace(position(), mark(), "\n", 1); + else + return 0; // reserved for shortcuts + case FL_Tab: + if (Fl::event_state(FL_CTRL|FL_SHIFT) || input_type()!=FL_MULTILINE_INPUT || readonly()) return 0; + return replace(position(), mark(), &ascii, 1); +#ifdef __APPLE__ + case 'c' : + case 'v' : + case 'x' : + case 'z' : +// printf("'%c' (0x%02x) pressed with%s%s%s%s\n", ascii, ascii, +// Fl::event_state(FL_SHIFT) ? " FL_SHIFT" : "", +// Fl::event_state(FL_CTRL) ? " FL_CTRL" : "", +// Fl::event_state(FL_ALT) ? " FL_ALT" : "", +// Fl::event_state(FL_META) ? " FL_META" : ""); + if (Fl::event_state(FL_META)) ascii -= 0x60; +// printf("using '%c' (0x%02x)...\n", ascii, ascii); + break; +#endif // __APPLE__ + } + + int i; + switch (ascii) { + case ctrl('A'): + return shift_position(line_start(position())) + NORMAL_INPUT_MOVE; + case ctrl('B'): + return shift_position(position()-1) + NORMAL_INPUT_MOVE; + case ctrl('C'): // copy + return copy(1); + case ctrl('D'): + case ctrl('?'): + if (readonly()) { + fl_beep(); + return 1; + } + if (mark() != position()) return cut(); + else return cut(1); + case ctrl('E'): + return shift_position(line_end(position())) + NORMAL_INPUT_MOVE; + case ctrl('F'): + return shift_position(position()+1) + NORMAL_INPUT_MOVE; + case ctrl('H'): + if (readonly()) { + fl_beep(); + return 1; + } + if (mark() != position()) cut(); + else cut(-1); + return 1; + case ctrl('K'): + if (readonly()) { + fl_beep(); + return 1; + } + if (position()>=size()) return 0; + i = line_end(position()); + if (i == position() && i < size()) i++; + cut(position(), i); + return copy_cuts(); + case ctrl('N'): + i = position(); + if (line_end(i) >= size()) return NORMAL_INPUT_MOVE; + while (repeat_num--) { + i = line_end(i); + if (i >= size()) break; + i++; + } + shift_up_down_position(i); + return 1; + case ctrl('P'): + i = position(); + if (!line_start(i)) return NORMAL_INPUT_MOVE; + while(repeat_num--) { + i = line_start(i); + if (!i) break; + i--; + } + shift_up_down_position(line_start(i)); + return 1; + case ctrl('U'): + if (readonly()) { + fl_beep(); + return 1; + } + return cut(0, size()); + case ctrl('V'): + case ctrl('Y'): + if (readonly()) { + fl_beep(); + return 1; + } + Fl::paste(*this, 1); + return 1; + case ctrl('X'): + case ctrl('W'): + if (readonly()) { + fl_beep(); + return 1; + } + copy(1); + return cut(); + case ctrl('Z'): + case ctrl('_'): + if (readonly()) { + fl_beep(); + return 1; + } + return undo(); + case ctrl('I'): + case ctrl('J'): + case ctrl('L'): + case ctrl('M'): + if (readonly()) { + fl_beep(); + return 1; + } + // insert a few selected control characters literally: + if (input_type() != FL_FLOAT_INPUT && input_type() != FL_INT_INPUT) + return replace(position(), mark(), &ascii, 1); + } + + return 0; +} + +int Fl_Input::handle(int event) { + static int dnd_save_position, dnd_save_mark, drag_start = -1, newpos; + static Fl_Widget *dnd_save_focus; + switch (event) { + case FL_FOCUS: + switch (Fl::event_key()) { + case FL_Right: + position(0); + break; + case FL_Left: + position(size()); + break; + case FL_Down: + up_down_position(0); + break; + case FL_Up: + up_down_position(line_start(size())); + break; + case FL_Tab: + case 0xfe20: // XK_ISO_Left_Tab + position(size(),0); + break; + default: + position(position(),mark());// turns off the saved up/down arrow position + break; + } + break; + + case FL_KEYBOARD: + if (Fl::event_key() == FL_Tab && mark() != position()) { + // Set the current cursor position to the end of the selection... + if (mark() > position()) + position(mark()); + else + position(position()); + return (1); + } else { + if (active_r() && window() && this == Fl::belowmouse()) + window()->cursor(FL_CURSOR_NONE); + return handle_key(); + } + + case FL_PUSH: + if (Fl::dnd_text_ops()) { + int oldpos = position(), oldmark = mark(); + Fl_Boxtype b = box(); + Fl_Input_::handle_mouse( + x()+Fl::box_dx(b), y()+Fl::box_dy(b), + w()-Fl::box_dw(b), h()-Fl::box_dh(b), 0); + newpos = position(); + position( oldpos, oldmark ); + if (Fl::focus()==this && !Fl::event_state(FL_SHIFT) && input_type()!=FL_SECRET_INPUT && + (newpos >= mark() && newpos < position() || + newpos >= position() && newpos < mark())) { + // user clicked in the selection, may be trying to drag + drag_start = newpos; + return 1; + } + drag_start = -1; + } + + if (Fl::focus() != this) { + Fl::focus(this); + handle(FL_FOCUS); + } + break; + + case FL_DRAG: + if (Fl::dnd_text_ops()) { + if (drag_start >= 0) { + if (Fl::event_is_click()) return 1; // debounce the mouse + // save the position because sometimes we don't get DND_ENTER: + dnd_save_position = position(); + dnd_save_mark = mark(); + // drag the data: + copy(0); Fl::dnd(); + return 1; + } + } + break; + + case FL_RELEASE: + if (Fl::event_button() == 2) { + Fl::event_is_click(0); // stop double click from picking a word + Fl::paste(*this, 0); + } else if (!Fl::event_is_click()) { + // copy drag-selected text to the clipboard. + copy(0); + } else if (Fl::event_is_click() && drag_start >= 0) { + // user clicked in the field and wants to reset the cursor position... + position(drag_start, drag_start); + drag_start = -1; + } else if (Fl::event_clicks()) { + // user double or triple clicked to select word or whole text + copy(0); + } + + // For output widgets, do the callback so the app knows the user + // did something with the mouse... + if (readonly()) do_callback(); + + return 1; + + case FL_DND_ENTER: + Fl::belowmouse(this); // send the leave events first + dnd_save_position = position(); + dnd_save_mark = mark(); + dnd_save_focus = Fl::focus(); + if (dnd_save_focus != this) { + Fl::focus(this); + handle(FL_FOCUS); + } + // fall through: + case FL_DND_DRAG: + //int p = mouse_position(X, Y, W, H); +#if DND_OUT_XXXX + if (Fl::focus()==this && (p>=dnd_save_position && p<=dnd_save_mark || + p>=dnd_save_mark && p<=dnd_save_position)) { + position(dnd_save_position, dnd_save_mark); + return 0; + } +#endif + { + Fl_Boxtype b = box(); + Fl_Input_::handle_mouse( + x()+Fl::box_dx(b), y()+Fl::box_dy(b), + w()-Fl::box_dw(b), h()-Fl::box_dh(b), 0); + } + return 1; + + case FL_DND_LEAVE: + position(dnd_save_position, dnd_save_mark); +#if DND_OUT_XXXX + if (!focused()) +#endif + if (dnd_save_focus != this) { + Fl::focus(dnd_save_focus); + handle(FL_UNFOCUS); + } + return 1; + + case FL_DND_RELEASE: + take_focus(); + return 1; + + } + Fl_Boxtype b = box(); + return Fl_Input_::handletext(event, + x()+Fl::box_dx(b), y()+Fl::box_dy(b), + w()-Fl::box_dw(b), h()-Fl::box_dh(b)); +} + +Fl_Input::Fl_Input(int X, int Y, int W, int H, const char *l) +: Fl_Input_(X, Y, W, H, l) { +} + +// +// End of "$Id: Fl_Input.cxx 6103 2008-04-21 20:42:51Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Input_.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Input_.cxx new file mode 100644 index 000000000..e0458a082 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Input_.cxx @@ -0,0 +1,907 @@ +// +// "$Id: Fl_Input_.cxx 6104 2008-04-21 20:54:37Z matt $" +// +// Common input widget routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2006 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// This is the base class for Fl_Input. You can use it directly +// if you are one of those people who like to define their own +// set of editing keys. It may also be useful for adding scrollbars +// to the input field. + +#include +#include +#include +#include +#include +#include +#include "flstring.h" +#include +#include + +#define MAXBUF 1024 + +extern void fl_draw(const char*, int, float, float); + +//////////////////////////////////////////////////////////////// + +// Copy string p..e to the buffer, replacing characters with ^X and \nnn +// as necessary. Truncate if necessary so the resulting string and +// null terminator fits in a buffer of size n. Return new end pointer. +const char* Fl_Input_::expand(const char* p, char* buf) const { + char* o = buf; + char* e = buf+(MAXBUF-4); + const char* lastspace = p; + char* lastspace_out = o; + int width_to_lastspace = 0; + int word_count = 0; + int word_wrap; + + if (input_type()==FL_SECRET_INPUT) { + while (o= value_+size_ || isspace(*p & 255))) { + word_wrap = w() - Fl::box_dw(box()) - 2; + width_to_lastspace += (int)fl_width(lastspace_out, o-lastspace_out); + if (p > lastspace+1) { + if (word_count && width_to_lastspace > word_wrap) { + p = lastspace; o = lastspace_out; break; + } + word_count++; + } + lastspace = p; + lastspace_out = o; + } + + if (p >= value_+size_) break; + int c = *p++ & 255; + if (c < ' ' || c == 127) { + if (c=='\n' && input_type()==FL_MULTILINE_INPUT) {p--; break;} + if (c == '\t' && input_type()==FL_MULTILINE_INPUT) { + for (c = (o-buf)%8; c<8 && o= 128 && c < 0xA0) { + // these codes are not defined in ISO code, so we output the octal code instead + // *o++ = '\\'; + // *o++ = ((c>>6)&0x03) + '0'; + // *o++ = ((c>>3)&0x07) + '0'; + // *o++ = (c&0x07) + '0'; + } else if (c == 0xA0) { // nbsp + *o++ = ' '; +#endif + } else { + *o++ = c; + } + } + *o = 0; + return p; +} + +// After filling in such a buffer, find the width to e +double Fl_Input_::expandpos( + const char* p, // real string + const char* e, // pointer into real string + const char* buf, // conversion of real string by expand() + int* returnn // return offset into buf here +) const { + int n = 0; + if (input_type()==FL_SECRET_INPUT) n = e-p; + else while (p= 128 && c < 0xA0) { + // these codes are not defined in ISO code, so we output the octal code instead + // n += 4; +#endif + } else { + n++; + } + } + if (returnn) *returnn = n; + return fl_width(buf, n); +} + +//////////////////////////////////////////////////////////////// + +// minimal update: +// Characters from mu_p to end of widget are redrawn. +// If erase_cursor_only, small part at mu_p is redrawn. +// Right now minimal update just keeps unchanged characters from +// being erased, so they don't blink. + +void Fl_Input_::minimal_update(int p) { + if (damage() & FL_DAMAGE_ALL) return; // don't waste time if it won't be done + if (damage() & FL_DAMAGE_EXPOSE) { + if (p < mu_p) mu_p = p; + } else { + mu_p = p; + } + + damage(FL_DAMAGE_EXPOSE); + erase_cursor_only = 0; +} + +void Fl_Input_::minimal_update(int p, int q) { + if (q < p) p = q; + minimal_update(p); +} + +//////////////////////////////////////////////////////////////// + +static double up_down_pos; +static int was_up_down; + +void Fl_Input_::setfont() const { + fl_font(textfont(), textsize()); +} + +void Fl_Input_::drawtext(int X, int Y, int W, int H) { + int do_mu = !(damage()&FL_DAMAGE_ALL); + + if (Fl::focus()!=this && !size()) { + if (do_mu) { // we have to erase it if cursor was there + draw_box(box(), X-Fl::box_dx(box()), Y-Fl::box_dy(box()), + W+Fl::box_dw(box()), H+Fl::box_dh(box()), color()); + } + return; + } + + int selstart, selend; + if (Fl::focus()!=this && /*Fl::selection_owner()!=this &&*/ Fl::pushed()!=this) + selstart = selend = 0; + else if (position() <= mark()) { + selstart = position(); selend = mark(); + } else { + selend = position(); selstart = mark(); + } + + setfont(); + const char *p, *e; + char buf[MAXBUF]; + + // count how many lines and put the last one into the buffer: + // And figure out where the cursor is: + int height = fl_height(); + int lines; + int curx, cury; + for (p=value(), curx=cury=lines=0; ;) { + e = expand(p, buf); + if (position() >= p-value() && position() <= e-value()) { + curx = int(expandpos(p, value()+position(), buf, 0)+.5); + if (Fl::focus()==this && !was_up_down) up_down_pos = curx; + cury = lines*height; + int newscroll = xscroll_; + if (curx > newscroll+W-20) { + // figure out scrolling so there is space after the cursor: + newscroll = curx+20-W; + // figure out the furthest left we ever want to scroll: + int ex = int(expandpos(p, e, buf, 0))+2-W; + // use minimum of both amounts: + if (ex < newscroll) newscroll = ex; + } else if (curx < newscroll+20) { + newscroll = curx-20; + } + if (newscroll < 0) newscroll = 0; + if (newscroll != xscroll_) { + xscroll_ = newscroll; + mu_p = 0; erase_cursor_only = 0; + } + } + lines++; + if (e >= value_+size_) break; + p = e+1; + } + + // adjust the scrolling: + if (input_type()==FL_MULTILINE_INPUT) { + int newy = yscroll_; + if (cury < newy) newy = cury; + if (cury > newy+H-height) newy = cury-H+height; + if (newy < -1) newy = -1; + if (newy != yscroll_) {yscroll_ = newy; mu_p = 0; erase_cursor_only = 0;} + } else { + yscroll_ = -(H-height)/2; + } + + fl_clip(X, Y, W, H); + Fl_Color tc = active_r() ? textcolor() : fl_inactive(textcolor()); + + p = value(); + // visit each line and draw it: + int desc = height-fl_descent(); + float xpos = (float)(X - xscroll_ + 1); + int ypos = -yscroll_; + for (; ypos < H;) { + + // re-expand line unless it is the last one calculated above: + if (lines>1) e = expand(p, buf); + + if (ypos <= -height) goto CONTINUE; // clipped off top + + if (do_mu) { // for minimal update: + const char* pp = value()+mu_p; // pointer to where minimal update starts + if (e < pp) goto CONTINUE2; // this line is before the changes + if (readonly()) erase_cursor_only = 0; // this isn't the most efficient way + if (erase_cursor_only && p > pp) goto CONTINUE2; // this line is after + // calculate area to erase: + float r = (float)(X+W); + float xx; + if (p >= pp) { + xx = (float)X; + if (erase_cursor_only) r = xpos+2; + else if (readonly()) xx -= 3; + } else { + xx = xpos + (float)expandpos(p, pp, buf, 0); + if (erase_cursor_only) r = xx+2; + else if (readonly()) xx -= 3; + } + // clip to and erase it: + fl_push_clip((int)xx-1-height/8, Y+ypos, (int)(r-xx+2+height/4), height); + draw_box(box(), X-Fl::box_dx(box()), Y-Fl::box_dy(box()), + W+Fl::box_dw(box()), H+Fl::box_dh(box()), color()); + // it now draws entire line over it + // this should not draw letters to left of erased area, but + // that is nyi. + } + + // Draw selection area if required: + if (selstart < selend && selstart <= e-value() && selend > p-value()) { + const char* pp = value()+selstart; + float x1 = xpos; + int offset1 = 0; + if (pp > p) { + fl_color(tc); + x1 += (float)expandpos(p, pp, buf, &offset1); + fl_draw(buf, offset1, xpos, (float)(Y+ypos+desc)); + } + pp = value()+selend; + float x2 = (float)(X+W); + int offset2; + if (pp <= e) x2 = xpos + (float)expandpos(p, pp, buf, &offset2); + else offset2 = strlen(buf); + fl_color(selection_color()); + fl_rectf((int)(x1+0.5), Y+ypos, (int)(x2-x1+0.5), height); + fl_color(fl_contrast(textcolor(), selection_color())); + fl_draw(buf+offset1, offset2-offset1, x1, (float)(Y+ypos+desc)); + if (pp < e) { + fl_color(tc); + fl_draw(buf+offset2, strlen(buf+offset2), x2, (float)(Y+ypos+desc)); + } + } else { + // draw unselected text + fl_color(tc); + fl_draw(buf, strlen(buf), xpos, (float)(Y+ypos+desc)); + } + + if (do_mu) fl_pop_clip(); + + CONTINUE2: + // draw the cursor: + if (Fl::focus() == this && selstart == selend && + position() >= p-value() && position() <= e-value()) { + fl_color(cursor_color()); + if (readonly()) { + fl_line((int)(xpos+curx-2.5f), Y+ypos+height-1, + (int)(xpos+curx+0.5f), Y+ypos+height-4, + (int)(xpos+curx+3.5f), Y+ypos+height-1); + } else { + fl_rectf((int)(xpos+curx+0.5), Y+ypos, 2, height); + } + } + + CONTINUE: + ypos += height; + if (e >= value_+size_) break; + if (*e == '\n' || *e == ' ') e++; + p = e; + } + + // for minimal update, erase all lines below last one if necessary: + if (input_type()==FL_MULTILINE_INPUT && do_mu && ypos= size() || !isword(index(i))) +// while (i > 0 && !isword(index(i-1))) i--; + while (i > 0 && isword(index(i-1))) i--; + return i; +} + +int Fl_Input_::line_end(int i) const { + if (input_type() != FL_MULTILINE_INPUT) return size(); + + if (wrap()) { + // go to the start of the paragraph: + int j = i; + while (j > 0 && index(j-1) != '\n') j--; + // now measure lines until we get past i, end of that line is real eol: + setfont(); + for (const char* p=value()+j; ;) { + char buf[MAXBUF]; + p = expand(p, buf); + if (p-value() >= i) return p-value(); + p++; + } + } else { + while (i < size() && index(i) != '\n') i++; + return i; + } +} + +int Fl_Input_::line_start(int i) const { + if (input_type() != FL_MULTILINE_INPUT) return 0; + int j = i; + while (j > 0 && index(j-1) != '\n') j--; + if (wrap()) { + // now measure lines until we get past i, start of that line is real eol: + setfont(); + for (const char* p=value()+j; ;) { + char buf[MAXBUF]; + const char* e = expand(p, buf); + if (e-value() >= i) return p-value(); + p = e+1; + } + } else return j; +} + +void Fl_Input_::handle_mouse(int X, int Y, int /*W*/, int /*H*/, int drag) { + was_up_down = 0; + if (!size()) return; + setfont(); + + const char *p, *e; + char buf[MAXBUF]; + + int theline = (input_type()==FL_MULTILINE_INPUT) ? + (Fl::event_y()-Y+yscroll_)/fl_height() : 0; + + int newpos = 0; + for (p=value();; ) { + e = expand(p, buf); + theline--; if (theline < 0) break; + if (e >= value_+size_) break; + p = e+1; + } + const char *l, *r, *t; double f0 = Fl::event_x()-X+xscroll_; + for (l = p, r = e; l= newmark) { + if (newpos == newmark) { + if (newpos < size()) newpos++; + else newmark--; + } + if (Fl::event_clicks() > 1) { + newpos = line_end(newpos); + newmark = line_start(newmark); + } else { + newpos = word_end(newpos); + newmark = word_start(newmark); + } + } else { + if (Fl::event_clicks() > 1) { + newpos = line_start(newpos); + newmark = line_end(newmark); + } else { + newpos = word_start(newpos); + newmark = word_end(newmark); + } + } + // if the multiple click does not increase the selection, revert + // to single-click behavior: + if (!drag && (mark() > position() ? + (newmark >= position() && newpos <= mark()) : + (newmark >= mark() && newpos <= position()))) { + Fl::event_clicks(0); + newmark = newpos = l-value(); + } + } + position(newpos, newmark); +} + +int Fl_Input_::position(int p, int m) { + was_up_down = 0; + if (p<0) p = 0; + if (p>size()) p = size(); + if (m<0) m = 0; + if (m>size()) m = size(); + if (p == position_ && m == mark_) return 0; + //if (Fl::selection_owner() == this) Fl::selection_owner(0); + if (p != m) { + if (p != position_) minimal_update(position_, p); + if (m != mark_) minimal_update(mark_, m); + } else { + // new position is a cursor + if (position_ == mark_) { + // old position was just a cursor + if (Fl::focus() == this && !(damage()&FL_DAMAGE_EXPOSE)) { + minimal_update(position_); erase_cursor_only = 1; + } + } else { // old position was a selection + minimal_update(position_, mark_); + } + } + position_ = p; + mark_ = m; + return 1; +} + +int Fl_Input_::up_down_position(int i, int keepmark) { + // unlike before, i must be at the start of the line already! + + setfont(); + char buf[MAXBUF]; + const char* p = value()+i; + const char* e = expand(p, buf); + const char *l, *r, *t; + for (l = p, r = e; l e) {b = mark(); e = position();} + if (input_type() == FL_SECRET_INPUT) e = b; + Fl::copy(value()+b, e-b, clipboard); + return 1; + } + return 0; +} + +#define MAXFLOATSIZE 40 + +static char* undobuffer; +static int undobufferlength; +static Fl_Input_* undowidget; +static int undoat; // points after insertion +static int undocut; // number of characters deleted there +static int undoinsert; // number of characters inserted +static int yankcut; // length of valid contents of buffer, even if undocut=0 + +static void undobuffersize(int n) { + if (n > undobufferlength) { + if (undobuffer) { + do {undobufferlength *= 2;} while (undobufferlength < n); + undobuffer = (char*)realloc(undobuffer, undobufferlength); + } else { + undobufferlength = n+9; + undobuffer = (char*)malloc(undobufferlength); + } + } +} + +// all changes go through here, delete characters b-e and insert text: +int Fl_Input_::replace(int b, int e, const char* text, int ilen) { + + was_up_down = 0; + + if (b<0) b = 0; + if (e<0) e = 0; + if (b>size_) b = size_; + if (e>size_) e = size_; + if (e maximum_size_) { + ilen = maximum_size_-size_+(e-b); + if (ilen < 0) ilen = 0; + } + + put_in_buffer(size_+ilen); + + if (e>b) { + if (undowidget == this && b == undoat) { + undobuffersize(undocut+(e-b)); + memcpy(undobuffer+undocut, value_+b, e-b); + undocut += e-b; + } else if (undowidget == this && e == undoat && !undoinsert) { + undobuffersize(undocut+(e-b)); + memmove(undobuffer+(e-b), undobuffer, undocut); + memcpy(undobuffer, value_+b, e-b); + undocut += e-b; + } else if (undowidget == this && e == undoat && (e-b) 0 && !isspace(index(b) & 255) && index(b)!='\n') b--; + else + while (b > 0 && index(b)!='\n') b--; + } + + // make sure we redraw the old selection or cursor: + if (mark_ < b) b = mark_; + if (position_ < b) b = position_; + + minimal_update(b); + + mark_ = position_ = undoat; + + set_changed(); + if (when()&FL_WHEN_CHANGED) do_callback(); + return 1; +} + +int Fl_Input_::undo() { + was_up_down = 0; + if (undowidget != this || !undocut && !undoinsert) return 0; + + int ilen = undocut; + int xlen = undoinsert; + int b = undoat-xlen; + int b1 = b; + + put_in_buffer(size_+ilen); + + if (ilen) { + memmove(buffer+b+ilen, buffer+b, size_-b+1); + memcpy(buffer+b, undobuffer, ilen); + size_ += ilen; + b += ilen; + } + + if (xlen) { + undobuffersize(xlen); + memcpy(undobuffer, buffer+b, xlen); + memmove(buffer+b, buffer+b+xlen, size_-xlen-b+1); + size_ -= xlen; + } + + undocut = xlen; + if (xlen) yankcut = xlen; + undoinsert = ilen; + undoat = b; + mark_ = b /* -ilen */; + position_ = b; + + if (wrap()) + while (b1 > 0 && index(b1)!='\n') b1--; + minimal_update(b1); + set_changed(); + if (when()&FL_WHEN_CHANGED) do_callback(); + return 1; +} + +int Fl_Input_::copy_cuts() { + // put the yank buffer into the X clipboard + if (!yankcut || input_type()==FL_SECRET_INPUT) return 0; + Fl::copy(undobuffer, yankcut, 1); + return 1; +} + +void Fl_Input_::maybe_do_callback() { + if (changed() || (when()&FL_WHEN_NOT_CHANGED)) { + do_callback(); + } +} + +int Fl_Input_::handletext(int event, int X, int Y, int W, int H) { + switch (event) { + + case FL_ENTER: + case FL_MOVE: + if (active_r() && window()) window()->cursor(FL_CURSOR_INSERT); + return 1; + + case FL_LEAVE: + if (active_r() && window()) window()->cursor(FL_CURSOR_DEFAULT); + return 1; + + case FL_FOCUS: + if (mark_ == position_) { + minimal_update(size()+1); + } else //if (Fl::selection_owner() != this) + minimal_update(mark_, position_); + return 1; + + case FL_UNFOCUS: + if (active_r() && window()) window()->cursor(FL_CURSOR_DEFAULT); + if (mark_ == position_) { + if (!(damage()&FL_DAMAGE_EXPOSE)) {minimal_update(position_); erase_cursor_only = 1;} + } else //if (Fl::selection_owner() != this) + minimal_update(mark_, position_); + case FL_HIDE: + if (!readonly() && (when() & FL_WHEN_RELEASE)) + maybe_do_callback(); + return 1; + + case FL_PUSH: + if (active_r() && window()) window()->cursor(FL_CURSOR_INSERT); + + handle_mouse(X, Y, W, H, Fl::event_state(FL_SHIFT)); + + if (Fl::focus() != this) { + Fl::focus(this); + handle(FL_FOCUS); + } + return 1; + + case FL_DRAG: + handle_mouse(X, Y, W, H, 1); + return 1; + + case FL_RELEASE: + copy(0); + return 1; + + case FL_PASTE: { + // Don't allow pastes into readonly widgets... + if (readonly()) { + fl_beep(FL_BEEP_ERROR); + return 1; + } + + // See if we have anything to paste... + if (!Fl::event_text() || !Fl::event_length()) return 1; + + // strip trailing control characters and spaces before pasting: + const char* t = Fl::event_text(); + const char* e = t+Fl::event_length(); + if (input_type() != FL_MULTILINE_INPUT) while (e > t && isspace(*(e-1) & 255)) e--; + if (!t || e <= t) return 1; // Int/float stuff will crash without this test + if (input_type() == FL_INT_INPUT) { + while (isspace(*t & 255) && t < e) t ++; + const char *p = t; + if (*p == '+' || *p == '-') p ++; + if (strncmp(p, "0x", 2) == 0) { + p += 2; + while (isxdigit(*p & 255) && p < e) p ++; + } else { + while (isdigit(*p & 255) && p < e) p ++; + } + if (p < e) { + fl_beep(FL_BEEP_ERROR); + return 1; + } else return replace(0, size(), t, e - t); + } else if (input_type() == FL_FLOAT_INPUT) { + while (isspace(*t & 255) && t < e) t ++; + const char *p = t; + if (*p == '+' || *p == '-') p ++; + while (isdigit(*p & 255) && p < e) p ++; + if (*p == '.') { + p ++; + while (isdigit(*p & 255) && p < e) p ++; + if (*p == 'e' || *p == 'E') { + p ++; + if (*p == '+' || *p == '-') p ++; + while (isdigit(*p & 255) && p < e) p ++; + } + } + if (p < e) { + fl_beep(FL_BEEP_ERROR); + return 1; + } else return replace(0, size(), t, e - t); + } + return replace(position(), mark(), t, e-t);} + + default: + return 0; + } +} + +/*------------------------------*/ + +Fl_Input_::Fl_Input_(int X, int Y, int W, int H, const char* l) +: Fl_Widget(X, Y, W, H, l) { + box(FL_DOWN_BOX); + color(FL_BACKGROUND2_COLOR, FL_SELECTION_COLOR); + align(FL_ALIGN_LEFT); + textsize_ = (uchar)FL_NORMAL_SIZE; + textfont_ = FL_HELVETICA; + textcolor_ = FL_FOREGROUND_COLOR; + cursor_color_ = FL_FOREGROUND_COLOR; // was FL_BLUE + mark_ = position_ = size_ = 0; + bufsize = 0; + buffer = 0; + value_ = ""; + xscroll_ = yscroll_ = 0; + maximum_size_ = 32767; +} + +void Fl_Input_::put_in_buffer(int len) { + if (value_ == buffer && bufsize > len) { + buffer[size_] = 0; + return; + } + if (!bufsize) { + if (len > size_) len += 9; // let a few characters insert before realloc + bufsize = len+1; + buffer = (char*)malloc(bufsize); + } else if (bufsize <= len) { + // we may need to move old value in case it points into buffer: + int moveit = (value_ >= buffer && value_ < buffer+bufsize); + // enlarge current buffer + if (len > size_) { + do {bufsize *= 2;} while (bufsize <= len); + } else { + bufsize = len+1; + } + // Note: the following code is equivalent to: + // + // if (moveit) value_ = value_ - buffer; + // char* nbuffer = (char*)realloc(buffer, bufsize); + // if (moveit) value_ = value_ + nbuffer; + // buffer = nbuffer; + // + // We just optimized the pointer arithmetic for value_... + // + char* nbuffer = (char*)realloc(buffer, bufsize); + if (moveit) value_ += (nbuffer-buffer); + buffer = nbuffer; + } + memmove(buffer, value_, size_); buffer[size_] = 0; + value_ = buffer; +} + +int Fl_Input_::static_value(const char* str, int len) { + clear_changed(); + if (undowidget == this) undowidget = 0; + if (str == value_ && len == size_) return 0; + if (len) { // non-empty new value: + if (xscroll_ || yscroll_) { + xscroll_ = yscroll_ = 0; + minimal_update(0); + } else { + int i = 0; + // find first different character: + if (value_) { + for (; i +#include +#include +#include "flstring.h" + +void Fl_Light_Button::draw() { + if (box()) draw_box(this==Fl::pushed() ? fl_down(box()) : box(), color()); + Fl_Color col = value() ? (active_r() ? selection_color() : + fl_inactive(selection_color())) : color(); + int W; + int dx, dy; + + W = labelsize(); + dx = Fl::box_dx(box()) + 2; + dy = (h() - W) / 2; + // if (dy < 0) dy = 0; // neg. offset o.k. for vertical centering + + if (down_box()) { + // draw other down_box() styles: + switch (down_box()) { + case FL_DOWN_BOX : + case FL_UP_BOX : + case _FL_PLASTIC_DOWN_BOX : + case _FL_PLASTIC_UP_BOX : + // Check box... + draw_box(down_box(), x()+dx, y()+dy, W, W, FL_BACKGROUND2_COLOR); + if (value()) { + if (Fl::scheme() && !strcmp(Fl::scheme(), "gtk+")) { + fl_color(FL_SELECTION_COLOR); + } else { + fl_color(col); + } + int tx = x() + dx + 3; + int tw = W - 6; + int d1 = tw/3; + int d2 = tw-d1; + int ty = y() + dy + (W+d2)/2-d1-2; + for (int n = 0; n < 3; n++, ty++) { + fl_line(tx, ty, tx+d1, ty+d1); + fl_line(tx+d1, ty+d1, tx+tw-1, ty+d1-d2+1); + } + } + break; + case _FL_ROUND_DOWN_BOX : + case _FL_ROUND_UP_BOX : + // Radio button... + draw_box(down_box(), x()+dx, y()+dy, W, W, FL_BACKGROUND2_COLOR); + if (value()) { + int tW = (W - Fl::box_dw(down_box())) / 2 + 1; + if ((W - tW) & 1) tW++; // Make sure difference is even to center + int tdx = dx + (W - tW) / 2; + int tdy = dy + (W - tW) / 2; + + if (Fl::scheme() && !strcmp(Fl::scheme(), "gtk+")) { + fl_color(FL_SELECTION_COLOR); + tW --; + fl_pie(x() + tdx - 1, y() + tdy - 1, tW + 3, tW + 3, 0.0, 360.0); + fl_arc(x() + tdx - 1, y() + tdy - 1, tW + 3, tW + 3, 0.0, 360.0); + fl_color(fl_color_average(FL_WHITE, FL_SELECTION_COLOR, 0.2f)); + } else fl_color(col); + + switch (tW) { + // Larger circles draw fine... + default : + fl_pie(x() + tdx, y() + tdy, tW, tW, 0.0, 360.0); + break; + + // Small circles don't draw well on many systems... + case 6 : + fl_rectf(x() + tdx + 2, y() + tdy, tW - 4, tW); + fl_rectf(x() + tdx + 1, y() + tdy + 1, tW - 2, tW - 2); + fl_rectf(x() + tdx, y() + tdy + 2, tW, tW - 4); + break; + + case 5 : + case 4 : + case 3 : + fl_rectf(x() + tdx + 1, y() + tdy, tW - 2, tW); + fl_rectf(x() + tdx, y() + tdy + 1, tW, tW - 2); + break; + + case 2 : + case 1 : + fl_rectf(x() + tdx, y() + tdy, tW, tW); + break; + } + + if (Fl::scheme() && !strcmp(Fl::scheme(), "gtk+")) { + fl_color(fl_color_average(FL_WHITE, FL_SELECTION_COLOR, 0.5)); + fl_arc(x() + tdx, y() + tdy, tW + 1, tW + 1, 60.0, 180.0); + } + } + break; + default : + draw_box(down_box(), x()+dx, y()+dy, W, W, col); + break; + } + } else { + // if down_box() is zero, draw light button style: + int hh = h()-2*dy - 2; + int ww = W/2+1; + int xx = dx; + if (w() +#include +#include +#include +#include +#include "flstring.h" + +#ifdef __APPLE__ +# include +#endif + +int Fl_Menu_Item::size() const { + const Fl_Menu_Item* m = this; + int nest = 0; + for (;;) { + if (!m->text) { + if (!nest) return (m-this+1); + nest--; + } else if (m->flags & FL_SUBMENU) { + nest++; + } + m++; + } +} + +const Fl_Menu_Item* Fl_Menu_Item::next(int n) const { + if (n < 0) return 0; // this is so selected==-1 returns NULL + const Fl_Menu_Item* m = this; + int nest = 0; + if (!m->visible()) n++; + while (n>0) { + if (!m->text) { + if (!nest) return m; + nest--; + } else if (m->flags&FL_SUBMENU) { + nest++; + } + m++; + if (!nest && m->visible()) n--; + } + return m; +} + +// appearance of current menus are pulled from this parent widget: +static const Fl_Menu_* button; + +//////////////////////////////////////////////////////////////// + +// tiny window for title of menu: +class menutitle : public Fl_Menu_Window { + void draw(); +public: + const Fl_Menu_Item* menu; + menutitle(int X, int Y, int W, int H, const Fl_Menu_Item*); +}; + +// each vertical menu has one of these: +class menuwindow : public Fl_Menu_Window { + void draw(); + void drawentry(const Fl_Menu_Item*, int i, int erase); +public: + menutitle* title; + int handle(int); +#ifdef __APPLE__ + int early_hide_handle(int); +#endif + int itemheight; // zero == menubar + int numitems; + int selected; + int drawn_selected; // last redraw has this selected + const Fl_Menu_Item* menu; + menuwindow(const Fl_Menu_Item* m, int X, int Y, int W, int H, + const Fl_Menu_Item* picked, const Fl_Menu_Item* title, + int menubar = 0, int menubar_title = 0, int right_edge = 0); + ~menuwindow(); + void set_selected(int); + int find_selected(int mx, int my); + int titlex(int); + void autoscroll(int); + void position(int x, int y); + int is_inside(int x, int y); +}; + +#define LEADING 4 // extra vertical leading + +extern char fl_draw_shortcut; + +// width of label, including effect of & characters: +int Fl_Menu_Item::measure(int* hp, const Fl_Menu_* m) const { + Fl_Label l; + l.value = text; + l.image = 0; + l.deimage = 0; + l.type = labeltype_; + l.font = labelsize_ || labelfont_ ? labelfont_ : uchar(m ? m->textfont() : FL_HELVETICA); + l.size = labelsize_ ? labelsize_ : m ? m->textsize() : (uchar)FL_NORMAL_SIZE; + l.color = FL_FOREGROUND_COLOR; // this makes no difference? + fl_draw_shortcut = 1; + int w = 0; int h = 0; + l.measure(w, hp ? *hp : h); + fl_draw_shortcut = 0; + if (flags & (FL_MENU_TOGGLE|FL_MENU_RADIO)) w += 14; + return w; +} + +void Fl_Menu_Item::draw(int x, int y, int w, int h, const Fl_Menu_* m, + int selected) const { + Fl_Label l; + l.value = text; + l.image = 0; + l.deimage = 0; + l.type = labeltype_; + l.font = labelsize_ || labelfont_ ? labelfont_ : uchar(m ? m->textfont() : FL_HELVETICA); + l.size = labelsize_ ? labelsize_ : m ? m->textsize() : (uchar)FL_NORMAL_SIZE; + l.color = labelcolor_ ? labelcolor_ : m ? m->textcolor() : int(FL_FOREGROUND_COLOR); + if (!active()) l.color = fl_inactive((Fl_Color)l.color); + Fl_Color color = m ? m->color() : FL_GRAY; + if (selected) { + Fl_Color r = m ? m->selection_color() : FL_SELECTION_COLOR; + Fl_Boxtype b = m && m->down_box() ? m->down_box() : FL_FLAT_BOX; + if (fl_contrast(r,color)!=r) { // back compatability boxtypes + if (selected == 2) { // menu title + r = color; + b = m ? m->box() : FL_UP_BOX; + } else { + r = (Fl_Color)(FL_COLOR_CUBE-1); // white + l.color = fl_contrast((Fl_Color)labelcolor_, r); + } + } else { + l.color = fl_contrast((Fl_Color)labelcolor_, r); + } + if (selected == 2) { // menu title + fl_draw_box(b, x, y, w, h, r); + x += 3; + w -= 8; + } else { + fl_draw_box(b, x+1, y-(LEADING-2)/2, w-2, h+(LEADING-2), r); + } + } + + if (flags & (FL_MENU_TOGGLE|FL_MENU_RADIO)) { + int d = (h - FL_NORMAL_SIZE + 1) / 2; + int W = h - 2 * d; + + if (flags & FL_MENU_RADIO) { + fl_draw_box(FL_ROUND_DOWN_BOX, x+2, y+d, W, W, FL_BACKGROUND2_COLOR); + if (value()) { + int tW = (W - Fl::box_dw(FL_ROUND_DOWN_BOX)) / 2 + 1; + if ((W - tW) & 1) tW++; // Make sure difference is even to center + int td = Fl::box_dx(FL_ROUND_DOWN_BOX) + 1; + if (Fl::scheme()) { + // Offset the radio circle... + td ++; + + if (!strcmp(Fl::scheme(), "gtk+")) { + fl_color(FL_SELECTION_COLOR); + tW --; + fl_pie(x + td + 1, y + d + td - 1, tW + 3, tW + 3, 0.0, 360.0); + fl_arc(x + td + 1, y + d + td - 1, tW + 3, tW + 3, 0.0, 360.0); + fl_color(fl_color_average(FL_WHITE, FL_SELECTION_COLOR, 0.2f)); + } else fl_color(labelcolor_); + } else fl_color(labelcolor_); + + switch (tW) { + // Larger circles draw fine... + default : + fl_pie(x + td + 2, y + d + td, tW, tW, 0.0, 360.0); + break; + + // Small circles don't draw well on many systems... + case 6 : + fl_rectf(x + td + 4, y + d + td, tW - 4, tW); + fl_rectf(x + td + 3, y + d + td + 1, tW - 2, tW - 2); + fl_rectf(x + td + 2, y + d + td + 2, tW, tW - 4); + break; + + case 5 : + case 4 : + case 3 : + fl_rectf(x + td + 3, y + d + td, tW - 2, tW); + fl_rectf(x + td + 2, y + d + td + 1, tW, tW - 2); + break; + + case 2 : + case 1 : + fl_rectf(x + td + 2, y + d + td, tW, tW); + break; + } + + if (Fl::scheme() && !strcmp(Fl::scheme(), "gtk+")) { + fl_color(fl_color_average(FL_WHITE, FL_SELECTION_COLOR, 0.5)); + fl_arc(x + td + 2, y + d + td, tW + 1, tW + 1, 60.0, 180.0); + } + } + } else { + fl_draw_box(FL_DOWN_BOX, x+2, y+d, W, W, FL_BACKGROUND2_COLOR); + if (value()) { + if (Fl::scheme() && !strcmp(Fl::scheme(), "gtk+")) { + fl_color(FL_SELECTION_COLOR); + } else { + fl_color(labelcolor_); + } + int tx = x + 5; + int tw = W - 6; + int d1 = tw/3; + int d2 = tw-d1; + int ty = y + d + (W+d2)/2-d1-2; + for (int n = 0; n < 3; n++, ty++) { + fl_line(tx, ty, tx+d1, ty+d1); + fl_line(tx+d1, ty+d1, tx+tw-1, ty+d1-d2+1); + } + } + } + x += W + 3; + w -= W + 3; + } + + if (!fl_draw_shortcut) fl_draw_shortcut = 1; + l.draw(x+3, y, w>6 ? w-6 : 0, h, FL_ALIGN_LEFT); + fl_draw_shortcut = 0; +} + +menutitle::menutitle(int X, int Y, int W, int H, const Fl_Menu_Item* L) : + Fl_Menu_Window(X, Y, W, H, 0) { + end(); + set_modal(); + clear_border(); + menu = L; + if (L->labelcolor_ || Fl::scheme() || L->labeltype_ > FL_NO_LABEL) clear_overlay(); +} + +menuwindow::menuwindow(const Fl_Menu_Item* m, int X, int Y, int Wp, int Hp, + const Fl_Menu_Item* picked, const Fl_Menu_Item* t, + int menubar, int menubar_title, int right_edge) + : Fl_Menu_Window(X, Y, Wp, Hp, 0) +{ + int scr_x, scr_y, scr_w, scr_h; + int tx = X, ty = Y; + + Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h); + if (!right_edge || right_edge > scr_x+scr_w) right_edge = scr_x+scr_w; + + end(); + set_modal(); + clear_border(); + menu = m; + if (m) m = m->first(); // find the first item that needs to be rendered + drawn_selected = -1; + if (button) { + box(button->box()); + if (box() == FL_NO_BOX || box() == FL_FLAT_BOX) box(FL_UP_BOX); + } else { + box(FL_UP_BOX); + } + color(button && !Fl::scheme() ? button->color() : FL_GRAY); + selected = -1; + {int j = 0; + if (m) for (const Fl_Menu_Item* m1=m; ; m1 = m1->next(), j++) { + if (picked) { + if (m1 == picked) {selected = j; picked = 0;} + else if (m1 > picked) {selected = j-1; picked = 0; Wp = Hp = 0;} + } + if (!m1->text) break; + } + numitems = j;} + + if (menubar) { + itemheight = 0; + title = 0; + return; + } + + itemheight = 1; + + int hotKeysw = 0; + int Wtitle = 0; + int Htitle = 0; + if (t) Wtitle = t->measure(&Htitle, button) + 12; + int W = 0; + if (m) for (; m->text; m = m->next()) { + int hh; int w1 = m->measure(&hh, button); + if (hh+LEADING>itemheight) itemheight = hh+LEADING; + if (m->flags&(FL_SUBMENU|FL_SUBMENU_POINTER)) w1 += 14; + if (w1 > W) W = w1; + if (m->shortcut_) { + w1 = int(fl_width(fl_shortcut_label(m->shortcut_))) + 8; + if (w1 > hotKeysw) hotKeysw = w1; + } + if (m->labelcolor_ || Fl::scheme() || m->labeltype_ > FL_NO_LABEL) clear_overlay(); + } + if (selected >= 0 && !Wp) X -= W/2; + int BW = Fl::box_dx(box()); + W += hotKeysw+2*BW+7; + if (Wp > W) W = Wp; + if (Wtitle > W) W = Wtitle; + + if (X < scr_x) X = scr_x; if (X > scr_x+scr_w-W) X= scr_x+scr_w-W; + x(X); w(W); + h((numitems ? itemheight*numitems-LEADING : 0)+2*BW+3); + if (selected >= 0) + Y = Y+(Hp-itemheight)/2-selected*itemheight-BW; + else { + Y = Y+Hp; + // if the menu hits the bottom of the screen, we try to draw + // it above the menubar instead. We will not adjust any menu + // that has a selected item. + if (Y+h()>scr_y+scr_h && Y-h()>=scr_y) { + if (Hp>1) + // if we know the height of the Fl_Menu_, use it + Y = Y-Hp-h(); + else if (t) + // assume that the menubar item height relates to the first + // menuitem as well + Y = Y-itemheight-h()-Fl::box_dh(box()); + else + // draw the menu to the right + Y = Y-h()+itemheight+Fl::box_dy(box()); + } + } + if (m) y(Y); else {y(Y-2); w(1); h(1);} + + if (t) { + if (menubar_title) { + int dy = Fl::box_dy(button->box())+1; + int ht = button->h()-dy*2; + title = new menutitle(tx, ty-ht-dy, Wtitle, ht, t); + } else { + int dy = 2; + int ht = Htitle+2*BW+3; + title = new menutitle(X, Y-ht-dy, Wtitle, ht, t); + } + } else + title = 0; +} + +menuwindow::~menuwindow() { + hide(); + delete title; +} + +void menuwindow::position(int X, int Y) { + if (title) {title->position(X, title->y()+Y-y());} + Fl_Menu_Window::position(X, Y); + // x(X); y(Y); // don't wait for response from X +} + +// scroll so item i is visible on screen +void menuwindow::autoscroll(int n) { + int scr_x, scr_y, scr_w, scr_h; + int Y = y()+Fl::box_dx(box())+2+n*itemheight; + + Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h); + if (Y <= scr_y) Y = scr_y-Y+10; + else { + Y = Y+itemheight-scr_h-scr_y; + if (Y < 0) return; + Y = -Y-10; + } + Fl_Menu_Window::position(x(), y()+Y); + // y(y()+Y); // don't wait for response from X +} + +//////////////////////////////////////////////////////////////// + +void menuwindow::drawentry(const Fl_Menu_Item* m, int n, int eraseit) { + if (!m) return; // this happens if -1 is selected item and redrawn + + int BW = Fl::box_dx(box()); + int xx = BW; + int W = w(); + int ww = W-2*BW-1; + int yy = BW+1+n*itemheight; + int hh = itemheight - LEADING; + + if (eraseit && n != selected) { + fl_push_clip(xx+1, yy-(LEADING-2)/2, ww-2, hh+(LEADING-2)); + draw_box(box(), 0, 0, w(), h(), button ? button->color() : color()); + fl_pop_clip(); + } + + m->draw(xx, yy, ww, hh, button, n==selected); + + // the shortcuts and arrows assumme fl_color() was left set by draw(): + if (m->submenu()) { + int sz = (hh-7)&-2; + int y1 = yy+(hh-sz)/2; + int x1 = xx+ww-sz-3; + fl_polygon(x1+2, y1, x1+2, y1+sz, x1+sz/2+2, y1+sz/2); + } else if (m->shortcut_) { + Fl_Font f = m->labelsize_ || m->labelfont_ ? (Fl_Font)m->labelfont_ : + button ? button->textfont() : FL_HELVETICA; + fl_font(f, m->labelsize_ ? m->labelsize_ : + button ? button->textsize() : FL_NORMAL_SIZE); + fl_draw(fl_shortcut_label(m->shortcut_), xx, yy, ww-3, hh, FL_ALIGN_RIGHT); + } + + if (m->flags & FL_MENU_DIVIDER) { + fl_color(FL_DARK3); + fl_xyline(BW-1, yy+hh+(LEADING-2)/2, W-2*BW+2); + fl_color(FL_LIGHT3); + fl_xyline(BW-1, yy+hh+((LEADING-2)/2+1), W-2*BW+2); + } +} + +void menutitle::draw() { + menu->draw(0, 0, w(), h(), button, 2); +} + +void menuwindow::draw() { + if (damage() != FL_DAMAGE_CHILD) { // complete redraw + fl_draw_box(box(), 0, 0, w(), h(), button ? button->color() : color()); + if (menu) { + const Fl_Menu_Item* m; int j; + for (m=menu->first(), j=0; m->text; j++, m = m->next()) drawentry(m, j, 0); + } + } else { + if (damage() & FL_DAMAGE_CHILD && selected!=drawn_selected) { // change selection + drawentry(menu->next(drawn_selected), drawn_selected, 1); + drawentry(menu->next(selected), selected, 1); + } + } + drawn_selected = selected; +} + +void menuwindow::set_selected(int n) { + if (n != selected) {selected = n; damage(FL_DAMAGE_CHILD);} +} + +//////////////////////////////////////////////////////////////// + +int menuwindow::find_selected(int mx, int my) { + if (!menu || !menu->text) return -1; + mx -= x(); + my -= y(); + if (my < 0 || my >= h()) return -1; + if (!itemheight) { // menubar + int xx = 3; int n = 0; + const Fl_Menu_Item* m = menu ? menu->first() : 0; + for (; ; m = m->next(), n++) { + if (!m->text) return -1; + xx += m->measure(0, button) + 16; + if (xx > mx) break; + } + return n; + } + if (mx < Fl::box_dx(box()) || mx >= w()) return -1; + int n = (my-Fl::box_dx(box())-1)/itemheight; + if (n < 0 || n>=numitems) return -1; + return n; +} + +// return horizontal position for item n in a menubar: +int menuwindow::titlex(int n) { + const Fl_Menu_Item* m; + int xx = 3; + for (m=menu->first(); n--; m = m->next()) xx += m->measure(0, button) + 16; + return xx; +} + +// return 1, if the given root coordinates are inside the window +int menuwindow::is_inside(int mx, int my) { + if ( mx < x_root() || mx >= x_root() + w() || + my < y_root() || my >= y_root() + h()) { + return 0; + } + return 1; +} + +//////////////////////////////////////////////////////////////// +// Fl_Menu_Item::popup(...) + +// Because Fl::grab() is done, all events go to one of the menu windows. +// But the handle method needs to look at all of them to find out +// what item the user is pointing at. And it needs a whole lot +// of other state variables to determine what is going on with +// the currently displayed menus. +// So the main loop (handlemenu()) puts all the state in a structure +// and puts a pointer to it in a static location, so the handle() +// on menus can refer to it and alter it. The handle() method +// changes variables in this state to indicate what item is +// picked, but does not actually alter the display, instead the +// main loop does that. This is because the X mapping and unmapping +// of windows is slow, and we don't want to fall behind the events. + +// values for menustate.state: +#define INITIAL_STATE 0 // no mouse up or down since popup() called +#define PUSH_STATE 1 // mouse has been pushed on a normal item +#define DONE_STATE 2 // exit the popup, the current item was picked +#define MENU_PUSH_STATE 3 // mouse has been pushed on a menu title + +struct menustate { + const Fl_Menu_Item* current_item; // what mouse is pointing at + int menu_number; // which menu it is in + int item_number; // which item in that menu, -1 if none + menuwindow* p[20]; // pointers to menus + int nummenus; + int menubar; // if true p[0] is a menubar + int state; + menuwindow* fakemenu; // kludge for buttons in menubar + int is_inside(int mx, int my); +}; +static menustate* p; + +// return 1 if the coordinates are inside any of the menuwindows +int menustate::is_inside(int mx, int my) { + int i; + for (i=nummenus-1; i>=0; i--) { + if (p[i]->is_inside(mx, my)) + return 1; + } + return 0; +} + +static inline void setitem(const Fl_Menu_Item* i, int m, int n) { + p->current_item = i; + p->menu_number = m; + p->item_number = n; +} + +static void setitem(int m, int n) { + menustate &pp = *p; + pp.current_item = (n >= 0) ? pp.p[m]->menu->next(n) : 0; + pp.menu_number = m; + pp.item_number = n; +} + +static int forward(int menu) { // go to next item in menu menu if possible + menustate &pp = *p; + // Fl_Menu_Button can geberate menu=-1. This line fixes it and selectes the first item. + if (menu==-1) + menu = 0; + menuwindow &m = *(pp.p[menu]); + int item = (menu == pp.menu_number) ? pp.item_number : m.selected; + while (++item < m.numitems) { + const Fl_Menu_Item* m1 = m.menu->next(item); + if (m1->activevisible()) {setitem(m1, menu, item); return 1;} + } + return 0; +} + +static int backward(int menu) { // previous item in menu menu if possible + menustate &pp = *p; + menuwindow &m = *(pp.p[menu]); + int item = (menu == pp.menu_number) ? pp.item_number : m.selected; + if (item < 0) item = m.numitems; + while (--item >= 0) { + const Fl_Menu_Item* m1 = m.menu->next(item); + if (m1->activevisible()) {setitem(m1, menu, item); return 1;} + } + return 0; +} + +int menuwindow::handle(int e) { +#ifdef __APPLE__ + // This off-route takes care of the "detached menu" bug on OS X. + // Apple event handler requires that we hide all menu windows right + // now, so that Carbon can continue undisturbed with handling window + // manager events, like dragging the application window. + int ret = early_hide_handle(e); + menustate &pp = *p; + if (pp.state == DONE_STATE) { + hide(); + if (pp.fakemenu) { + pp.fakemenu->hide(); + if (pp.fakemenu->title) + pp.fakemenu->title->hide(); + } + int i = pp.nummenus; + while (i>0) { + menuwindow *mw = pp.p[--i]; + if (mw) { + mw->hide(); + if (mw->title) + mw->title->hide(); + } + } + } + return ret; +} + +int menuwindow::early_hide_handle(int e) { +#endif + menustate &pp = *p; + switch (e) { + case FL_KEYBOARD: + switch (Fl::event_key()) { + case FL_BackSpace: + case 0xFE20: // backtab + BACKTAB: + if (!backward(pp.menu_number)) {pp.item_number = -1;backward(pp.menu_number);} + return 1; + case FL_Up: + if (pp.menubar && pp.menu_number == 0) { + // Do nothing... + } else if (backward(pp.menu_number)) { + // Do nothing... + } else if (pp.menubar && pp.menu_number==1) { + setitem(0, pp.p[0]->selected); + } + return 1; + case FL_Tab: + if (Fl::event_shift()) goto BACKTAB; + case FL_Down: + if (pp.menu_number || !pp.menubar) { + if (!forward(pp.menu_number) && Fl::event_key()==FL_Tab) { + pp.item_number = -1; + forward(pp.menu_number); + } + } else if (pp.menu_number < pp.nummenus-1) { + forward(pp.menu_number+1); + } + return 1; + case FL_Right: + if (pp.menubar && (pp.menu_number<=0 || pp.menu_number==1 && pp.nummenus==2)) + forward(0); + else if (pp.menu_number < pp.nummenus-1) forward(pp.menu_number+1); + return 1; + case FL_Left: + if (pp.menubar && pp.menu_number<=1) backward(0); + else if (pp.menu_number>0) + setitem(pp.menu_number-1, pp.p[pp.menu_number-1]->selected); + return 1; + case FL_Enter: + case FL_KP_Enter: + case ' ': + pp.state = DONE_STATE; + return 1; + case FL_Escape: + setitem(0, -1, 0); + pp.state = DONE_STATE; + return 1; + } + break; + case FL_SHORTCUT: { + for (int mymenu = pp.nummenus; mymenu--;) { + menuwindow &mw = *(pp.p[mymenu]); + int item; const Fl_Menu_Item* m = mw.menu->find_shortcut(&item); + if (m) { + setitem(m, mymenu, item); + if (!m->submenu()) pp.state = DONE_STATE; + return 1; + } + }} break; + case FL_ENTER: + case FL_MOVE: + case FL_PUSH: + case FL_DRAG: { +#ifdef __QNX__ + // STR 704: workaround QNX X11 bug - in QNX a FL_MOVE event is sent + // right after FL_RELEASE... + if (pp.state == DONE_STATE) return 1; +#endif // __QNX__ + int mx = Fl::event_x_root(); + int my = Fl::event_y_root(); + int item=0; int mymenu = pp.nummenus-1; + // Clicking or dragging outside menu cancels it... + if ((!pp.menubar || mymenu) && !pp.is_inside(mx, my)) { + setitem(0, -1, 0); + if (e==FL_PUSH) + pp.state = DONE_STATE; + return 1; + } + for (mymenu = pp.nummenus-1; ; mymenu--) { + item = pp.p[mymenu]->find_selected(mx, my); + if (item >= 0) + break; + if (mymenu <= 0) { + // buttons in menubars must be deselected if we move outside of them! + if (pp.menu_number==-1 && e==FL_PUSH) { + pp.state = DONE_STATE; + return 1; + } + if (pp.current_item && pp.menu_number==0 && !pp.current_item->submenu()) { + if (e==FL_PUSH) + pp.state = DONE_STATE; + setitem(0, -1, 0); + return 1; + } + // all others can stay selected + return 0; + } + } + if (my == 0 && item > 0) setitem(mymenu, item - 1); + else setitem(mymenu, item); + if (e == FL_PUSH) { + if (pp.current_item && pp.current_item->submenu() // this is a menu title + && item != pp.p[mymenu]->selected // and it is not already on + && !pp.current_item->callback_) // and it does not have a callback + pp.state = MENU_PUSH_STATE; + else + pp.state = PUSH_STATE; + }} return 1; + case FL_RELEASE: + // Mouse must either be held down/dragged some, or this must be + // the second click (not the one that popped up the menu): + if (!Fl::event_is_click() || pp.state == PUSH_STATE || + pp.menubar && pp.current_item && !pp.current_item->submenu() // button + ) { +#if 0 // makes the check/radio items leave the menu up + const Fl_Menu_Item* m = pp.current_item; + if (m && button && (m->flags & (FL_MENU_TOGGLE|FL_MENU_RADIO))) { + ((Fl_Menu_*)button)->picked(m); + pp.p[pp.menu_number]->redraw(); + } else +#endif + // do nothing if they try to pick inactive items + if (!pp.current_item || pp.current_item->activevisible()) + pp.state = DONE_STATE; + } + return 1; + } + return Fl_Window::handle(e); +} + +const Fl_Menu_Item* Fl_Menu_Item::pulldown( + int X, int Y, int W, int H, + const Fl_Menu_Item* initial_item, + const Fl_Menu_* pbutton, + const Fl_Menu_Item* t, + int menubar) const +{ + Fl_Group::current(0); // fix possible user error... + + button = pbutton; + if (pbutton) { + for (Fl_Window* w = pbutton->window(); w; w = w->window()) { + X += w->x(); + Y += w->y(); + } + } else { + X += Fl::event_x_root()-Fl::event_x(); + Y += Fl::event_y_root()-Fl::event_y(); + } + menuwindow mw(this, X, Y, W, H, initial_item, t, menubar); + Fl::grab(mw); + menustate pp; p = &pp; + pp.p[0] = &mw; + pp.nummenus = 1; + pp.menubar = menubar; + pp.state = INITIAL_STATE; + pp.fakemenu = 0; // kludge for buttons in menubar + + // preselected item, pop up submenus if necessary: + if (initial_item && mw.selected >= 0) { + setitem(0, mw.selected); + goto STARTUP; + } + + pp.current_item = 0; pp.menu_number = 0; pp.item_number = -1; + if (menubar) { + // find the initial menu + if (!mw.handle(FL_DRAG)) { + Fl::release(); + return 0; + } + } + initial_item = pp.current_item; + if (initial_item) goto STARTUP; + + // the main loop, runs until p.state goes to DONE_STATE: + for (;;) { + + // make sure all the menus are shown: + {for (int k = menubar; k < pp.nummenus; k++) + if (!pp.p[k]->shown()) { + if (pp.p[k]->title) pp.p[k]->title->show(); + pp.p[k]->show(); + } + } + + // get events: + {const Fl_Menu_Item* oldi = pp.current_item; + Fl::wait(); + if (pp.state == DONE_STATE) break; // done. + if (pp.current_item == oldi) continue;} + // only do rest if item changes: + + delete pp.fakemenu; pp.fakemenu = 0; // turn off "menubar button" + + if (!pp.current_item) { // pointing at nothing + // turn off selection in deepest menu, but don't erase other menus: + pp.p[pp.nummenus-1]->set_selected(-1); + continue; + } + + delete pp.fakemenu; pp.fakemenu = 0; + initial_item = 0; // stop the startup code + pp.p[pp.menu_number]->autoscroll(pp.item_number); + + STARTUP: + menuwindow& cw = *pp.p[pp.menu_number]; + const Fl_Menu_Item* m = pp.current_item; + if (!m->activevisible()) { // pointing at inactive item + cw.set_selected(-1); + initial_item = 0; // turn off startup code + continue; + } + cw.set_selected(pp.item_number); + + if (m==initial_item) initial_item=0; // stop the startup code if item found + if (m->submenu()) { + const Fl_Menu_Item* title = m; + const Fl_Menu_Item* menutable; + if (m->flags&FL_SUBMENU) menutable = m+1; + else menutable = (Fl_Menu_Item*)(m)->user_data_; + // figure out where new menu goes: + int nX, nY; + if (!pp.menu_number && pp.menubar) { // menu off a menubar: + nX = cw.x() + cw.titlex(pp.item_number); + nY = cw.y() + cw.h(); + initial_item = 0; + } else { + nX = cw.x() + cw.w(); + nY = cw.y() + pp.item_number * cw.itemheight; + title = 0; + } + if (initial_item) { // bring up submenu containing initial item: + menuwindow* n = new menuwindow(menutable,X,Y,W,H,initial_item,title,0,0,cw.x()); + pp.p[pp.nummenus++] = n; + // move all earlier menus to line up with this new one: + if (n->selected>=0) { + int dy = n->y()-nY; + int dx = n->x()-nX; + for (int menu = 0; menu <= pp.menu_number; menu++) { + menuwindow* tt = pp.p[menu]; + int nx = tt->x()+dx; if (nx < 0) {nx = 0; dx = -tt->x();} + int ny = tt->y()+dy; if (ny < 0) {ny = 0; dy = -tt->y();} + tt->position(nx, ny); + } + setitem(pp.nummenus-1, n->selected); + goto STARTUP; + } + } else if (pp.nummenus > pp.menu_number+1 && + pp.p[pp.menu_number+1]->menu == menutable) { + // the menu is already up: + while (pp.nummenus > pp.menu_number+2) delete pp.p[--pp.nummenus]; + pp.p[pp.nummenus-1]->set_selected(-1); + } else { + // delete all the old menus and create new one: + while (pp.nummenus > pp.menu_number+1) delete pp.p[--pp.nummenus]; + pp.p[pp.nummenus++]= new menuwindow(menutable, nX, nY, + title?1:0, 0, 0, title, 0, menubar, cw.x()); + } + } else { // !m->submenu(): + while (pp.nummenus > pp.menu_number+1) delete pp.p[--pp.nummenus]; + if (!pp.menu_number && pp.menubar) { + // kludge so "menubar buttons" turn "on" by using menu title: + pp.fakemenu = new menuwindow(0, + cw.x()+cw.titlex(pp.item_number), + cw.y()+cw.h(), 0, 0, + 0, m, 0, 1); + pp.fakemenu->title->show(); + } + } + } + const Fl_Menu_Item* m = pp.current_item; + Fl::release(); + delete pp.fakemenu; + while (pp.nummenus>1) delete pp.p[--pp.nummenus]; + mw.hide(); + return m; +} + +const Fl_Menu_Item* +Fl_Menu_Item::popup( + int X, int Y, + const char* title, + const Fl_Menu_Item* picked, + const Fl_Menu_* but + ) const +{ + static Fl_Menu_Item dummy; // static so it is all zeros + dummy.text = title; + return pulldown(X, Y, 0, 0, picked, but, title ? &dummy : 0); +} + +// Search only the top level menu for a shortcut. Either &x in the +// label or the shortcut fields are used: +const Fl_Menu_Item* Fl_Menu_Item::find_shortcut(int* ip) const { + const Fl_Menu_Item* m = first(); + if (m) for (int ii = 0; m->text; m = m->next(), ii++) { + if (m->activevisible()) { + if (Fl::test_shortcut(m->shortcut_) + || Fl_Widget::test_shortcut(m->text)) { + if (ip) *ip=ii; + return m; + } + } + } + return 0; +} + +// Recursive search of all submenus for anything with this key as a +// shortcut. Only uses the shortcut field, ignores &x in the labels: +const Fl_Menu_Item* Fl_Menu_Item::test_shortcut() const { + const Fl_Menu_Item* m = first(); + const Fl_Menu_Item* ret = 0; + if (m) for (; m->text; m = m->next()) { + if (m->activevisible()) { + // return immediately any match of an item in top level menu: + if (Fl::test_shortcut(m->shortcut_)) return m; + // if (Fl_Widget::test_shortcut(m->text)) return m; + // only return matches from lower menu if nothing found in top menu: + if (!ret && m->submenu()) { + const Fl_Menu_Item* s = + (m->flags&FL_SUBMENU) ? m+1:(const Fl_Menu_Item*)m->user_data_; + ret = s->test_shortcut(); + } + } + } + return ret; +} + +// +// End of "$Id: Fl_Menu.cxx 6043 2008-02-25 13:09:30Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Menu_.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Menu_.cxx new file mode 100644 index 000000000..5585bbdf1 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Menu_.cxx @@ -0,0 +1,232 @@ +// +// "$Id: Fl_Menu_.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Common menu code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// This is a base class for all items that have a menu: +// Fl_Menu_Bar, Fl_Menu_Button, Fl_Choice +// This provides storage for a menu item, functions to add/modify/delete +// items, and a call for when the user picks a menu item. + +// More code in Fl_Menu_add.cxx + +#include +#include +#include "flstring.h" +#include +#include + +// Set 'pathname' of specified menuitem +// If finditem==NULL, mvalue() is used (the most recently picked menuitem) +// Returns: +// 0 : OK +// -1 : item not found (name="") +// -2 : 'name' not large enough (name="") +// +#define SAFE_STRCAT(s) \ + { len += strlen(s); if ( len >= namelen ) { *name='\0'; return(-2); } else strcat(name,(s)); } +int Fl_Menu_::item_pathname(char *name, int namelen, const Fl_Menu_Item *finditem) const { + int len = 0; + finditem = finditem ? finditem : mvalue(); + name[0] = '\0'; + for ( int t=0; tsubmenu() ) { // submenu? descend + if (*name) SAFE_STRCAT("/"); + if (m->label()) SAFE_STRCAT(m->label()); + } else { + if (m->label()) { // menu item? + if ( m == finditem ) { // found? tack on itemname, done. + SAFE_STRCAT("/"); + SAFE_STRCAT(m->label()); + return(0); + } + } else { // end of submenu? pop + char *ss = strrchr(name, '/'); + if ( ss ) { *ss = 0; len = strlen(name); } // "File/Edit" -> "File" + else { name[0] = '\0'; len = 0; } // "File" -> "" + continue; + } + } + } + *name = '\0'; + return(-1); // item not found +} + +// FIND MENU ITEM INDEX, GIVEN MENU PATHNAME +// eg. "Edit/Copy" +// Will also return submenus, eg. "Edit" +// Returns NULL if not found. +// +const Fl_Menu_Item * +Fl_Menu_::find_item(const char *name) +{ + char menupath[1024] = ""; // File/Export + + for ( int t=0; t < size(); t++ ) { + Fl_Menu_Item *m = menu_ + t; + + if (m->flags&FL_SUBMENU) { + // IT'S A SUBMENU + // we do not support searches through FL_SUBMENU_POINTER links + if (menupath[0]) strlcat(menupath, "/", sizeof(menupath)); + strlcat(menupath, m->label(), sizeof(menupath)); + if (!strcmp(menupath, name)) return m; + } else { + if (!m->label()) { + // END OF SUBMENU? Pop back one level. + char *ss = strrchr(menupath, '/'); + if ( ss ) *ss = 0; + else menupath[0] = '\0'; + continue; + } + + // IT'S A MENU ITEM + char itempath[1024]; // eg. Edit/Copy + strcpy(itempath, menupath); + if (itempath[0]) strlcat(itempath, "/", sizeof(itempath)); + strlcat(itempath, m->label(), sizeof(itempath)); + if (!strcmp(itempath, name)) return m; + } + } + + return (const Fl_Menu_Item *)0; +} + +int Fl_Menu_::value(const Fl_Menu_Item* m) { + clear_changed(); + if (value_ != m) {value_ = m; return 1;} + return 0; +} + +// When user picks a menu item, call this. It will do the callback. +// Unfortunatly this also casts away const for the checkboxes, but this +// was necessary so non-checkbox menus can really be declared const... +const Fl_Menu_Item* Fl_Menu_::picked(const Fl_Menu_Item* v) { + if (v) { + if (v->radio()) { + if (!v->value()) { // they are turning on a radio item + set_changed(); + ((Fl_Menu_Item*)v)->setonly(); + } + redraw(); + } else if (v->flags & FL_MENU_TOGGLE) { + set_changed(); + ((Fl_Menu_Item*)v)->flags ^= FL_MENU_VALUE; + redraw(); + } else if (v != value_) { // normal item + set_changed(); + } + value_ = v; + if (when()&(FL_WHEN_CHANGED|FL_WHEN_RELEASE)) { + if (changed() || when()&FL_WHEN_NOT_CHANGED) { + if (value_ && value_->callback_) value_->do_callback((Fl_Widget*)this); + else do_callback(); + } + } + } + return v; +} + +// turn on one of a set of radio buttons +void Fl_Menu_Item::setonly() { + flags |= FL_MENU_RADIO | FL_MENU_VALUE; + Fl_Menu_Item* j; + for (j = this; ; ) { // go down + if (j->flags & FL_MENU_DIVIDER) break; // stop on divider lines + j++; + if (!j->text || !j->radio()) break; // stop after group + j->clear(); + } + for (j = this-1; ; j--) { // go up + if (!j->text || (j->flags&FL_MENU_DIVIDER) || !j->radio()) break; + j->clear(); + } +} + +Fl_Menu_::Fl_Menu_(int X,int Y,int W,int H,const char* l) +: Fl_Widget(X,Y,W,H,l) { + set_flag(SHORTCUT_LABEL); + box(FL_UP_BOX); + when(FL_WHEN_RELEASE_ALWAYS); + value_ = menu_ = 0; + alloc = 0; + selection_color(FL_SELECTION_COLOR); + textfont(FL_HELVETICA); + textsize((uchar)FL_NORMAL_SIZE); + textcolor(FL_FOREGROUND_COLOR); + down_box(FL_NO_BOX); +} + +int Fl_Menu_::size() const { + if (!menu_) return 0; + return menu_->size(); +} + +void Fl_Menu_::menu(const Fl_Menu_Item* m) { + clear(); + value_ = menu_ = (Fl_Menu_Item*)m; +} + +// this version is ok with new Fl_Menu_add code with fl_menu_array_owner: + +void Fl_Menu_::copy(const Fl_Menu_Item* m, void* ud) { + int n = m->size(); + Fl_Menu_Item* newMenu = new Fl_Menu_Item[n]; + memcpy(newMenu, m, n*sizeof(Fl_Menu_Item)); + menu(newMenu); + alloc = 1; // make destructor free array, but not strings + // for convienence, provide way to change all the user data pointers: + if (ud) for (; n--;) { + if (newMenu->callback_) newMenu->user_data_ = ud; + newMenu++; + } +} + +Fl_Menu_::~Fl_Menu_() { + clear(); +} + +// Fl_Menu::add() uses this to indicate the owner of the dynamically- +// expanding array. We must not free this array: +Fl_Menu_* fl_menu_array_owner = 0; + +void Fl_Menu_::clear() { + if (alloc) { + if (alloc>1) for (int i = size(); i--;) + if (menu_[i].text) free((void*)menu_[i].text); + if (this == fl_menu_array_owner) + fl_menu_array_owner = 0; + else + delete[] menu_; + menu_ = 0; + value_ = 0; + alloc = 0; + } +} + +// +// End of "$Id: Fl_Menu_.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Menu_Bar.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Menu_Bar.cxx new file mode 100644 index 000000000..15035f237 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Menu_Bar.cxx @@ -0,0 +1,78 @@ +// +// "$Id: Fl_Menu_Bar.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Menu bar widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include + +void Fl_Menu_Bar::draw() { + draw_box(); + if (!menu() || !menu()->text) return; + const Fl_Menu_Item* m; + int X = x()+6; + for (m=menu()->first(); m->text; m = m->next()) { + int W = m->measure(0,this) + 16; + m->draw(X, y(), W, h(), this); + X += W; + if (m->flags & FL_MENU_DIVIDER) { + int y1 = y() + Fl::box_dy(box()); + int y2 = y1 + h() - Fl::box_dh(box()) - 1; + + // Draw a vertical divider between menus... + fl_color(FL_DARK3); + fl_yxline(X - 6, y1, y2); + fl_color(FL_LIGHT3); + fl_yxline(X - 5, y1, y2); + } + } +} + +int Fl_Menu_Bar::handle(int event) { + const Fl_Menu_Item* v; + if (menu() && menu()->text) switch (event) { + case FL_ENTER: + case FL_LEAVE: + return 1; + case FL_PUSH: + v = 0; + J1: + v = menu()->pulldown(x(), y(), w(), h(), v, this, 0, 1); + picked(v); + return 1; + case FL_SHORTCUT: + if (visible_r()) { + v = menu()->find_shortcut(); + if (v && v->submenu()) goto J1; + } + return test_shortcut() != 0; + } + return 0; +} + +// +// End of "$Id: Fl_Menu_Bar.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Menu_Button.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Menu_Button.cxx new file mode 100644 index 000000000..76c4a8600 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Menu_Button.cxx @@ -0,0 +1,111 @@ +// +// "$Id: Fl_Menu_Button.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Menu button widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2006 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include + + +static Fl_Menu_Button *pressed_menu_button_ = 0; + +void Fl_Menu_Button::draw() { + if (!box() || type()) return; + draw_box(pressed_menu_button_ == this ? fl_down(box()) : box(), color()); + draw_label(); + if (Fl::focus() == this) draw_focus(); + if (box() == FL_FLAT_BOX) return; // for XForms compatability + int H = (labelsize()-3)&-2; + int X = x()+w()-H*2; + int Y = y()+(h()-H)/2; + fl_color(active_r() ? FL_DARK3 : fl_inactive(FL_DARK3)); + fl_line(X+H/2, Y+H, X, Y, X+H, Y); + fl_color(active_r() ? FL_LIGHT3 : fl_inactive(FL_LIGHT3)); + fl_line(X+H, Y, X+H/2, Y+H); +} + +const Fl_Menu_Item* Fl_Menu_Button::popup() { + const Fl_Menu_Item* m; + pressed_menu_button_ = this; + redraw(); + Fl_Widget *mb = this; + Fl::watch_widget_pointer(mb); + if (!box() || type()) { + m = menu()->popup(Fl::event_x(), Fl::event_y(), label(), mvalue(), this); + } else { + m = menu()->pulldown(x(), y(), w(), h(), 0, this); + } + picked(m); + pressed_menu_button_ = 0; + if (mb) mb->redraw(); + Fl::release_widget_pointer(mb); + return m; +} + +int Fl_Menu_Button::handle(int e) { + if (!menu() || !menu()->text) return 0; + switch (e) { + case FL_ENTER: + case FL_LEAVE: + return (box() && !type()) ? 1 : 0; + case FL_PUSH: + if (!box()) { + if (Fl::event_button() != 3) return 0; + } else if (type()) { + if (!(type() & (1 << (Fl::event_button()-1)))) return 0; + } + if (Fl::visible_focus()) Fl::focus(this); + popup(); + return 1; + case FL_KEYBOARD: + if (!box()) return 0; + if (Fl::event_key() == ' ' && + !(Fl::event_state() & (FL_SHIFT | FL_CTRL | FL_ALT | FL_META))) { + popup(); + return 1; + } else return 0; + case FL_SHORTCUT: + if (Fl_Widget::test_shortcut()) {popup(); return 1;} + return test_shortcut() != 0; + case FL_FOCUS: + case FL_UNFOCUS: + if (box() && Fl::visible_focus()) { + redraw(); + return 1; + } + default: + return 0; + } +} + +Fl_Menu_Button::Fl_Menu_Button(int X,int Y,int W,int H,const char *l) +: Fl_Menu_(X,Y,W,H,l) { + down_box(FL_NO_BOX); +} + +// +// End of "$Id: Fl_Menu_Button.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Menu_Window.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Menu_Window.cxx new file mode 100644 index 000000000..42f51c934 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Menu_Window.cxx @@ -0,0 +1,103 @@ +// +// "$Id: Fl_Menu_Window.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Menu window code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// This is the window type used by Fl_Menu to make the pop-ups. +// It draws in the overlay planes if possible. + +// Also here is the implementation of the mouse & keyboard grab, +// which are used so that clicks outside the program's windows +// can be used to dismiss the menus. + +#include +#include +#include +#include +#include + +// WIN32 note: HAVE_OVERLAY is false +#if HAVE_OVERLAY +extern XVisualInfo *fl_find_overlay_visual(); +extern XVisualInfo *fl_overlay_visual; +extern Colormap fl_overlay_colormap; +extern unsigned long fl_transparent_pixel; +static GC gc; // the GC used by all X windows +extern uchar fl_overlay; // changes how fl_color(x) works +#endif + +#include + +void Fl_Menu_Window::show() { +#if HAVE_OVERLAY + if (!shown() && overlay() && fl_find_overlay_visual()) { + XInstallColormap(fl_display, fl_overlay_colormap); + fl_background_pixel = int(fl_transparent_pixel); + Fl_X::make_xid(this, fl_overlay_visual, fl_overlay_colormap); + fl_background_pixel = -1; + } else +#endif + Fl_Single_Window::show(); +} + +void Fl_Menu_Window::flush() { +#if HAVE_OVERLAY + if (!fl_overlay_visual || !overlay()) {Fl_Single_Window::flush(); return;} + Fl_X *myi = Fl_X::i(this); + fl_window = myi->xid; + if (!gc) gc = XCreateGC(fl_display, myi->xid, 0, 0); + fl_gc = gc; + fl_overlay = 1; + fl_clip_region(myi->region); myi->region = 0; current_ = this; + draw(); + fl_overlay = 0; +#else + Fl_Single_Window::flush(); +#endif +} + +void Fl_Menu_Window::erase() { +#if HAVE_OVERLAY + if (!gc || !shown()) return; +//XSetForeground(fl_display, gc, 0); +//XFillRectangle(fl_display, fl_xid(this), gc, 0, 0, w(), h()); + XClearWindow(fl_display, fl_xid(this)); +#endif +} + +// Fix the colormap flashing on Maximum Impact Graphics by erasing the +// menu before unmapping it: +void Fl_Menu_Window::hide() { + erase(); + Fl_Single_Window::hide(); +} + +Fl_Menu_Window::~Fl_Menu_Window() { + hide(); +} + +// +// End of "$Id: Fl_Menu_Window.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Menu_add.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Menu_add.cxx new file mode 100644 index 000000000..805e694d2 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Menu_add.cxx @@ -0,0 +1,268 @@ +// +// "$Id: Fl_Menu_add.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Menu utilities for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Methods to alter the menu in an Fl_Menu_ widget. + +// These are for Forms emulation and for dynamically changing the +// menus. They are in this source file so they are not linked in if +// not used, which is what will happen if the the program only uses +// constant menu tables. + +// Not at all guaranteed to be Forms compatable, especially with any +// string with a % sign in it! + +#include +#include "flstring.h" +#include +#include + +// If the array is this, we will double-reallocate as necessary: +static Fl_Menu_Item* local_array = 0; +static int local_array_alloc = 0; // number allocated +static int local_array_size = 0; // == size(local_array) +extern Fl_Menu_* fl_menu_array_owner; // in Fl_Menu_.cxx + +// For historical reasons there are matching methods that work on a +// user-allocated array of Fl_Menu_Item. These methods are quite +// depreciated and should not be used. These old methods use the +// above pointers to detect if the array belongs to an Fl_Menu_ +// widget, and if so it reallocates as necessary. + +// Insert a single Fl_Menu_Item into an array of size at offset n, +// if this is local_array it will be reallocated if needed. +static Fl_Menu_Item* insert( + Fl_Menu_Item* array, int size, + int n, + const char *text, + int flags +) { + if (array == local_array && size >= local_array_alloc) { + local_array_alloc = 2*size; + Fl_Menu_Item* newarray = new Fl_Menu_Item[local_array_alloc]; + memmove(newarray, array, size*sizeof(Fl_Menu_Item)); + delete[] local_array; + local_array = array = newarray; + } + // move all the later items: + memmove(array+n+1, array+n, sizeof(Fl_Menu_Item)*(size-n)); + // create the new item: + Fl_Menu_Item* m = array+n; + m->text = text ? strdup(text) : 0; + m->shortcut_ = 0; + m->callback_ = 0; + m->user_data_ = 0; + m->flags = flags; + m->labeltype_ = m->labelfont_ = m->labelsize_ = m->labelcolor_ = 0; + return array; +} + +// Comparison that does not care about deleted '&' signs: +static int compare(const char* a, const char* b) { + for (;;) { + int n = *a-*b; + if (n) { + if (*a == '&') a++; + else if (*b == '&') b++; + else return n; + } else if (*a) { + a++; b++; + } else { + return 0; + } + } +} + +// Add an item. The text is split at '/' characters to automatically +// produce submenus (actually a totally unnecessary feature as you can +// now add submenu titles directly by setting SUBMENU in the flags): +int Fl_Menu_Item::add( + const char *mytext, + int sc, + Fl_Callback *cb, + void *data, + int myflags +) { + Fl_Menu_Item *array = this; + Fl_Menu_Item *m = this; + const char *p; + char *q; + char buf[1024]; + + int msize = array==local_array ? local_array_size : array->size(); + int flags1 = 0; + const char* item; + + // split at slashes to make submenus: + for (;;) { + + // leading slash makes us assumme it is a filename: + if (*mytext == '/') {item = mytext; break;} + + // leading underscore causes divider line: + if (*mytext == '_') {mytext++; flags1 = FL_MENU_DIVIDER;} + + // copy to buf, changing \x to x: + q = buf; + for (p=mytext; *p && *p != '/'; *q++ = *p++) if (*p=='\\' && p[1]) p++; + *q = 0; + + item = buf; + if (*p != '/') break; /* not a menu title */ + mytext = p+1; /* point at item title */ + + /* find a matching menu title: */ + for (; m->text; m = m->next()) + if (m->flags&FL_SUBMENU && !compare(item, m->text)) break; + + if (!m->text) { /* create a new menu */ + int n = m-array; + array = insert(array, msize, n, item, FL_SUBMENU|flags1); + msize++; + array = insert(array, msize, n+1, 0, 0); + msize++; + m = array+n; + } + m++; /* go into the submenu */ + flags1 = 0; + } + + /* find a matching menu item: */ + for (; m->text; m = m->next()) + if (!(m->flags&FL_SUBMENU) && !compare(m->text,item)) break; + + if (!m->text) { /* add a new menu item */ + int n = m-array; + array = insert(array, msize, n, item, myflags|flags1); + msize++; + if (myflags & FL_SUBMENU) { // add submenu delimiter + array = insert(array, msize, n+1, 0, 0); + msize++; + } + m = array+n; + } + + /* fill it in */ + m->shortcut_ = sc; + m->callback_ = cb; + m->user_data_ = data; + m->flags = myflags|flags1; + + if (array == local_array) local_array_size = msize; + return m-array; +} + +int Fl_Menu_::add(const char *t, int s, Fl_Callback *c,void *v,int f) { + // make this widget own the local array: + if (this != fl_menu_array_owner) { + if (fl_menu_array_owner) { + Fl_Menu_* o = fl_menu_array_owner; + // the previous owner get's its own correctly-sized array: + int value_offset = o->value_-local_array; + int n = local_array_size; + Fl_Menu_Item* newMenu = o->menu_ = new Fl_Menu_Item[n]; + memcpy(newMenu, local_array, n*sizeof(Fl_Menu_Item)); + if (o->value_) o->value_ = newMenu+value_offset; + } + if (menu_) { + // this already has a menu array, use it as the local one: + delete[] local_array; + if (!alloc) copy(menu_); // duplicate a user-provided static array + // add to the menu's current array: + local_array_alloc = local_array_size = size(); + local_array = menu_; + } else { + // start with a blank array: + alloc = 2; // indicates that the strings can be freed + if (local_array) { + menu_ = local_array; + } else { + local_array_alloc = 15; + local_array = menu_ = new Fl_Menu_Item[local_array_alloc]; + memset(local_array, 0, sizeof(Fl_Menu_Item) * local_array_alloc); + } + memset(menu_, 0, sizeof(Fl_Menu_Item)); + local_array_size = 1; + } + fl_menu_array_owner = this; + } + int r = menu_->add(t,s,c,v,f); + // if it rellocated array we must fix the pointer: + int value_offset = value_-menu_; + menu_ = local_array; // in case it reallocated it + if (value_) value_ = menu_+value_offset; + return r; +} + +// This is a Forms (and SGI GL library) compatable add function, it +// adds many menu items, with '|' seperating the menu items, and tab +// seperating the menu item names from an optional shortcut string. +int Fl_Menu_::add(const char *str) { + char buf[1024]; + int r = 0; + while (*str) { + int sc = 0; + char *c; + for (c = buf; c < (buf + sizeof(buf) - 2) && *str && *str != '|'; str++) { + if (*str == '\t') {*c++ = 0; sc = fl_old_shortcut(str);} + else *c++ = *str; + } + *c = 0; + r = add(buf, sc, 0, 0, 0); + if (*str) str++; + } + return r; +} + +void Fl_Menu_::replace(int i, const char *str) { + if (i<0 || i>=size()) return; + if (!alloc) copy(menu_); + if (alloc > 1) { + free((void *)menu_[i].text); + str = strdup(str); + } + menu_[i].text = str; +} + +void Fl_Menu_::remove(int i) { + int n = size(); + if (i<0 || i>=n) return; + if (!alloc) copy(menu_); + // find the next item, skipping submenus: + Fl_Menu_Item* item = menu_+i; + const Fl_Menu_Item* next_item = item->next(); + // delete the text only if all items were created with add(): + if (alloc > 1) { + for (Fl_Menu_Item* m = item; m < next_item; m++) + if (m->text) free((void*)(m->text)); + } + // MRS: "n" is the menu size(), which includes the trailing NULL entry... + memmove(item, next_item, (menu_+n-next_item)*sizeof(Fl_Menu_Item)); +} + +// +// End of "$Id: Fl_Menu_add.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Menu_global.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Menu_global.cxx new file mode 100644 index 000000000..e751f1497 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Menu_global.cxx @@ -0,0 +1,50 @@ +// +// "$Id: Fl_Menu_global.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Global menu shortcut code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Make all the shortcuts in this menu global. +// Currently only one menu at a time and you cannot destruct the menu, +// is this sufficient? + +#include +#include + +static Fl_Menu_* the_widget; + +static int handler(int e) { + if (e != FL_SHORTCUT || Fl::modal()) return 0; + Fl::first_window(the_widget->window()); + return the_widget->handle(e); +} + +void Fl_Menu_::global() { + if (!the_widget) Fl::add_handler(handler); + the_widget = this; +} + +// +// End of "$Id: Fl_Menu_global.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Multi_Label.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Multi_Label.cxx new file mode 100644 index 000000000..6c5bcd4e4 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Multi_Label.cxx @@ -0,0 +1,80 @@ +// +// "$Id: Fl_Multi_Label.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Multi-label widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Allows two labels to be used on a widget (by having one of them +// be one of these it allows an infinte number!) + +#include +#include +#include +#include + +static void multi_labeltype( + const Fl_Label* o, int x, int y, int w, int h, Fl_Align a) +{ + Fl_Multi_Label* b = (Fl_Multi_Label*)(o->value); + Fl_Label local = *o; + local.value = b->labela; + local.type = b->typea; + int W = w; int H = h; local.measure(W, H); + local.draw(x,y,w,h,a); + if (a & FL_ALIGN_BOTTOM) h -= H; + else if (a & FL_ALIGN_TOP) {y += H; h -= H;} + else if (a & FL_ALIGN_RIGHT) w -= W; + else if (a & FL_ALIGN_LEFT) {x += W; w -= W;} + else {int d = (h+H)/2; y += d; h -= d;} + local.value = b->labelb; + local.type = b->typeb; + local.draw(x,y,w,h,a); +} + +// measurement is only correct for left-to-right appending... +static void multi_measure(const Fl_Label* o, int& w, int& h) { + Fl_Multi_Label* b = (Fl_Multi_Label*)(o->value); + Fl_Label local = *o; + local.value = b->labela; + local.type = b->typea; + local.measure(w,h); + local.value = b->labelb; + local.type = b->typeb; + int W = 0; int H = 0; local.measure(W,H); + w += W; if (H>h) h = H; +} + +void Fl_Multi_Label::label(Fl_Widget* o) { + Fl::set_labeltype(_FL_MULTI_LABEL, multi_labeltype, multi_measure); + o->label(_FL_MULTI_LABEL, (const char*)this); +} + +void Fl_Multi_Label::label(Fl_Menu_Item* o) { + Fl::set_labeltype(_FL_MULTI_LABEL, multi_labeltype, multi_measure); + o->label(_FL_MULTI_LABEL, (const char*)this); +} + +// +// End of "$Id: Fl_Multi_Label.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Overlay_Window.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Overlay_Window.cxx new file mode 100644 index 000000000..26f847041 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Overlay_Window.cxx @@ -0,0 +1,155 @@ +// +// "$Id: Fl_Overlay_Window.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Overlay window code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// A window using double-buffering and able to draw an overlay +// on top of that. Uses the hardware to draw the overlay if +// possible, otherwise it just draws in the front buffer. + +#include +#include +#include +#include +#include + +void Fl_Overlay_Window::show() { + Fl_Double_Window::show(); + if (overlay_ && overlay_ != this) overlay_->show(); +} + +void Fl_Overlay_Window::hide() { + Fl_Double_Window::hide(); +} + +void Fl_Overlay_Window::flush() { +#ifdef BOXX_BUGS + if (overlay_ && overlay_ != this && overlay_->shown()) { + // all drawing to windows hidden by overlay windows is ignored, fix this + XUnmapWindow(fl_display, fl_xid(overlay_)); + Fl_Double_Window::flush(0); + XMapWindow(fl_display, fl_xid(overlay_)); + return; + } +#endif + int erase_overlay = (damage()&FL_DAMAGE_OVERLAY); + clear_damage((uchar)(damage()&~FL_DAMAGE_OVERLAY)); + Fl_Double_Window::flush(erase_overlay); + if (overlay_ == this) draw_overlay(); +} + +void Fl_Overlay_Window::resize(int X, int Y, int W, int H) { + Fl_Double_Window::resize(X,Y,W,H); + if (overlay_ && overlay_!=this) overlay_->resize(0,0,w(),h()); +} + +Fl_Overlay_Window::~Fl_Overlay_Window() { + hide(); +// delete overlay; this is done by ~Fl_Group +} + +#if !HAVE_OVERLAY + +int Fl_Overlay_Window::can_do_overlay() {return 0;} + +void Fl_Overlay_Window::redraw_overlay() { + overlay_ = this; + clear_damage((uchar)(damage()|FL_DAMAGE_OVERLAY)); + Fl::damage(FL_DAMAGE_CHILD); +} + +#else + +extern XVisualInfo *fl_find_overlay_visual(); +extern XVisualInfo *fl_overlay_visual; +extern Colormap fl_overlay_colormap; +extern unsigned long fl_transparent_pixel; +static GC gc; // the GC used by all X windows +extern uchar fl_overlay; // changes how fl_color(x) works + +class _Fl_Overlay : public Fl_Window { + friend class Fl_Overlay_Window; + void flush(); + void show(); +public: + _Fl_Overlay(int x, int y, int w, int h) : + Fl_Window(x,y,w,h) {set_flag(INACTIVE);} +}; + +int Fl_Overlay_Window::can_do_overlay() { + return fl_find_overlay_visual() != 0; +} + +void _Fl_Overlay::show() { + if (shown()) {Fl_Window::show(); return;} + fl_background_pixel = int(fl_transparent_pixel); + Fl_X::make_xid(this, fl_overlay_visual, fl_overlay_colormap); + fl_background_pixel = -1; + // find the outermost window to tell wm about the colormap: + Fl_Window *w = window(); + for (;;) {Fl_Window *w1 = w->window(); if (!w1) break; w = w1;} + XSetWMColormapWindows(fl_display, fl_xid(w), &(Fl_X::i(this)->xid), 1); +} + +void _Fl_Overlay::flush() { + fl_window = fl_xid(this); + if (!gc) gc = XCreateGC(fl_display, fl_xid(this), 0, 0); + fl_gc = gc; + fl_overlay = 1; + Fl_Overlay_Window *w = (Fl_Overlay_Window *)parent(); + Fl_X *myi = Fl_X::i(this); + if (damage() != FL_DAMAGE_EXPOSE) XClearWindow(fl_display, fl_xid(this)); + fl_clip_region(myi->region); myi->region = 0; + w->draw_overlay(); + fl_overlay = 0; +} + +void Fl_Overlay_Window::redraw_overlay() { + if (!fl_display) return; // this prevents fluid -c from opening display + if (!overlay_) { + if (can_do_overlay()) { + Fl_Group::current(this); + overlay_ = new _Fl_Overlay(0,0,w(),h()); + Fl_Group::current(0); + } else { + overlay_ = this; // fake the overlay + } + } + if (shown()) { + if (overlay_ == this) { + clear_damage(damage()|FL_DAMAGE_OVERLAY); + Fl::damage(FL_DAMAGE_CHILD); + } else if (!overlay_->shown()) + overlay_->show(); + else + overlay_->redraw(); + } +} + +#endif + +// +// End of "$Id: Fl_Overlay_Window.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Pack.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Pack.cxx new file mode 100644 index 000000000..29d43af9c --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Pack.cxx @@ -0,0 +1,147 @@ +// +// "$Id: Fl_Pack.cxx 5981 2007-11-19 16:21:19Z matt $" +// +// Packing widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2006 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Based on code by Curtis Edwards +// Group that compresses all it's children together and resizes to surround +// them on each redraw (only if box() is zero) +// Bugs: ? + +#include +#include +#include + +Fl_Pack::Fl_Pack(int X, int Y, int W, int H,const char *l) +: Fl_Group(X, Y, W, H, l) { + resizable(0); + spacing_ = 0; + // type(VERTICAL); // already set like this +} + +void Fl_Pack::draw() { + int tx = x()+Fl::box_dx(box()); + int ty = y()+Fl::box_dy(box()); + int tw = w()-Fl::box_dw(box()); + int th = h()-Fl::box_dh(box()); + int rw, rh; + int current_position = horizontal() ? tx : ty; + int maximum_position = current_position; + uchar d = damage(); + Fl_Widget*const* a = array(); + if (horizontal()) { + rw = -spacing_; + rh = th; + + for (int i = children(); i--;) + if (child(i)->visible()) { + if (child(i) != this->resizable()) rw += child(i)->w(); + rw += spacing_; + } + } else { + rw = tw; + rh = -spacing_; + + for (int i = children(); i--;) + if (child(i)->visible()) { + if (child(i) != this->resizable()) rh += child(i)->h(); + rh += spacing_; + } + } + for (int i = children(); i--;) { + Fl_Widget* o = *a++; + if (o->visible()) { + int X,Y,W,H; + if (horizontal()) { + X = current_position; + W = o->w(); + Y = ty; + H = th; + } else { + X = tx; + W = tw; + Y = current_position; + H = o->h(); + } + // Last child, if resizable, takes all remaining room + if(i == 0 && o == this->resizable()) { + if(horizontal()) + W = tw - rw; + else + H = th - rh; + } + if (spacing_ && current_position>maximum_position && box() && + (X != o->x() || Y != o->y() || d&FL_DAMAGE_ALL)) { + fl_color(color()); + if (horizontal()) + fl_rectf(maximum_position, ty, spacing_, th); + else + fl_rectf(tx, maximum_position, tw, spacing_); + } + if (X != o->x() || Y != o->y() || W != o->w() || H != o->h()) { + o->resize(X,Y,W,H); + o->clear_damage(FL_DAMAGE_ALL); + } + if (d&FL_DAMAGE_ALL) { + draw_child(*o); + draw_outside_label(*o); + } else update_child(*o); + // child's draw() can change it's size, so use new size: + current_position += (horizontal() ? o->w() : o->h()); + if (current_position > maximum_position) + maximum_position = current_position; + current_position += spacing_; + } + } + + if (horizontal()) { + if (maximum_position < tx+tw && box()) { + fl_color(color()); + fl_rectf(maximum_position, ty, tx+tw-maximum_position, th); + } + tw = maximum_position-tx; + } else { + if (maximum_position < ty+th && box()) { + fl_color(color()); + fl_rectf(tx, maximum_position, tw, ty+th-maximum_position); + } + th = maximum_position-ty; + } + + tw += Fl::box_dw(box()); if (tw <= 0) tw = 1; + th += Fl::box_dh(box()); if (th <= 0) th = 1; + if (tw != w() || th != h()) { + Fl_Widget::resize(x(),y(),tw,th); + d = FL_DAMAGE_ALL; + } + if (d&FL_DAMAGE_ALL) { + draw_box(); + draw_label(); + } +} + +// +// End of "$Id: Fl_Pack.cxx 5981 2007-11-19 16:21:19Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Pixmap.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Pixmap.cxx new file mode 100644 index 000000000..382b692bf --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Pixmap.cxx @@ -0,0 +1,495 @@ +// +// "$Id: Fl_Pixmap.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Pixmap drawing code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Draws X pixmap data, keeping it stashed in a server pixmap so it +// redraws fast. + +// See fl_draw_pixmap.cxx for code used to get the actual data into pixmap. +// Implemented without using the xpm library (which I can't use because +// it interferes with the color cube used by fl_draw_image). + +#include +#include +#include +#include +#include +#include + +#include +#include "flstring.h" +#include + +#ifdef WIN32 +extern void fl_release_dc(HWND, HDC); // located in Fl_win32.cxx +#endif + +#ifdef __APPLE_QUARTZ__ +extern Fl_Offscreen fl_create_offscreen_with_alpha(int w, int h); +#endif + +extern uchar **fl_mask_bitmap; // used by fl_draw_pixmap.cxx to store mask +void fl_restore_clip(); // in fl_rect.cxx + +void Fl_Pixmap::measure() { + int W, H; + + // ignore empty or bad pixmap data: + if (w()<0 && data()) { + fl_measure_pixmap(data(), W, H); + w(W); h(H); + } +} + +void Fl_Pixmap::draw(int XP, int YP, int WP, int HP, int cx, int cy) { + // ignore empty or bad pixmap data: + if (!data()) { + draw_empty(XP, YP); + return; + } + if (w()<0) measure(); + if (WP==-1) { + WP = w(); + HP = h(); + } + if (!w()) { + draw_empty(XP, YP); + return; + } + // account for current clip region (faster on Irix): + int X,Y,W,H; fl_clip_box(XP,YP,WP,HP,X,Y,W,H); + cx += X-XP; cy += Y-YP; + // clip the box down to the size of image, quit if empty: + if (cx < 0) {W += cx; X -= cx; cx = 0;} + if (cx+W > w()) W = w()-cx; + if (W <= 0) return; + if (cy < 0) {H += cy; Y -= cy; cy = 0;} + if (cy+H > h()) H = h()-cy; + if (H <= 0) return; + if (!id) { +#ifdef __APPLE_QUARTZ__ + id = fl_create_offscreen_with_alpha(w(), h()); + fl_begin_offscreen((Fl_Offscreen)id); + fl_draw_pixmap(data(), 0, 0, FL_GREEN); + fl_end_offscreen(); +#else + id = fl_create_offscreen(w(), h()); + fl_begin_offscreen((Fl_Offscreen)id); + uchar *bitmap = 0; + fl_mask_bitmap = &bitmap; + fl_draw_pixmap(data(), 0, 0, FL_BLACK); + fl_mask_bitmap = 0; + if (bitmap) { + mask = fl_create_bitmask(w(), h(), bitmap); + delete[] bitmap; + } + fl_end_offscreen(); +#endif + } +#ifdef WIN32 + if (mask) { + HDC new_gc = CreateCompatibleDC(fl_gc); + int save = SaveDC(new_gc); + SelectObject(new_gc, (void*)mask); + BitBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, SRCAND); + SelectObject(new_gc, (void*)id); + BitBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, SRCPAINT); + RestoreDC(new_gc,save); + DeleteDC(new_gc); + } else { + fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)id, cx, cy); + } +#elif defined(__APPLE_QD__) + if (mask) { + Rect src, dst; + src.left = cx; src.right = cx+W; + src.top = cy; src.bottom = cy+H; + dst.left = X; dst.right = X+W; + dst.top = Y; dst.bottom = Y+H; + RGBColor rgb, oldfg, oldbg; + GetForeColor(&oldfg); + GetBackColor(&oldbg); + rgb.red = 0xffff; rgb.green = 0xffff; rgb.blue = 0xffff; + RGBBackColor(&rgb); + rgb.red = 0x0000; rgb.green = 0x0000; rgb.blue = 0x0000; + RGBForeColor(&rgb); + CopyMask(GetPortBitMapForCopyBits((GrafPtr)id), + GetPortBitMapForCopyBits((GrafPtr)mask), + GetPortBitMapForCopyBits(GetWindowPort(fl_window)), + &src, &src, &dst); + RGBBackColor(&oldbg); + RGBForeColor(&oldfg); + } else { + fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)id, cx, cy); + } +#elif defined(__APPLE_QUARTZ__) + fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)id, cx, cy); +#else + if (mask) { + // I can't figure out how to combine a mask with existing region, + // so cut the image down to a clipped rectangle: + int nx, ny; fl_clip_box(X,Y,W,H,nx,ny,W,H); + cx += nx-X; X = nx; + cy += ny-Y; Y = ny; + // make X use the bitmap as a mask: + XSetClipMask(fl_display, fl_gc, mask); + int ox = X-cx; if (ox < 0) ox += w(); + int oy = Y-cy; if (oy < 0) oy += h(); + XSetClipOrigin(fl_display, fl_gc, X-cx, Y-cy); + } + fl_copy_offscreen(X, Y, W, H, id, cx, cy); + if (mask) { + // put the old clip region back + XSetClipOrigin(fl_display, fl_gc, 0, 0); + fl_restore_clip(); + } +#endif +} + +Fl_Pixmap::~Fl_Pixmap() { + uncache(); + delete_data(); +} + +void Fl_Pixmap::uncache() { + if (id) { + fl_delete_offscreen((Fl_Offscreen)id); + id = 0; + } + + if (mask) { + fl_delete_bitmask((Fl_Bitmask)mask); + mask = 0; + } +} + +void Fl_Pixmap::label(Fl_Widget* widget) { + widget->image(this); +} + +void Fl_Pixmap::label(Fl_Menu_Item* m) { + Fl::set_labeltype(_FL_IMAGE_LABEL, labeltype, Fl_Image::measure); + m->label(_FL_IMAGE_LABEL, (const char*)this); +} + +void Fl_Pixmap::copy_data() { + if (alloc_data) return; + + char **new_data, // New data array + **new_row; // Current row in image + int i, // Looping var + ncolors, // Number of colors in image + chars_per_pixel,// Characters per color + chars_per_line; // Characters per line + + // Figure out how many colors there are, and how big they are... + sscanf(data()[0],"%*d%*d%d%d", &ncolors, &chars_per_pixel); + chars_per_line = chars_per_pixel * w() + 1; + + // Allocate memory for the new array... + if (ncolors < 0) new_data = new char *[h() + 2]; + else new_data = new char *[h() + ncolors + 1]; + + new_data[0] = new char[strlen(data()[0]) + 1]; + strcpy(new_data[0], data()[0]); + + // Copy colors... + if (ncolors < 0) { + // Copy FLTK colormap values... + ncolors = -ncolors; + new_row = new_data + 1; + *new_row = new char[ncolors * 4]; + memcpy(*new_row, data()[1], ncolors * 4); + ncolors = 1; + new_row ++; + } else { + // Copy standard XPM colormap values... + for (i = 0, new_row = new_data + 1; i < ncolors; i ++, new_row ++) { + *new_row = new char[strlen(data()[i + 1]) + 1]; + strcpy(*new_row, data()[i + 1]); + } + } + + // Copy image data... + for (i = 0; i < h(); i ++, new_row ++) { + *new_row = new char[chars_per_line]; + memcpy(*new_row, data()[i + ncolors + 1], chars_per_line); + } + + // Update pointers... + data((const char **)new_data, h() + ncolors + 1); + alloc_data = 1; +} + +Fl_Image *Fl_Pixmap::copy(int W, int H) { + Fl_Pixmap *new_image; // New pixmap + + // Optimize the simple copy where the width and height are the same... + if (W == w() && H == h()) { + // Make an exact copy of the image and return it... + new_image = new Fl_Pixmap(data()); + new_image->copy_data(); + return new_image; + } + if (W <= 0 || H <= 0) return 0; + + // OK, need to resize the image data; allocate memory and + char **new_data, // New array for image data + **new_row, // Pointer to row in image data + *new_ptr, // Pointer into new array + new_info[255]; // New information line + const char *old_ptr; // Pointer into old array + int i, // Looping var + c, // Channel number + sy, // Source coordinate + dx, dy, // Destination coordinates + xerr, yerr, // X & Y errors + xmod, ymod, // X & Y moduli + xstep, ystep; // X & Y step increments + int ncolors, // Number of colors in image + chars_per_pixel,// Characters per color + chars_per_line; // Characters per line + + // Figure out how many colors there are, and how big they are... + sscanf(data()[0],"%*d%*d%d%d", &ncolors, &chars_per_pixel); + chars_per_line = chars_per_pixel * W + 1; + + sprintf(new_info, "%d %d %d %d", W, H, ncolors, chars_per_pixel); + + // Figure out Bresenheim step/modulus values... + xmod = w() % W; + xstep = (w() / W) * chars_per_pixel; + ymod = h() % H; + ystep = h() / H; + + // Allocate memory for the new array... + if (ncolors < 0) new_data = new char *[H + 2]; + else new_data = new char *[H + ncolors + 1]; + new_data[0] = new char[strlen(new_info) + 1]; + strcpy(new_data[0], new_info); + + // Copy colors... + if (ncolors < 0) { + // Copy FLTK colormap values... + ncolors = -ncolors; + new_row = new_data + 1; + *new_row = new char[ncolors * 4]; + memcpy(*new_row, data()[1], ncolors * 4); + ncolors = 1; + new_row ++; + } else { + // Copy standard XPM colormap values... + for (i = 0, new_row = new_data + 1; i < ncolors; i ++, new_row ++) { + *new_row = new char[strlen(data()[i + 1]) + 1]; + strcpy(*new_row, data()[i + 1]); + } + } + + // Scale the image using a nearest-neighbor algorithm... + for (dy = H, sy = 0, yerr = H; dy > 0; dy --, new_row ++) { + *new_row = new char[chars_per_line]; + new_ptr = *new_row; + + for (dx = W, xerr = W, old_ptr = data()[sy + ncolors + 1]; + dx > 0; + dx --) { + for (c = 0; c < chars_per_pixel; c ++) *new_ptr++ = old_ptr[c]; + + old_ptr += xstep; + xerr -= xmod; + + if (xerr <= 0) { + xerr += W; + old_ptr += chars_per_pixel; + } + } + + *new_ptr = '\0'; + sy += ystep; + yerr -= ymod; + if (yerr <= 0) { + yerr += H; + sy ++; + } + } + + new_image = new Fl_Pixmap((char*const*)new_data); + new_image->alloc_data = 1; + + return new_image; +} + +void Fl_Pixmap::color_average(Fl_Color c, float i) { + // Delete any existing pixmap/mask objects... + uncache(); + + // Allocate memory as needed... + copy_data(); + + // Get the color to blend with... + uchar r, g, b; + unsigned ia, ir, ig, ib; + + Fl::get_color(c, r, g, b); + if (i < 0.0f) i = 0.0f; + else if (i > 1.0f) i = 1.0f; + + ia = (unsigned)(256 * i); + ir = r * (256 - ia); + ig = g * (256 - ia); + ib = b * (256 - ia); + + // Update the colormap to do the blend... + char line[255]; // New colormap line + int color, // Looping var + ncolors, // Number of colors in image + chars_per_pixel;// Characters per color + + + sscanf(data()[0],"%*d%*d%d%d", &ncolors, &chars_per_pixel); + + if (ncolors < 0) { + // Update FLTK colormap... + ncolors = -ncolors; + uchar *cmap = (uchar *)(data()[1]); + for (color = 0; color < ncolors; color ++, cmap += 4) { + cmap[1] = (ia * cmap[1] + ir) >> 8; + cmap[2] = (ia * cmap[2] + ig) >> 8; + cmap[3] = (ia * cmap[3] + ib) >> 8; + } + } else { + // Update standard XPM colormap... + for (color = 0; color < ncolors; color ++) { + // look for "c word", or last word if none: + const char *p = data()[color + 1] + chars_per_pixel + 1; + const char *previous_word = p; + for (;;) { + while (*p && isspace(*p)) p++; + char what = *p++; + while (*p && !isspace(*p)) p++; + while (*p && isspace(*p)) p++; + if (!*p) {p = previous_word; break;} + if (what == 'c') break; + previous_word = p; + while (*p && !isspace(*p)) p++; + } + + if (fl_parse_color(p, r, g, b)) { + r = (ia * r + ir) >> 8; + g = (ia * g + ig) >> 8; + b = (ia * b + ib) >> 8; + + if (chars_per_pixel > 1) sprintf(line, "%c%c c #%02X%02X%02X", + data()[color + 1][0], + data()[color + 1][1], r, g, b); + else sprintf(line, "%c c #%02X%02X%02X", data()[color + 1][0], r, g, b); + + delete[] (char *)data()[color + 1]; + ((char **)data())[color + 1] = new char[strlen(line) + 1]; + strcpy((char *)data()[color + 1], line); + } + } + } +} + +void Fl_Pixmap::delete_data() { + if (alloc_data) { + for (int i = 0; i < count(); i ++) delete[] (char *)data()[i]; + delete[] (char **)data(); + } +} + +void Fl_Pixmap::set_data(const char * const * p) { + int height, // Number of lines in image + ncolors; // Number of colors in image + + if (p) { + sscanf(p[0],"%*d%d%d", &height, &ncolors); + if (ncolors < 0) data(p, height + 2); + else data(p, height + ncolors + 1); + } +} + + +void Fl_Pixmap::desaturate() { + // Delete any existing pixmap/mask objects... + uncache(); + + // Allocate memory as needed... + copy_data(); + + // Update the colormap to grayscale... + char line[255]; // New colormap line + int i, // Looping var + ncolors, // Number of colors in image + chars_per_pixel;// Characters per color + uchar r, g, b; + + sscanf(data()[0],"%*d%*d%d%d", &ncolors, &chars_per_pixel); + + if (ncolors < 0) { + // Update FLTK colormap... + ncolors = -ncolors; + uchar *cmap = (uchar *)(data()[1]); + for (i = 0; i < ncolors; i ++, cmap += 4) { + g = (uchar)((cmap[1] * 31 + cmap[2] * 61 + cmap[3] * 8) / 100); + cmap[1] = cmap[2] = cmap[3] = g; + } + } else { + // Update standard XPM colormap... + for (i = 0; i < ncolors; i ++) { + // look for "c word", or last word if none: + const char *p = data()[i + 1] + chars_per_pixel + 1; + const char *previous_word = p; + for (;;) { + while (*p && isspace(*p)) p++; + char what = *p++; + while (*p && !isspace(*p)) p++; + while (*p && isspace(*p)) p++; + if (!*p) {p = previous_word; break;} + if (what == 'c') break; + previous_word = p; + while (*p && !isspace(*p)) p++; + } + + if (fl_parse_color(p, r, g, b)) { + g = (uchar)((r * 31 + g * 61 + b * 8) / 100); + + if (chars_per_pixel > 1) sprintf(line, "%c%c c #%02X%02X%02X", data()[i + 1][0], + data()[i + 1][1], g, g, g); + else sprintf(line, "%c c #%02X%02X%02X", data()[i + 1][0], g, g, g); + + delete[] (char *)data()[i + 1]; + ((char **)data())[i + 1] = new char[strlen(line) + 1]; + strcpy((char *)data()[i + 1], line); + } + } + } +} + +// +// End of "$Id: Fl_Pixmap.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Positioner.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Positioner.cxx new file mode 100644 index 000000000..a688a9a09 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Positioner.cxx @@ -0,0 +1,151 @@ +// +// "$Id: Fl_Positioner.cxx 5347 2006-08-23 12:57:42Z matt $" +// +// Positioner widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// The positioner widget from Forms, gives 2D input +// Written by: Mark Overmars + +#include +#include +#include + +static double flinear(double val, double smin, double smax, double gmin, double gmax) +{ + if (smin == smax) return gmax; + else return gmin + (gmax - gmin) * (val - smin) / (smax - smin); +} + +void Fl_Positioner::draw(int X, int Y, int W, int H) { + int x1 = X + 4; + int y1 = Y + 4; + int w1 = W - 2 * 4; + int h1 = H - 2 * 4; + int xx = int(flinear(xvalue(), xmin, xmax, x1, x1+w1-1)+.5); + int yy = int(flinear(yvalue(), ymin, ymax, y1, y1+h1-1)+.5); + draw_box(box(), X, Y, W, H, color()); + fl_color(selection_color()); + fl_xyline(x1, yy, x1+w1); + fl_yxline(xx, y1, y1+h1); +} + +void Fl_Positioner::draw() { + draw(x(), y(), w(), h()); + draw_label(); +} + +int Fl_Positioner::value(double X, double Y) { + clear_changed(); + if (X == xvalue_ && Y == yvalue_) return 0; + xvalue_ = X; yvalue_ = Y; + redraw(); + return 1; +} + +int Fl_Positioner::xvalue(double X) { + return(value(X, yvalue_)); +} + +int Fl_Positioner::yvalue(double Y) { + return(value(xvalue_, Y)); +} + +int Fl_Positioner::handle(int event, int X, int Y, int W, int H) { + switch (event) { + case FL_PUSH: + case FL_DRAG: + case FL_RELEASE: { + double x1 = X + 4; + double y1 = Y + 4; + double w1 = W - 2 * 4; + double h1 = H - 2 * 4; + double xx = flinear(Fl::event_x(), x1, x1+w1-1.0, xmin, xmax); + if (xstep_) xx = int(xx/xstep_+0.5) * xstep_; + if (xmin < xmax) { + if (xx < xmin) xx = xmin; + if (xx > xmax) xx = xmax; + } else { + if (xx > xmin) xx = xmin; + if (xx < xmax) xx = xmax; + } + double yy = flinear(Fl::event_y(), y1, y1+h1-1.0, ymin, ymax); + if (ystep_) yy = int(yy/ystep_+0.5) * ystep_; + if (ymin < ymax) { + if (yy < ymin) yy = ymin; + if (yy > ymax) yy = ymax; + } else { + if (yy > ymin) yy = ymin; + if (yy < ymax) yy = ymax; + } + if (xx != xvalue_ || yy != yvalue_) { + xvalue_ = xx; yvalue_ = yy; + set_changed(); + redraw(); + } } + if (!(when() & FL_WHEN_CHANGED || + (when() & FL_WHEN_RELEASE && event == FL_RELEASE))) return 1; + if (changed() || when()&FL_WHEN_NOT_CHANGED) { + if (event == FL_RELEASE) clear_changed(); + do_callback(); + } + return 1; + default: + return 0; + } +} + +int Fl_Positioner::handle(int e) { + return handle(e, x(), y(), w(), h()); +} + +Fl_Positioner::Fl_Positioner(int X, int Y, int W, int H, const char* l) +: Fl_Widget(X, Y, W, H, l) { + box(FL_DOWN_BOX); + selection_color(FL_RED); + align(FL_ALIGN_BOTTOM); + when(FL_WHEN_CHANGED); + xmin = ymin = 0; + xmax = ymax = 1; + xvalue_ = yvalue_ = .5; + xstep_ = ystep_ = 0; +} + +void Fl_Positioner::xbounds(double a, double b) { + if (a != xmin || b != xmax) { + xmin = a; xmax = b; + redraw(); + } +} + +void Fl_Positioner::ybounds(double a, double b) { + if (a != ymin || b != ymax) { + ymin = a; ymax = b; + redraw(); + } +} + +// +// End of "$Id: Fl_Positioner.cxx 5347 2006-08-23 12:57:42Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Preferences.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Preferences.cxx new file mode 100644 index 000000000..91c46cf27 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Preferences.cxx @@ -0,0 +1,1182 @@ +// +// "$Id: Fl_Preferences.cxx 6015 2008-01-09 21:23:51Z matt $" +// +// Preferences methods for the Fast Light Tool Kit (FLTK). +// +// Copyright 2002-2005 by Matthias Melcher. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + + +#include +#include +#include + +#include +#include +#include +#include "flstring.h" +#include + +#if defined(WIN32) && !defined(__CYGWIN__) +# include +# include +// Visual C++ 2005 incorrectly displays a warning about the use of POSIX APIs +// on Windows, which is supposed to be POSIX compliant... +# define access _access +# define mkdir _mkdir +#elif defined (__APPLE__) +# include +# include +#else +# include +#endif + + +char Fl_Preferences::nameBuffer[128]; + + +/** + * create the initial preferences base + * - root: machine or user preferences + * - vendor: unique identification of author or vendor of application + * Must be a valid directory name. + * - application: vendor unique application name, i.e. "PreferencesTest" + * multiple preferences files can be created per application. + * Must be a valid file name. + * example: Fl_Preferences base( Fl_Preferences::USER, "fltk.org", "test01"); + */ +Fl_Preferences::Fl_Preferences( Root root, const char *vendor, const char *application ) +{ + node = new Node( "." ); + rootNode = new RootNode( this, root, vendor, application ); +} + + +/** + * create the initial preferences base + * - path: an application-supplied path + * example: Fl_Preferences base( "/usr/foo" ); + */ +Fl_Preferences::Fl_Preferences( const char *path, const char *vendor, const char *application ) +{ + node = new Node( "." ); + rootNode = new RootNode( this, path, vendor, application ); +} + + +/** + * create a Preferences node in relation to a parent node for reading and writing + * - parent: base name for group + * - group: group name (can contain '/' seperated group names) + * example: Fl_Preferences colors( base, "setup/colors" ); + */ +Fl_Preferences::Fl_Preferences( Fl_Preferences &parent, const char *key ) +{ + rootNode = parent.rootNode; + node = parent.node->addChild( key ); +} + + +/** + * create a Preferences node in relation to a parent node for reading and writing + * - parent: base name for group + * - group: group name (can contain '/' seperated group names) + * example: Fl_Preferences colors( base, "setup/colors" ); + */ +Fl_Preferences::Fl_Preferences( Fl_Preferences *parent, const char *key ) +{ + rootNode = parent->rootNode; + node = parent->node->addChild( key ); +} + + +/** + * destroy individual keys + * - destroying the base preferences will flush changes to the prefs file + * - after destroying the base, none of the depending preferences must be read or written + */ +Fl_Preferences::~Fl_Preferences() +{ + if (node && !node->parent()) delete rootNode; + // DO NOT delete nodes! The root node will do that after writing the preferences + // zero all pointer to avoid memory errors, event though + // Valgrind does not complain (Cygwind does though) + node = 0L; + rootNode = 0L; +} + + +/** + * return the number of groups that are contained within a group + * example: int n = base.groups(); + */ +int Fl_Preferences::groups() +{ + return node->nChildren(); +} + + +/** + * return the group name of the n'th group + * - there is no guaranteed order of group names + * - the index must be within the range given by groups() + * example: printf( "Group(%d)='%s'\n", ix, base.group(ix) ); + */ +const char *Fl_Preferences::group( int ix ) +{ + return node->child( ix ); +} + + +/** + * return 1, if a group with this name exists + * example: if ( base.groupExists( "setup/colors" ) ) ... + */ +char Fl_Preferences::groupExists( const char *key ) +{ + return node->search( key ) ? 1 : 0 ; +} + + +/** + * delete a group + * example: setup.deleteGroup( "colors/buttons" ); + */ +char Fl_Preferences::deleteGroup( const char *key ) +{ + Node *nd = node->search( key ); + if ( nd ) return nd->remove(); + return 0; +} + + +/** + * return the number of entries (name/value) pairs for a group + * example: int n = buttonColor.entries(); + */ +int Fl_Preferences::entries() +{ + return node->nEntry; +} + + +/** + * return the name of an entry + * - there is no guaranteed order of entry names + * - the index must be within the range given by entries() + * example: printf( "Entry(%d)='%s'\n", ix, buttonColor.entry(ix) ); + */ +const char *Fl_Preferences::entry( int ix ) +{ + return node->entry[ix].name; +} + + +/** + * return 1, if an entry with this name exists + * example: if ( buttonColor.entryExists( "red" ) ) ... + */ +char Fl_Preferences::entryExists( const char *key ) +{ + return node->getEntry( key )>=0 ? 1 : 0 ; +} + + +/** + * remove a single entry (name/value pair) + * example: buttonColor.deleteEntry( "red" ); + */ +char Fl_Preferences::deleteEntry( const char *key ) +{ + return node->deleteEntry( key ); +} + + +/** + * read an entry from the group + */ +char Fl_Preferences::get( const char *key, int &value, int defaultValue ) +{ + const char *v = node->get( key ); + value = v ? atoi( v ) : defaultValue; + return ( v != 0 ); +} + + +/** + * set an entry (name/value pair) + */ +char Fl_Preferences::set( const char *key, int value ) +{ + sprintf( nameBuffer, "%d", value ); + node->set( key, nameBuffer ); + return 1; +} + + +/** + * read an entry from the group + */ +char Fl_Preferences::get( const char *key, float &value, float defaultValue ) +{ + const char *v = node->get( key ); + value = v ? (float)atof( v ) : defaultValue; + return ( v != 0 ); +} + + +/** + * set an entry (name/value pair) + */ +char Fl_Preferences::set( const char *key, float value ) +{ + sprintf( nameBuffer, "%g", value ); + node->set( key, nameBuffer ); + return 1; +} + + +/** + * set an entry (name/value pair) + */ +char Fl_Preferences::set( const char *key, float value, int precision ) +{ + sprintf( nameBuffer, "%.*g", precision, value ); + node->set( key, nameBuffer ); + return 1; +} + + +/** + * read an entry from the group + */ +char Fl_Preferences::get( const char *key, double &value, double defaultValue ) +{ + const char *v = node->get( key ); + value = v ? atof( v ) : defaultValue; + return ( v != 0 ); +} + + +/** + * set an entry (name/value pair) + */ +char Fl_Preferences::set( const char *key, double value ) +{ + sprintf( nameBuffer, "%g", value ); + node->set( key, nameBuffer ); + return 1; +} + + +/** + * set an entry (name/value pair) + */ +char Fl_Preferences::set( const char *key, double value, int precision ) +{ + sprintf( nameBuffer, "%.*g", precision, value ); + node->set( key, nameBuffer ); + return 1; +} + + +// remove control sequences from a string +static char *decodeText( const char *src ) +{ + int len = 0; + const char *s = src; + for ( ; *s; s++, len++ ) + { + if ( *s == '\\' ) + if ( isdigit( s[1] ) ) s+=3; else s+=1; + } + char *dst = (char*)malloc( len+1 ), *d = dst; + for ( s = src; *s; s++ ) + { + char c = *s; + if ( c == '\\' ) + { + if ( s[1] == '\\' ) { *d++ = c; s++; } + else if ( s[1] == 'n' ) { *d++ = '\n'; s++; } + else if ( s[1] == 'r' ) { *d++ = '\r'; s++; } + else if ( isdigit( s[1] ) ) { *d++ = ((s[1]-'0')<<6) + ((s[2]-'0')<<3) + (s[3]-'0'); s+=3; } + else s++; // error + } + else + *d++ = c; + } + *d = 0; + return dst; +} + + +/** + * read a text entry from the group + * the text will be moved into the given text buffer + * text will be clipped to the buffer size + */ +char Fl_Preferences::get( const char *key, char *text, const char *defaultValue, int maxSize ) +{ + const char *v = node->get( key ); + if ( v && strchr( v, '\\' ) ) { + char *w = decodeText( v ); + strlcpy(text, w, maxSize); + free( w ); + return 1; + } + if ( !v ) v = defaultValue; + if ( v ) strlcpy(text, v, maxSize); + else text = 0; + return ( v != defaultValue ); +} + + +/** + * read a text entry from the group + * 'text' will be changed to point to a new text buffer + * the text buffer must be deleted with 'free(text)' by the user. + */ +char Fl_Preferences::get( const char *key, char *&text, const char *defaultValue ) +{ + const char *v = node->get( key ); + if ( v && strchr( v, '\\' ) ) + { + text = decodeText( v ); + return 1; + } + if ( !v ) v = defaultValue; + if ( v ) + text = strdup( v ); + else + text = 0; + return ( v != defaultValue ); +} + + +/** + * set an entry (name/value pair) + */ +char Fl_Preferences::set( const char *key, const char *text ) +{ + const char *s = text ? text : ""; + int n=0, ns=0; + for ( ; *s; s++ ) { n++; if ( *s<32 || *s=='\\' || *s==0x7f ) ns+=4; } + if ( ns ) + { + char *buffer = (char*)malloc( n+ns+1 ), *d = buffer; + for ( s=text; *s; ) + { + char c = *s; + if ( c=='\\' ) { *d++ = '\\'; *d++ = '\\'; s++; } + else if ( c=='\n' ) { *d++ = '\\'; *d++ = 'n'; s++; } + else if ( c=='\r' ) { *d++ = '\\'; *d++ = 'r'; s++; } + else if ( c<32 || c==0x7f ) + { *d++ = '\\'; *d++ = '0'+((c>>6)&3); *d++ = '0'+((c>>3)&7); *d++ = '0'+(c&7); s++; } + else *d++ = *s++; + } + *d = 0; + node->set( key, buffer ); + free( buffer ); + } + else + node->set( key, text ); + return 1; +} + + +// convert a hex string to binary data +static void *decodeHex( const char *src, int &size ) +{ + size = strlen( src )/2; + unsigned char *data = (unsigned char*)malloc( size ), *d = data; + const char *s = src; + int i; + + for ( i=size; i>0; i-- ) + { + int v; + char x = tolower(*s++); + if ( x >= 'a' ) v = x-'a'+10; else v = x-'0'; + v = v<<4; + x = tolower(*s++); + if ( x >= 'a' ) v += x-'a'+10; else v += x-'0'; + *d++ = (uchar)v; + } + + return (void*)data; +} + + +/** + * read a binary entry from the group + * the data will be moved into the given destination buffer + * data will be clipped to the buffer size + */ +char Fl_Preferences::get( const char *key, void *data, const void *defaultValue, int defaultSize, int maxSize ) +{ + const char *v = node->get( key ); + if ( v ) + { + int dsize; + void *w = decodeHex( v, dsize ); + memmove( data, w, dsize>maxSize?maxSize:dsize ); + free( w ); + return 1; + } + if ( defaultValue ) + memmove( data, defaultValue, defaultSize>maxSize?maxSize:defaultSize ); + return 0; +} + + +/** + * read a binary entry from the group + * 'data' will be changed to point to a new data buffer + * the data buffer must be deleted with 'free(data)' by the user. + */ +char Fl_Preferences::get( const char *key, void *&data, const void *defaultValue, int defaultSize ) +{ + const char *v = node->get( key ); + if ( v ) + { + int dsize; + data = decodeHex( v, dsize ); + return 1; + } + if ( defaultValue ) + { + data = (void*)malloc( defaultSize ); + memmove( data, defaultValue, defaultSize ); + } + else + data = 0; + return 0; +} + + +/** + * set an entry (name/value pair) + */ +char Fl_Preferences::set( const char *key, const void *data, int dsize ) +{ + char *buffer = (char*)malloc( dsize*2+1 ), *d = buffer;; + unsigned char *s = (unsigned char*)data; + for ( ; dsize>0; dsize-- ) + { + static char lu[] = "0123456789abcdef"; + unsigned char v = *s++; + *d++ = lu[v>>4]; + *d++ = lu[v&0xf]; + } + *d = 0; + node->set( key, buffer ); + free( buffer ); + return 1; +} + + +/** + * return the size of the value part of an entry + */ +int Fl_Preferences::size( const char *key ) +{ + const char *v = node->get( key ); + return v ? strlen( v ) : 0 ; +} + +/** + * creates a path that is related to the preferences file + * and that is usable for application data beyond what is covered + * by Fl_Preferences. + * - 'getUserdataPath' actually creates the directory + * - 'path' must be large enough to receive a complete file path + * example: + * Fl_Preferences prefs( USER, "matthiasm.com", "test" ); + * char path[FL_PATH_MAX]; + * prefs.getUserdataPath( path ); + * sample returns: + * Win32: c:/Documents and Settings/matt/Application Data/matthiasm.com/test/ + * prefs: c:/Documents and Settings/matt/Application Data/matthiasm.com/test.prefs + */ +char Fl_Preferences::getUserdataPath( char *path, int pathlen ) +{ + if ( rootNode ) + return rootNode->getPath( path, pathlen ); + return 0; +} + +/** + * write all preferences to disk + * - this function works only with the base preference group + * - this function is rarely used as deleting the base preferences flushes automatically + */ +void Fl_Preferences::flush() +{ + if ( rootNode && node->dirty() ) + rootNode->write(); +} + +//----------------------------------------------------------------------------- +// helper class to create dynamic group and entry names on the fly +// + +/** + * create a group name or entry name on the fly + * - this version creates a simple unsigned integer as an entry name + * example: + * int n, i; + * Fl_Preferences prev( appPrefs, "PreviousFiles" ); + * prev.get( "n", 0 ); + * for ( i=0; inode->dirty() ) + write(); + if ( filename_ ) { + free( filename_ ); + filename_ = 0L; + } + if ( vendor_ ) { + free( vendor_ ); + vendor_ = 0L; + } + if ( application_ ) { + free( application_ ); + application_ = 0L; + } + delete prefs_->node; + prefs_->node = 0L; +} + +// read a preferences file and construct the group tree and with all entry leafs +int Fl_Preferences::RootNode::read() +{ + char buf[1024]; + FILE *f = fopen( filename_, "rb" ); + if ( !f ) return 0; + fgets( buf, 1024, f ); + fgets( buf, 1024, f ); + fgets( buf, 1024, f ); + Node *nd = prefs_->node; + for (;;) + { + if ( !fgets( buf, 1024, f ) ) break; // EOF or Error + if ( buf[0]=='[' ) // read a new group + { + int end = strcspn( buf+1, "]\n\r" ); + buf[ end+1 ] = 0; + nd = prefs_->node->find( buf+1 ); + } + else if ( buf[0]=='+' ) // + { // value of previous name/value pair spans multiple lines + int end = strcspn( buf+1, "\n\r" ); + if ( end != 0 ) // if entry is not empty + { + buf[ end+1 ] = 0; + nd->add( buf+1 ); + } + } + else // read a name/value pair + { + int end = strcspn( buf, "\n\r" ); + if ( end != 0 ) // if entry is not empty + { + buf[ end ] = 0; + nd->set( buf ); + } + } + } + fclose( f ); + return 0; +} + +// write the group tree and all entry leafs +int Fl_Preferences::RootNode::write() +{ + makePathForFile(filename_); + FILE *f = fopen( filename_, "wb" ); + if ( !f ) return 1; + fprintf( f, "; FLTK preferences file format 1.0\n" ); + fprintf( f, "; vendor: %s\n", vendor_ ); + fprintf( f, "; application: %s\n", application_ ); + prefs_->node->write( f ); + fclose( f ); + return 0; +} + +// get the path to the preferences directory +char Fl_Preferences::RootNode::getPath( char *path, int pathlen ) +{ + strlcpy( path, filename_, pathlen); + + char *s; + for ( s = path; *s; s++ ) if ( *s == '\\' ) *s = '/'; + s = strrchr( path, '.' ); + if ( !s ) return 0; + *s = 0; + char ret = makePath( path ); + strcpy( s, "/" ); + return ret; +} + +// create a node that represents a group +// - path must be a single word, prferable alnum(), dot and underscore only. Space is ok. +Fl_Preferences::Node::Node( const char *path ) +{ + if ( path ) path_ = strdup( path ); else path_ = 0; + child_ = 0; next_ = 0; parent_ = 0; + entry = 0; + nEntry = NEntry = 0; + dirty_ = 0; +} + +// delete this and all depending nodes +Fl_Preferences::Node::~Node() +{ + Node *nx; + for ( Node *nd = child_; nd; nd = nx ) + { + nx = nd->next_; + delete nd; + } + child_ = 0L; + if ( entry ) + { + for ( int i = 0; i < nEntry; i++ ) + { + if ( entry[i].name ) { + free( entry[i].name ); + entry[i].name = 0L; + } + if ( entry[i].value ) { + free( entry[i].value ); + entry[i].value = 0L; + } + } + free( entry ); + entry = 0L; + nEntry = 0; + } + if ( path_ ) { + free( path_ ); + path_ = 0L; + } + next_ = 0L; + parent_ = 0L; +} + +// recursively check if any entry is dirty (was changed after loading a fresh prefs file) +char Fl_Preferences::Node::dirty() +{ + if ( dirty_ ) return 1; + if ( next_ && next_->dirty() ) return 1; + if ( child_ && child_->dirty() ) return 1; + return 0; +} + +// write this node (recursively from the last neighbor back to this) +// write all entries +// write all children +int Fl_Preferences::Node::write( FILE *f ) +{ + if ( next_ ) next_->write( f ); + fprintf( f, "\n[%s]\n\n", path_ ); + for ( int i = 0; i < nEntry; i++ ) + { + char *src = entry[i].value; + if ( src ) + { // hack it into smaller pieces if needed + fprintf( f, "%s:", entry[i].name ); + int cnt; + for ( cnt = 0; cnt < 60; cnt++ ) + if ( src[cnt]==0 ) break; + fwrite( src, cnt, 1, f ); + fprintf( f, "\n" ); + src += cnt; + for (;*src;) + { + for ( cnt = 0; cnt < 80; cnt++ ) + if ( src[cnt]==0 ) break; + fputc( '+', f ); + fwrite( src, cnt, 1, f ); + fputc( '\n', f ); + src += cnt; + } + } + else + fprintf( f, "%s\n", entry[i].name ); + } + if ( child_ ) child_->write( f ); + dirty_ = 0; + return 0; +} + +// set the parent node and create the full path +void Fl_Preferences::Node::setParent( Node *pn ) +{ + parent_ = pn; + next_ = pn->child_; + pn->child_ = this; + sprintf( nameBuffer, "%s/%s", pn->path_, path_ ); + free( path_ ); + path_ = strdup( nameBuffer ); +} + +// add a child to this node and set its path (try to find it first...) +Fl_Preferences::Node *Fl_Preferences::Node::addChild( const char *path ) +{ + sprintf( nameBuffer, "%s/%s", path_, path ); + char *name = strdup( nameBuffer ); + Node *nd = find( name ); + free( name ); + dirty_ = 1; + return nd; +} + +// create and set, or change an entry within this node +void Fl_Preferences::Node::set( const char *name, const char *value ) +{ + for ( int i=0; i= sizeof( nameBuffer ) ) + len = sizeof( nameBuffer ); + strlcpy( nameBuffer, line, len ); + set( nameBuffer, c+1 ); + } + else + set( line, "" ); + } + dirty_ = dirt; +} + +// add more data to an existing entry +void Fl_Preferences::Node::add( const char *line ) +{ + if ( lastEntrySet<0 || lastEntrySet>=nEntry ) return; + char *&dst = entry[ lastEntrySet ].value; + int a = strlen( dst ); + int b = strlen( line ); + dst = (char*)realloc( dst, a+b+1 ); + memcpy( dst+a, line, b+1 ); + dirty_ = 1; +} + +// get the value for a name, returns 0 if no such name +const char *Fl_Preferences::Node::get( const char *name ) +{ + int i = getEntry( name ); + return i>=0 ? entry[i].value : 0 ; +} + +// find the index of an entry, returns -1 if no such entry +int Fl_Preferences::Node::getEntry( const char *name ) +{ + for ( int i=0; inext_ ) + { + Node *nn = nd->find( path ); + if ( nn ) return nn; + } + const char *s = path+len+1; + const char *e = strchr( s, '/' ); + if (e) strlcpy( nameBuffer, s, e-s+1 ); + else strlcpy( nameBuffer, s, sizeof(nameBuffer)); + nd = new Node( nameBuffer ); + nd->setParent( this ); + return nd->find( path ); + } + } + return 0; +} + +// find a group somewhere in the tree starting here +// caller must not set 'offset' argument +// - if the node does not exist, 'search' returns NULL +// - if the pathname is "." (current node) return this node +// - if the pathname is "./" (root node) return the topmost node +// - if the pathname starts with "./", start the search at the root node instead +Fl_Preferences::Node *Fl_Preferences::Node::search( const char *path, int offset ) +{ + + if ( offset == 0 ) + { + if ( path[0] == '.' ) + { + if ( path[1] == 0 ) + { + return this; // user was searching for current node + } + else if ( path[1] == '/' ) + { + Node *nn = this; + while ( nn->parent_ ) nn = nn->parent_; + if ( path[2]==0 ) + { // user is searching for root ( "./" ) + return nn; + } + return nn->search( path+2, 2 ); // do a relative search on the root node + } + } + offset = strlen( path_ ) + 1; + } + + int len = strlen( path_ ); + if ( len < offset-1 ) return 0; + len -= offset; + if ( ( len <= 0 ) || ( strncmp( path, path_+offset, len ) == 0 ) ) + { + if ( len > 0 && path[ len ] == 0 ) + return this; + if ( len <= 0 || path[ len ] == '/' ) + { + for ( Node *nd = child_; nd; nd = nd->next_ ) + { + Node *nn = nd->search( path, offset ); + if ( nn ) return nn; + } + return 0; + } + } + return 0; +} + +// return the number of child nodes (groups) +int Fl_Preferences::Node::nChildren() +{ + int cnt = 0; + for ( Node *nd = child_; nd; nd = nd->next_ ) + cnt++; + return cnt; +} + +// return the n'th child node +const char *Fl_Preferences::Node::child( int ix ) +{ + Node *nd; + for ( nd = child_; nd; nd = nd->next_ ) + { + if ( !ix-- ) break; + } + if ( nd && nd->path_ ) + { + char *r = strrchr( nd->path_, '/' ); + return r ? r+1 : nd->path_ ; + } + return 0L ; +} + +// remove myself from the list and delete me (and all children) +char Fl_Preferences::Node::remove() +{ + Node *nd = 0, *np; + if ( parent_ ) + { + nd = parent_->child_; np = 0L; + for ( ; nd; np = nd, nd = nd->next_ ) + { + if ( nd == this ) + { + if ( np ) + np->next_ = nd->next_; + else + parent_->child_ = nd->next_; + break; + } + } + parent_->dirty_ = 1; + } + delete this; + return ( nd != 0 ); +} + + +// +// End of "$Id: Fl_Preferences.cxx 6015 2008-01-09 21:23:51Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Progress.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Progress.cxx new file mode 100644 index 000000000..1d26b0c9a --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Progress.cxx @@ -0,0 +1,117 @@ +// +// "$Id: Fl_Progress.cxx 5540 2006-11-12 20:44:12Z matt $" +// +// Progress bar widget routines. +// +// Copyright 2000-2005 by Michael Sweet. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +// Contents: +// +// Fl_Progress::draw() - Draw the check button. +// Fl_Progress::Fl_Progress() - Construct a Fl_Progress widget. +// + +// +// Include necessary header files... +// + +#include +#include +#include + + +// +// Fl_Progress is a progress bar widget based off Fl_Widget that shows a +// standard progress bar... +// + + +// +// 'Fl_Progress::draw()' - Draw the check button. +// + +void Fl_Progress::draw() +{ + int progress; // Size of progress bar... + int bx, by, bw, bh; // Box areas... + int tx, tw; // Temporary X + width + + + // Get the box borders... + bx = Fl::box_dx(box()); + by = Fl::box_dy(box()); + bw = Fl::box_dw(box()); + bh = Fl::box_dh(box()); + + tx = x() + bx; + tw = w() - bw; + + // Draw the progress bar... + if (maximum_ > minimum_) + progress = (int)(w() * (value_ - minimum_) / (maximum_ - minimum_) + 0.5f); + else + progress = 0; + + // Draw the box and label... + if (progress > 0) { + Fl_Color c = labelcolor(); + labelcolor(fl_contrast(labelcolor(), color2())); + + fl_clip(x(), y(), progress + bx, h()); + draw_box(box(), x(), y(), w(), h(), active_r() ? color2() : fl_inactive(color2())); + draw_label(tx, y() + by, tw, h() - bh); + fl_pop_clip(); + + labelcolor(c); + + if (progress +#include + +#define INITIALREPEAT .5 +#define REPEAT .1 + +void Fl_Repeat_Button::repeat_callback(void *v) { + Fl_Button *b = (Fl_Button*)v; + Fl::add_timeout(REPEAT,repeat_callback,b); + b->do_callback(); +} + +int Fl_Repeat_Button::handle(int event) { + int newval; + switch (event) { + case FL_HIDE: + case FL_DEACTIVATE: + case FL_RELEASE: + newval = 0; goto J1; + case FL_PUSH: + case FL_DRAG: + if (Fl::visible_focus()) Fl::focus(this); + newval = Fl::event_inside(this); + J1: + if (!active()) + newval = 0; + if (value(newval)) { + if (newval) { + Fl::add_timeout(INITIALREPEAT,repeat_callback,this); + do_callback(); + } else { + Fl::remove_timeout(repeat_callback,this); + } + } + return 1; + default: + return Fl_Button::handle(event); + } +} + +// +// End of "$Id: Fl_Repeat_Button.cxx 5219 2006-06-21 06:52:10Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Return_Button.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Return_Button.cxx new file mode 100644 index 000000000..360a91a6b --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Return_Button.cxx @@ -0,0 +1,72 @@ +// +// "$Id: Fl_Return_Button.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Return button widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include + +int fl_return_arrow(int x, int y, int w, int h) { + int size = w; if (h +#include +#include +#include + +int Fl_Roller::handle(int event) { + static int ipos; + int newpos = horizontal() ? Fl::event_x() : Fl::event_y(); + switch (event) { + case FL_PUSH: + if (Fl::visible_focus()) { + Fl::focus(this); + redraw(); + } + handle_push(); + ipos = newpos; + return 1; + case FL_DRAG: + handle_drag(clamp(round(increment(previous_value(),newpos-ipos)))); + return 1; + case FL_RELEASE: + handle_release(); + return 1; + case FL_KEYBOARD : + switch (Fl::event_key()) { + case FL_Up: + if (horizontal()) return 0; + handle_drag(clamp(increment(value(),-1))); + return 1; + case FL_Down: + if (horizontal()) return 0; + handle_drag(clamp(increment(value(),1))); + return 1; + case FL_Left: + if (!horizontal()) return 0; + handle_drag(clamp(increment(value(),-1))); + return 1; + case FL_Right: + if (!horizontal()) return 0; + handle_drag(clamp(increment(value(),1))); + return 1; + default: + return 0; + } + // break not required because of switch... + case FL_FOCUS : + case FL_UNFOCUS : + if (Fl::visible_focus()) { + redraw(); + return 1; + } else return 0; + case FL_ENTER : + case FL_LEAVE : + return 1; + default: + return 0; + } +} + +void Fl_Roller::draw() { + if (damage()&FL_DAMAGE_ALL) draw_box(); + int X = x()+Fl::box_dx(box()); + int Y = y()+Fl::box_dy(box()); + int W = w()-Fl::box_dw(box())-1; + int H = h()-Fl::box_dh(box())-1; + if (W<=0 || H <=0) return; + int offset = step() ? int(value()/step()) : 0; + const double ARC = 1.5; // 1/2 the number of radians visible + const double delta = .2; // radians per knurl + if (horizontal()) { // horizontal one + // draw shaded ends of wheel: + int h1 = W/4+1; // distance from end that shading starts + fl_color(color()); fl_rectf(X+h1,Y,W-2*h1,H); + for (int i=0; h1; i++) { + fl_color((Fl_Color)(FL_GRAY-i-1)); + int h2 = FL_GRAY-i-1 > FL_DARK3 ? 2*h1/3+1 : 0; + fl_rectf(X+h2,Y,h1-h2,H); + fl_rectf(X+W-h1,Y,h1-h2,H); + h1 = h2; + } + if (active_r()) { + // draw ridges: + double junk; + for (double yy = -ARC+modf(offset*sin(ARC)/(W/2)/delta,&junk)*delta;; + yy += delta) { + int yy1 = int((sin(yy)/sin(ARC)+1)*W/2); + if (yy1 <= 0) continue; else if (yy1 >= W-1) break; + fl_color(FL_DARK3); fl_yxline(X+yy1,Y+1,Y+H-1); + if (yy < 0) yy1--; else yy1++; + fl_color(FL_LIGHT1);fl_yxline(X+yy1,Y+1,Y+H-1); + } + // draw edges: + h1 = W/8+1; // distance from end the color inverts + fl_color(FL_DARK2); + fl_xyline(X+h1,Y+H-1,X+W-h1); + fl_color(FL_DARK3); + fl_yxline(X,Y+H,Y,X+h1); + fl_xyline(X+W-h1,Y,X+W); + fl_color(FL_LIGHT2); + fl_xyline(X+h1,Y-1,X+W-h1); + fl_yxline(X+W,Y,Y+H,X+W-h1); + fl_xyline(X+h1,Y+H,X); + } + } else { // vertical one + // draw shaded ends of wheel: + int h1 = H/4+1; // distance from end that shading starts + fl_color(color()); fl_rectf(X,Y+h1,W,H-2*h1); + for (int i=0; h1; i++) { + fl_color((Fl_Color)(FL_GRAY-i-1)); + int h2 = FL_GRAY-i-1 > FL_DARK3 ? 2*h1/3+1 : 0; + fl_rectf(X,Y+h2,W,h1-h2); + fl_rectf(X,Y+H-h1,W,h1-h2); + h1 = h2; + } + if (active_r()) { + // draw ridges: + double junk; + for (double yy = -ARC+modf(offset*sin(ARC)/(H/2)/delta,&junk)*delta; + ; yy += delta) { + int yy1 = int((sin(yy)/sin(ARC)+1)*H/2); + if (yy1 <= 0) continue; else if (yy1 >= H-1) break; + fl_color(FL_DARK3); fl_xyline(X+1,Y+yy1,X+W-1); + if (yy < 0) yy1--; else yy1++; + fl_color(FL_LIGHT1);fl_xyline(X+1,Y+yy1,X+W-1); + } + // draw edges: + h1 = H/8+1; // distance from end the color inverts + fl_color(FL_DARK2); + fl_yxline(X+W-1,Y+h1,Y+H-h1); + fl_color(FL_DARK3); + fl_xyline(X+W,Y,X,Y+h1); + fl_yxline(X,Y+H-h1,Y+H); + fl_color(FL_LIGHT2); + fl_yxline(X,Y+h1,Y+H-h1); + fl_xyline(X,Y+H,X+W,Y+H-h1); + fl_yxline(X+W,Y+h1,Y); + } + } + + if (Fl::focus() == this) draw_focus(FL_THIN_UP_FRAME, x(), y(), w(), h()); +} + +Fl_Roller::Fl_Roller(int X,int Y,int W,int H,const char* L) + : Fl_Valuator(X,Y,W,H,L) { + box(FL_UP_BOX); + step(1,1000); +} + +// +// End of "$Id: Fl_Roller.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Round_Button.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Round_Button.cxx new file mode 100644 index 000000000..fe8ffa28e --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Round_Button.cxx @@ -0,0 +1,44 @@ +// +// "$Id: Fl_Round_Button.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Round button for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// A subclass of Fl_Button that always draws as a round circle. This +// circle is smaller than the widget size and can be surrounded by +// another box type, for compatability with Forms. + +#include +#include + +Fl_Round_Button::Fl_Round_Button(int X,int Y,int W,int H, const char *l) +: Fl_Light_Button(X,Y,W,H,l) { + box(FL_NO_BOX); + down_box(FL_ROUND_DOWN_BOX); + selection_color(FL_FOREGROUND_COLOR); +} + +// +// End of "$Id: Fl_Round_Button.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Scroll.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Scroll.cxx new file mode 100644 index 000000000..ba3571c70 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Scroll.cxx @@ -0,0 +1,297 @@ +// +// "$Id: Fl_Scroll.cxx 5547 2006-11-16 23:17:13Z mike $" +// +// Scroll widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2006 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include + +// Clear all but the scrollbars... +void Fl_Scroll::clear() { + for (int i=children() - 1; i >= 0; i --) { + Fl_Widget* o = child(i); + if (o != &hscrollbar && o != &scrollbar) { + remove(o); + delete o; + } + } +} + +// Insure the scrollbars are the last children: +void Fl_Scroll::fix_scrollbar_order() { + Fl_Widget** a = (Fl_Widget**)array(); + if (a[children()-1] != &scrollbar) { + int i,j; for (i = j = 0; j < children(); j++) + if (a[j] != &hscrollbar && a[j] != &scrollbar) a[i++] = a[j]; + a[i++] = &hscrollbar; + a[i++] = &scrollbar; + } +} + +void Fl_Scroll::draw_clip(void* v,int X, int Y, int W, int H) { + fl_clip(X,Y,W,H); + Fl_Scroll* s = (Fl_Scroll*)v; + // erase background as needed... + switch (s->box()) { + case FL_NO_BOX : + case FL_UP_FRAME : + case FL_DOWN_FRAME : + case FL_THIN_UP_FRAME : + case FL_THIN_DOWN_FRAME : + case FL_ENGRAVED_FRAME : + case FL_EMBOSSED_FRAME : + case FL_BORDER_FRAME : + case _FL_SHADOW_FRAME : + case _FL_ROUNDED_FRAME : + case _FL_OVAL_FRAME : + case _FL_PLASTIC_UP_FRAME : + case _FL_PLASTIC_DOWN_FRAME : + if (s->parent() == (Fl_Group *)s->window() && Fl::scheme_bg_) { + Fl::scheme_bg_->draw(X-(X%((Fl_Tiled_Image *)Fl::scheme_bg_)->image()->w()), + Y-(Y%((Fl_Tiled_Image *)Fl::scheme_bg_)->image()->h()), + W+((Fl_Tiled_Image *)Fl::scheme_bg_)->image()->w(), + H+((Fl_Tiled_Image *)Fl::scheme_bg_)->image()->h()); + break; + } + + default : + fl_color(s->color()); + fl_rectf(X,Y,W,H); + break; + } + Fl_Widget*const* a = s->array(); + for (int i=s->children()-2; i--;) { + Fl_Widget& o = **a++; + s->draw_child(o); + s->draw_outside_label(o); + } + fl_pop_clip(); +} + +void Fl_Scroll::bbox(int& X, int& Y, int& W, int& H) { + X = x()+Fl::box_dx(box()); + Y = y()+Fl::box_dy(box()); + W = w()-Fl::box_dw(box()); + H = h()-Fl::box_dh(box()); + if (scrollbar.visible()) { + W -= scrollbar.w(); + if (scrollbar.align() & FL_ALIGN_LEFT) X += scrollbar.w(); + } + if (hscrollbar.visible()) { + H -= hscrollbar.h(); + if (scrollbar.align() & FL_ALIGN_TOP) Y += hscrollbar.h(); + } +} + +void Fl_Scroll::draw() { + fix_scrollbar_order(); + int X,Y,W,H; bbox(X,Y,W,H); + + uchar d = damage(); + + if (d & FL_DAMAGE_ALL) { // full redraw + draw_box(box(),x(),y(),w(),h(),color()); + draw_clip(this, X, Y, W, H); + } else { + if (d & FL_DAMAGE_SCROLL) { + // scroll the contents: + fl_scroll(X, Y, W, H, oldx-xposition_, oldy-yposition_, draw_clip, this); + + // Erase the background as needed... + Fl_Widget*const* a = array(); + int L, R, T, B; + L = 999999; + R = 0; + T = 999999; + B = 0; + for (int i=children()-2; i--; a++) { + if ((*a)->x() < L) L = (*a)->x(); + if (((*a)->x() + (*a)->w()) > R) R = (*a)->x() + (*a)->w(); + if ((*a)->y() < T) T = (*a)->y(); + if (((*a)->y() + (*a)->h()) > B) B = (*a)->y() + (*a)->h(); + } + if (L > X) draw_clip(this, X, Y, L - X, H); + if (R < (X + W)) draw_clip(this, R, Y, X + W - R, H); + if (T > Y) draw_clip(this, X, Y, W, T - Y); + if (B < (Y + H)) draw_clip(this, X, B, W, Y + H - B); + } + if (d & FL_DAMAGE_CHILD) { // draw damaged children + fl_clip(X, Y, W, H); + Fl_Widget*const* a = array(); + for (int i=children()-2; i--;) update_child(**a++); + fl_pop_clip(); + } + } + + // accumulate bounding box of children: + int l = X; int r = X; int t = Y; int b = Y; + Fl_Widget*const* a = array(); + for (int i=children()-2; i--;) { + Fl_Object* o = *a++; + if (o->x() < l) l = o->x(); + if (o->y() < t) t = o->y(); + if (o->x()+o->w() > r) r = o->x()+o->w(); + if (o->y()+o->h() > b) b = o->y()+o->h(); + } + + // turn the scrollbars on and off as necessary: + // See if children would fit if we had no scrollbars... + X = x()+Fl::box_dx(box()); + Y = y()+Fl::box_dy(box()); + W = w()-Fl::box_dw(box()); + H = h()-Fl::box_dh(box()); + int vneeded = 0; + int hneeded = 0; + if (type() & VERTICAL) { + if ((type() & ALWAYS_ON) || t < Y || b > Y+H) { + vneeded = 1; + W -= scrollbar.w(); + if (scrollbar.align() & FL_ALIGN_LEFT) X += scrollbar.w(); + } + } + if (type() & HORIZONTAL) { + if ((type() & ALWAYS_ON) || l < X || r > X+W) { + hneeded = 1; + H -= hscrollbar.h(); + if (scrollbar.align() & FL_ALIGN_TOP) Y += hscrollbar.h(); + // recheck vertical since we added a horizontal scrollbar + if (!vneeded && (type() & VERTICAL)) { + if ((type() & ALWAYS_ON) || t < Y || b > Y+H) { + vneeded = 1; + W -= scrollbar.w(); + if (scrollbar.align() & FL_ALIGN_LEFT) X += scrollbar.w(); + } + } + } + } + // Now that we know what's needed, make it so. + if (vneeded && !scrollbar.visible()) { + scrollbar.set_visible(); + d = FL_DAMAGE_ALL; + } + else if (!vneeded && scrollbar.visible()) { + scrollbar.clear_visible(); + draw_clip(this, + scrollbar.align()&FL_ALIGN_LEFT ? X : X+W-scrollbar.w(), + Y, scrollbar.w(), H); + d = FL_DAMAGE_ALL; + } + if (hneeded && !hscrollbar.visible()) { + hscrollbar.set_visible(); + d = FL_DAMAGE_ALL; + } + else if (!hneeded && hscrollbar.visible()) { + hscrollbar.clear_visible(); + draw_clip(this, + X, scrollbar.align()&FL_ALIGN_TOP ? Y : Y+H-hscrollbar.h(), + W, hscrollbar.h()); + d = FL_DAMAGE_ALL; + } + + scrollbar.resize(scrollbar.align()&FL_ALIGN_LEFT ? X-scrollbar.w() : X+W, + Y, scrollbar.w(), H); + scrollbar.value(oldy = yposition_ = (Y-t), H, 0, b-t); + + hscrollbar.resize(X, + scrollbar.align()&FL_ALIGN_TOP ? Y-hscrollbar.h() : Y+H, + W, hscrollbar.h()); + hscrollbar.value(oldx = xposition_ = (X-l), W, 0, r-l); + + // draw the scrollbars: + if (d & FL_DAMAGE_ALL) { + draw_child(scrollbar); + draw_child(hscrollbar); + if (scrollbar.visible() && hscrollbar.visible()) { + // fill in the little box in the corner + fl_color(color()); + fl_rectf(scrollbar.x(), hscrollbar.y(), scrollbar.w(), hscrollbar.h()); + } + } else { + update_child(scrollbar); + update_child(hscrollbar); + } +} + +void Fl_Scroll::resize(int X, int Y, int W, int H) { + fix_scrollbar_order(); + // move all the children: + Fl_Widget*const* a = array(); + for (int i=children()-2; i--;) { + Fl_Object* o = *a++; + o->position(o->x()+X-x(), o->y()+Y-y()); + } + Fl_Widget::resize(X,Y,W,H); +} + +void Fl_Scroll::position(int X, int Y) { + int dx = xposition_-X; + int dy = yposition_-Y; + if (!dx && !dy) return; + xposition_ = X; + yposition_ = Y; + Fl_Widget*const* a = array(); + for (int i=children(); i--;) { + Fl_Widget* o = *a++; + if (o == &hscrollbar || o == &scrollbar) continue; + o->position(o->x()+dx, o->y()+dy); + } + if (parent() == (Fl_Group *)window() && Fl::scheme_bg_) damage(FL_DAMAGE_ALL); + else damage(FL_DAMAGE_SCROLL); +} + +void Fl_Scroll::hscrollbar_cb(Fl_Widget* o, void*) { + Fl_Scroll* s = (Fl_Scroll*)(o->parent()); + s->position(int(((Fl_Scrollbar*)o)->value()), s->yposition()); +} + +void Fl_Scroll::scrollbar_cb(Fl_Widget* o, void*) { + Fl_Scroll* s = (Fl_Scroll*)(o->parent()); + s->position(s->xposition(), int(((Fl_Scrollbar*)o)->value())); +} + +Fl_Scroll::Fl_Scroll(int X,int Y,int W,int H,const char* L) + : Fl_Group(X,Y,W,H,L), + scrollbar(X+W-Fl::scrollbar_size(),Y, + Fl::scrollbar_size(),H-Fl::scrollbar_size()), + hscrollbar(X,Y+H-Fl::scrollbar_size(), + W-Fl::scrollbar_size(),Fl::scrollbar_size()) { + type(BOTH); + xposition_ = 0; + yposition_ = 0; + hscrollbar.type(FL_HORIZONTAL); + hscrollbar.callback(hscrollbar_cb); + scrollbar.callback(scrollbar_cb); +} + +int Fl_Scroll::handle(int event) { + fix_scrollbar_order(); + return Fl_Group::handle(event); +} + +// +// End of "$Id: Fl_Scroll.cxx 5547 2006-11-16 23:17:13Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Scrollbar.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Scrollbar.cxx new file mode 100644 index 000000000..58d88d356 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Scrollbar.cxx @@ -0,0 +1,277 @@ +// +// "$Id: Fl_Scrollbar.cxx 6042 2008-02-25 13:00:53Z matt $" +// +// Scroll bar widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2006 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include +#include "flstring.h" + +#define INITIALREPEAT .5 +#define REPEAT .05 + +void Fl_Scrollbar::increment_cb() { + int ls = maximum()>=minimum() ? linesize_ : -linesize_; + int i; + switch (pushed_) { + case 1: + i = -ls; + break; + default: + i = ls; + break; + case 5: + i = -int((maximum()-minimum())*slider_size()/(1.0-slider_size())) + ls; + if (i > -ls) i = -ls; + break; + case 6: + i = int((maximum()-minimum())*slider_size()/(1.0-slider_size())) - ls; + if (i < ls) i = ls; + break; + } + handle_drag(clamp(value() + i)); +} + +void Fl_Scrollbar::timeout_cb(void* v) { + Fl_Scrollbar* s = (Fl_Scrollbar*)v; + s->increment_cb(); + Fl::add_timeout(REPEAT, timeout_cb, s); +} + +int Fl_Scrollbar::handle(int event) { + // area of scrollbar: + int area; + int X=x(); int Y=y(); int W=w(); int H=h(); + + // adjust slider area to be inside the arrow buttons: + if (horizontal()) { + if (W >= 3*H) {X += H; W -= 2*H;} + } else { + if (H >= 3*W) {Y += W; H -= 2*W;} + } + + // which widget part is highlighted? + int relx; + int ww; + if (horizontal()) { + relx = Fl::event_x()-X; + ww = W; + } else { + relx = Fl::event_y()-Y; + ww = H; + } + if (relx < 0) area = 1; + else if (relx >= ww) area = 2; + else { + int S = int(slider_size()*ww+.5); + int T = (horizontal() ? H : W)/2+1; + if (type()==FL_VERT_NICE_SLIDER || type()==FL_HOR_NICE_SLIDER) T += 4; + if (S < T) S = T; + double val = + (maximum()-minimum()) ? (value()-minimum())/(maximum()-minimum()) : 0.5; + int sliderx; + if (val >= 1.0) sliderx = ww-S; + else if (val <= 0.0) sliderx = 0; + else sliderx = int(val*(ww-S)+.5); + if (Fl::event_button() == FL_MIDDLE_MOUSE) area = 8; + else if (relx < sliderx) area = 5; + else if (relx >= sliderx+S) area = 6; + else area = 8; + } + + switch (event) { + case FL_ENTER: + case FL_LEAVE: + return 1; + case FL_RELEASE: + damage(FL_DAMAGE_ALL); + if (pushed_) { + Fl::remove_timeout(timeout_cb, this); + pushed_ = 0; + } + handle_release(); + return 1; + case FL_PUSH: + if (pushed_) return 1; + if (area != 8) pushed_ = area; + if (pushed_) { + handle_push(); + Fl::add_timeout(INITIALREPEAT, timeout_cb, this); + increment_cb(); + damage(FL_DAMAGE_ALL); + return 1; + } + return Fl_Slider::handle(event, X,Y,W,H); + case FL_DRAG: + if (pushed_) return 1; + return Fl_Slider::handle(event, X,Y,W,H); + case FL_MOUSEWHEEL : + if (horizontal()) { + if (Fl::e_dx==0) return 0; + handle_drag(clamp(value() + linesize_ * Fl::e_dx)); + return 1; + } else { + if (Fl::e_dy==0) return 0; + handle_drag(clamp(value() + linesize_ * Fl::e_dy)); + return 1; + } + case FL_SHORTCUT: + case FL_KEYBOARD: { + int v = value(); + int ls = maximum()>=minimum() ? linesize_ : -linesize_; + if (horizontal()) { + switch (Fl::event_key()) { + case FL_Left: + v -= ls; + break; + case FL_Right: + v += ls; + break; + default: + return 0; + } + } else { // vertical + switch (Fl::event_key()) { + case FL_Up: + v -= ls; + break; + case FL_Down: + v += ls; + break; + case FL_Page_Up: + if (slider_size() >= 1.0) return 0; + v -= int((maximum()-minimum())*slider_size()/(1.0-slider_size())); + v += ls; + break; + case FL_Page_Down: + if (slider_size() >= 1.0) return 0; + v += int((maximum()-minimum())*slider_size()/(1.0-slider_size())); + v -= ls; + break; + case FL_Home: + v = int(minimum()); + break; + case FL_End: + v = int(maximum()); + break; + default: + return 0; + } + } + v = int(clamp(v)); + if (v != value()) { + Fl_Slider::value(v); + value_damage(); + set_changed(); + do_callback(); + } + return 1;} + } + return 0; +} + +void Fl_Scrollbar::draw() { + if (damage()&FL_DAMAGE_ALL) draw_box(); + int X = x()+Fl::box_dx(box()); + int Y = y()+Fl::box_dy(box()); + int W = w()-Fl::box_dw(box()); + int H = h()-Fl::box_dh(box()); + if (horizontal()) { + if (W < 3*H) {Fl_Slider::draw(X,Y,W,H); return;} + Fl_Slider::draw(X+H,Y,W-2*H,H); + if (damage()&FL_DAMAGE_ALL) { + draw_box((pushed_==1) ? fl_down(slider()) : slider(), + X, Y, H, H, selection_color()); + draw_box((pushed_==2) ? fl_down(slider()) : slider(), + X+W-H, Y, H, H, selection_color()); + if (active_r()) + fl_color(labelcolor()); + else + fl_color(fl_inactive(labelcolor())); + int w1 = (H-4)/3; if (w1 < 1) w1 = 1; + int x1 = X+(H-w1-1)/2; + int yy1 = Y+(H-2*w1-1)/2; + if (Fl::scheme_ && !strcmp(Fl::scheme_, "gtk+")) { + fl_polygon(x1, yy1+w1, x1+w1, yy1+2*w1, x1+w1-1, yy1+w1, x1+w1, yy1); + x1 += (W-H); + fl_polygon(x1, yy1, x1+1, yy1+w1, x1, yy1+2*w1, x1+w1, yy1+w1); + } else { + fl_polygon(x1, yy1+w1, x1+w1, yy1+2*w1, x1+w1, yy1); + x1 += (W-H); + fl_polygon(x1, yy1, x1, yy1+2*w1, x1+w1, yy1+w1); + } + } + } else { // vertical + if (H < 3*W) {Fl_Slider::draw(X,Y,W,H); return;} + Fl_Slider::draw(X,Y+W,W,H-2*W); + if (damage()&FL_DAMAGE_ALL) { + draw_box((pushed_==1) ? fl_down(slider()) : slider(), + X, Y, W, W, selection_color()); + draw_box((pushed_==2) ? fl_down(slider()) : slider(), + X, Y+H-W, W, W, selection_color()); + if (active_r()) + fl_color(labelcolor()); + else + fl_color(fl_inactive(labelcolor())); + int w1 = (W-4)/3; if (w1 < 1) w1 = 1; + int x1 = X+(W-2*w1-1)/2; + int yy1 = Y+(W-w1-1)/2; + if (Fl::scheme_ && !strcmp(Fl::scheme_, "gtk+")) { + fl_polygon(x1, yy1+w1, x1+w1, yy1+w1-1, x1+2*w1, yy1+w1, x1+w1, yy1); + yy1 += H-W; + fl_polygon(x1, yy1, x1+w1, yy1+1, x1+w1, yy1+w1); + fl_polygon(x1+w1, yy1+1, x1+2*w1, yy1, x1+w1, yy1+w1); + } else { + fl_polygon(x1, yy1+w1, x1+2*w1, yy1+w1, x1+w1, yy1); + yy1 += H-W; + fl_polygon(x1, yy1, x1+w1, yy1+w1, x1+2*w1, yy1); + } + } + } +} + +Fl_Scrollbar::Fl_Scrollbar(int X, int Y, int W, int H, const char* L) + : Fl_Slider(X, Y, W, H, L) +{ + box(FL_FLAT_BOX); + color(FL_DARK2); + slider(FL_UP_BOX); + linesize_ = 16; + pushed_ = 0; + step(1); +} + +Fl_Scrollbar::~Fl_Scrollbar() +{ + if (pushed_) + Fl::remove_timeout(timeout_cb, this); +} + + +// +// End of "$Id: Fl_Scrollbar.cxx 6042 2008-02-25 13:00:53Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Shared_Image.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Shared_Image.cxx new file mode 100644 index 000000000..3d29dc537 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Shared_Image.cxx @@ -0,0 +1,467 @@ +// +// "$Id: Fl_Shared_Image.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Shared image code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include "flstring.h" + +#include +#include +#include +#include + + +// +// Global class vars... +// + +Fl_Shared_Image **Fl_Shared_Image::images_ = 0; // Shared images +int Fl_Shared_Image::num_images_ = 0; // Number of shared images +int Fl_Shared_Image::alloc_images_ = 0; // Allocated shared images + +Fl_Shared_Handler *Fl_Shared_Image::handlers_ = 0;// Additional format handlers +int Fl_Shared_Image::num_handlers_ = 0; // Number of format handlers +int Fl_Shared_Image::alloc_handlers_ = 0; // Allocated format handlers + + +// +// Typedef the C API sort function type the only way I know how... +// + +extern "C" { + typedef int (*compare_func_t)(const void *, const void *); +} + + +// Static methods that really should be inline, but some WIN32 compilers +// can't handle it... +Fl_Shared_Image **Fl_Shared_Image::images() { + return images_; +} + +int Fl_Shared_Image::num_images() { + return num_images_; +} + + +// +// 'Fl_Shared_Image::compare()' - Compare two shared images... +// + +int +Fl_Shared_Image::compare(Fl_Shared_Image **i0, // I - First image + Fl_Shared_Image **i1) { // I - Second image + int i = strcmp((*i0)->name(), (*i1)->name()); + + if (i) return i; + else if (((*i0)->w() == 0 && (*i1)->original_) || + ((*i1)->w() == 0 && (*i0)->original_)) return 0; + else if ((*i0)->w() != (*i1)->w()) return (*i0)->w() - (*i1)->w(); + else return (*i0)->h() - (*i1)->h(); +} + + +// +// 'Fl_Shared_Image::Fl_Shared_Image()' - Basic constructor. +// + +Fl_Shared_Image::Fl_Shared_Image() : Fl_Image(0,0,0) { + name_ = 0; + refcount_ = 1; + original_ = 0; + image_ = 0; + alloc_image_ = 0; +} + + +// +// 'Fl_Shared_Image::Fl_Shared_Image()' - Add an image to the image cache. +// + +Fl_Shared_Image::Fl_Shared_Image(const char *n, // I - Filename + Fl_Image *img) // I - Image + : Fl_Image(0,0,0) { + name_ = new char[strlen(n) + 1]; + strcpy((char *)name_, n); + + refcount_ = 1; + image_ = img; + alloc_image_ = !img; + original_ = 1; + + if (!img) reload(); + else update(); +} + + +// +// 'Fl_Shared_Image::add()' - Add a shared image to the array. +// + +void +Fl_Shared_Image::add() { + Fl_Shared_Image **temp; // New image pointer array... + + if (num_images_ >= alloc_images_) { + // Allocate more memory... + temp = new Fl_Shared_Image *[alloc_images_ + 32]; + + if (alloc_images_) { + memcpy(temp, images_, alloc_images_ * sizeof(Fl_Shared_Image *)); + + delete[] images_; + } + + images_ = temp; + alloc_images_ += 32; + } + + images_[num_images_] = this; + num_images_ ++; + + if (num_images_ > 1) { + qsort(images_, num_images_, sizeof(Fl_Shared_Image *), + (compare_func_t)compare); + } +} + + +// +// 'Fl_Shared_Image::update()' - Update the dimensions of the shared images. +// + +void +Fl_Shared_Image::update() { + if (image_) { + w(image_->w()); + h(image_->h()); + d(image_->d()); + data(image_->data(), image_->count()); + } +} + + +// +// 'Fl_Shared_Image::~Fl_Shared_Image()' - Destroy a shared image... +// + +Fl_Shared_Image::~Fl_Shared_Image() { + if (name_) delete[] (char *)name_; + if (alloc_image_) delete image_; +} + + +// +// 'Fl_Shared_Image::release()' - Release and possibly destroy a shared image. +// + +void +Fl_Shared_Image::release() { + int i; // Looping var... + + refcount_ --; + if (refcount_ > 0) return; + + for (i = 0; i < num_images_; i ++) + if (images_[i] == this) { + num_images_ --; + + if (i < num_images_) { + memmove(images_ + i, images_ + i + 1, + (num_images_ - i) * sizeof(Fl_Shared_Image *)); + } + + break; + } + + delete this; + + if (num_images_ == 0 && images_) { + delete[] images_; + + images_ = 0; + alloc_images_ = 0; + } +} + + +// +// 'Fl_Shared_Image::reload()' - Reload the shared image... +// + +void +Fl_Shared_Image::reload() { + // Load image from disk... + int i; // Looping var + FILE *fp; // File pointer + uchar header[64]; // Buffer for auto-detecting files + Fl_Image *img; // New image + + if (!name_) return; + + if ((fp = fopen(name_, "rb")) != NULL) { + fread(header, 1, sizeof(header), fp); + fclose(fp); + } else { + return; + } + + // Load the image as appropriate... + if (memcmp(header, "#define", 7) == 0) // XBM file + img = new Fl_XBM_Image(name_); + else if (memcmp(header, "/* XPM */", 9) == 0) // XPM file + img = new Fl_XPM_Image(name_); + else { + // Not a standard format; try an image handler... + for (i = 0, img = 0; i < num_handlers_; i ++) { + img = (handlers_[i])(name_, header, sizeof(header)); + + if (img) break; + } + } + + if (img) { + if (alloc_image_) delete image_; + + alloc_image_ = 1; + + if ((img->w() != w() && w()) || (img->h() != h() && h())) { + // Make sure the reloaded image is the same size as the existing one. + Fl_Image *temp = img->copy(w(), h()); + delete img; + image_ = temp; + } else { + image_ = img; + } + + update(); + } +} + + +// +// 'Fl_Shared_Image::copy()' - Copy and resize a shared image... +// + +Fl_Image * +Fl_Shared_Image::copy(int W, int H) { + Fl_Image *temp_image; // New image file + Fl_Shared_Image *temp_shared; // New shared image + + // Make a copy of the image we're sharing... + if (!image_) temp_image = 0; + else temp_image = image_->copy(W, H); + + // Then make a new shared image... + temp_shared = new Fl_Shared_Image(); + + temp_shared->name_ = new char[strlen(name_) + 1]; + strcpy((char *)temp_shared->name_, name_); + + temp_shared->refcount_ = 1; + temp_shared->image_ = temp_image; + temp_shared->alloc_image_ = 1; + + temp_shared->update(); + + return temp_shared; +} + + +// +// 'Fl_Shared_Image::color_average()' - Blend colors... +// + +void +Fl_Shared_Image::color_average(Fl_Color c, // I - Color to blend with + float i) { // I - Blend fraction + if (!image_) return; + + image_->color_average(c, i); + update(); +} + + +// +// 'Fl_Shared_Image::desaturate()' - Convert the image to grayscale... +// + +void +Fl_Shared_Image::desaturate() { + if (!image_) return; + + image_->desaturate(); + update(); +} + + +// +// 'Fl_Shared_Image::draw()' - Draw a shared image... +// + +void +Fl_Shared_Image::draw(int X, int Y, int W, int H, int cx, int cy) { + if (image_) image_->draw(X, Y, W, H, cx, cy); + else Fl_Image::draw(X, Y, W, H, cx, cy); +} + + +// +// 'Fl_Shared_Image::uncache()' - Uncache the shared image... +// + +void +Fl_Shared_Image::uncache() +{ + if (image_) image_->uncache(); +} + + +// +// 'Fl_Shared_Image::find()' - Find a shared image... +// + +Fl_Shared_Image * +Fl_Shared_Image::find(const char *n, int W, int H) { + Fl_Shared_Image *key, // Image key + **match; // Matching image + + if (num_images_) { + key = new Fl_Shared_Image(); + key->name_ = new char[strlen(n) + 1]; + strcpy((char *)key->name_, n); + key->w(W); + key->h(H); + + match = (Fl_Shared_Image **)bsearch(&key, images_, num_images_, + sizeof(Fl_Shared_Image *), + (compare_func_t)compare); + + delete key; + + if (match) { + (*match)->refcount_ ++; + return *match; + } + } + + return 0; +} + + +// +// 'Fl_Shared_Image::get()' - Get a shared image... +// + +Fl_Shared_Image * +Fl_Shared_Image::get(const char *n, int W, int H) { + Fl_Shared_Image *temp; // Image + + if ((temp = find(n, W, H)) != NULL) return temp; + + if ((temp = find(n)) == NULL) { + temp = new Fl_Shared_Image(n); + + if (!temp->image_) { + delete temp; + return NULL; + } + + temp->add(); + } + + if ((temp->w() != W || temp->h() != H) && W && H) { + temp = (Fl_Shared_Image *)temp->copy(W, H); + temp->add(); + } + + return temp; +} + + +// +// 'Fl_Shared_Image::add_handler()' - Add a shared image handler. +// + +void +Fl_Shared_Image::add_handler(Fl_Shared_Handler f) { + int i; // Looping var... + Fl_Shared_Handler *temp; // New image handler array... + + // First see if we have already added the handler... + for (i = 0; i < num_handlers_; i ++) { + if (handlers_[i] == f) return; + } + + if (num_handlers_ >= alloc_handlers_) { + // Allocate more memory... + temp = new Fl_Shared_Handler [alloc_handlers_ + 32]; + + if (alloc_handlers_) { + memcpy(temp, handlers_, alloc_handlers_ * sizeof(Fl_Shared_Handler)); + + delete[] handlers_; + } + + handlers_ = temp; + alloc_handlers_ += 32; + } + + handlers_[num_handlers_] = f; + num_handlers_ ++; +} + + +// +// 'Fl_Shared_Image::remove_handler()' - Remove a shared image handler. +// + +void +Fl_Shared_Image::remove_handler(Fl_Shared_Handler f) { + int i; // Looping var... + + // First see if the handler has been added... + for (i = 0; i < num_handlers_; i ++) { + if (handlers_[i] == f) break; + } + + if (i >= num_handlers_) return; + + // OK, remove the handler from the array... + num_handlers_ --; + + if (i < num_handlers_) { + // Shift later handlers down 1... + memmove(handlers_ + i, handlers_ + i + 1, + (num_handlers_ - i) * sizeof(Fl_Shared_Handler )); + } +} + + +// +// End of "$Id: Fl_Shared_Image.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Single_Window.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Single_Window.cxx new file mode 100644 index 000000000..433700216 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Single_Window.cxx @@ -0,0 +1,41 @@ +// +// "$Id: Fl_Single_Window.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Single-buffered window for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// A window with a single-buffered context +// +// This is provided for systems where the base class is double +// buffered. You can turn it off using this subclass in case +// your display looks better without it. + +#include + +void Fl_Single_Window::show() {Fl_Window::show();} +void Fl_Single_Window::flush() {Fl_Window::flush();} + +// +// End of "$Id: Fl_Single_Window.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Slider.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Slider.cxx new file mode 100644 index 000000000..3ad4895ad --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Slider.cxx @@ -0,0 +1,339 @@ +// +// "$Id: Fl_Slider.cxx 5438 2006-09-17 14:58:25Z mike $" +// +// Slider widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2006 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include +#include "flstring.h" + +void Fl_Slider::_Fl_Slider() { + slider_size_ = 0; + slider_ = 0; // FL_UP_BOX; +} + +Fl_Slider::Fl_Slider(int X, int Y, int W, int H, const char* l) +: Fl_Valuator(X, Y, W, H, l) { + box(FL_DOWN_BOX); + _Fl_Slider(); +} + +Fl_Slider::Fl_Slider(uchar t, int X, int Y, int W, int H, const char* l) + : Fl_Valuator(X, Y, W, H, l) { + type(t); + box(t==FL_HOR_NICE_SLIDER || t==FL_VERT_NICE_SLIDER ? + FL_FLAT_BOX : FL_DOWN_BOX); + _Fl_Slider(); +} + +void Fl_Slider::slider_size(double v) { + if (v < 0) v = 0; + if (v > 1) v = 1; + if (slider_size_ != float(v)) { + slider_size_ = float(v); + damage(FL_DAMAGE_EXPOSE); + } +} + +void Fl_Slider::bounds(double a, double b) { + if (minimum() != a || maximum() != b) { + Fl_Valuator::bounds(a, b); + damage(FL_DAMAGE_EXPOSE); + } +} + +int Fl_Slider::scrollvalue(int p, int W, int t, int l) { +// p = position, first line displayed +// w = window, number of lines displayed +// t = top, number of first line +// l = length, total number of lines + step(1, 1); + if (p+W > t+l) l = p+W-t; + slider_size(W >= l ? 1.0 : double(W)/double(l)); + bounds(t, l-W+t); + return value(p); +} + +// All slider interaction is done as though the slider ranges from +// zero to one, and the left (bottom) edge of the slider is at the +// given position. Since when the slider is all the way to the +// right (top) the left (bottom) edge is not all the way over, a +// position on the widget itself covers a wider range than 0-1, +// actually it ranges from 0 to 1/(1-size). + +void Fl_Slider::draw_bg(int X, int Y, int W, int H) { + fl_push_clip(X, Y, W, H); + draw_box(); + fl_pop_clip(); + + Fl_Color black = active_r() ? FL_FOREGROUND_COLOR : FL_INACTIVE_COLOR; + if (type() == FL_VERT_NICE_SLIDER) { + draw_box(FL_THIN_DOWN_BOX, X+W/2-2, Y, 4, H, black); + } else if (type() == FL_HOR_NICE_SLIDER) { + draw_box(FL_THIN_DOWN_BOX, X, Y+H/2-2, W, 4, black); + } +} + +void Fl_Slider::draw(int X, int Y, int W, int H) { + + double val; + if (minimum() == maximum()) + val = 0.5; + else { + val = (value()-minimum())/(maximum()-minimum()); + if (val > 1.0) val = 1.0; + else if (val < 0.0) val = 0.0; + } + + int ww = (horizontal() ? W : H); + int xx, S; + if (type()==FL_HOR_FILL_SLIDER || type() == FL_VERT_FILL_SLIDER) { + S = int(val*ww+.5); + if (minimum()>maximum()) {S = ww-S; xx = ww-S;} + else xx = 0; + } else { + S = int(slider_size_*ww+.5); + int T = (horizontal() ? H : W)/2+1; + if (type()==FL_VERT_NICE_SLIDER || type()==FL_HOR_NICE_SLIDER) T += 4; + if (S < T) S = T; + xx = int(val*(ww-S)+.5); + } + int xsl, ysl, wsl, hsl; + if (horizontal()) { + xsl = X+xx; + wsl = S; + ysl = Y; + hsl = H; + } else { + ysl = Y+xx; + hsl = S; + xsl = X; + wsl = W; + } + + draw_bg(X, Y, W, H); + + Fl_Boxtype box1 = slider(); + if (!box1) {box1 = (Fl_Boxtype)(box()&-2); if (!box1) box1 = FL_UP_BOX;} + if (type() == FL_VERT_NICE_SLIDER) { + draw_box(box1, xsl, ysl, wsl, hsl, FL_GRAY); + int d = (hsl-4)/2; + draw_box(FL_THIN_DOWN_BOX, xsl+2, ysl+d, wsl-4, hsl-2*d,selection_color()); + } else if (type() == FL_HOR_NICE_SLIDER) { + draw_box(box1, xsl, ysl, wsl, hsl, FL_GRAY); + int d = (wsl-4)/2; + draw_box(FL_THIN_DOWN_BOX, xsl+d, ysl+2, wsl-2*d, hsl-4,selection_color()); + } else { + if (wsl>0 && hsl>0) draw_box(box1, xsl, ysl, wsl, hsl, selection_color()); + + if (type()!=FL_HOR_FILL_SLIDER && type() != FL_VERT_FILL_SLIDER && + Fl::scheme_ && !strcmp(Fl::scheme_, "gtk+")) { + if (W>H && wsl>(hsl+8)) { + // Draw horizontal grippers + int yy, hh; + hh = hsl-8; + xx = xsl+(wsl-hsl-4)/2; + yy = ysl+3; + + fl_color(fl_darker(selection_color())); + fl_line(xx, yy+hh, xx+hh, yy); + fl_line(xx+6, yy+hh, xx+hh+6, yy); + fl_line(xx+12, yy+hh, xx+hh+12, yy); + + xx++; + fl_color(fl_lighter(selection_color())); + fl_line(xx, yy+hh, xx+hh, yy); + fl_line(xx+6, yy+hh, xx+hh+6, yy); + fl_line(xx+12, yy+hh, xx+hh+12, yy); + } else if (H>W && hsl>(wsl+8)) { + // Draw vertical grippers + int yy; + xx = xsl+4; + ww = wsl-8; + yy = ysl+(hsl-wsl-4)/2; + + fl_color(fl_darker(selection_color())); + fl_line(xx, yy+ww, xx+ww, yy); + fl_line(xx, yy+ww+6, xx+ww, yy+6); + fl_line(xx, yy+ww+12, xx+ww, yy+12); + + yy++; + fl_color(fl_lighter(selection_color())); + fl_line(xx, yy+ww, xx+ww, yy); + fl_line(xx, yy+ww+6, xx+ww, yy+6); + fl_line(xx, yy+ww+12, xx+ww, yy+12); + } + } + } + + draw_label(xsl, ysl, wsl, hsl); + if (Fl::focus() == this) { + if (type() == FL_HOR_FILL_SLIDER || type() == FL_VERT_FILL_SLIDER) draw_focus(); + else draw_focus(box1, xsl, ysl, wsl, hsl); + } +} + +void Fl_Slider::draw() { + if (damage()&FL_DAMAGE_ALL) draw_box(); + draw(x()+Fl::box_dx(box()), + y()+Fl::box_dy(box()), + w()-Fl::box_dw(box()), + h()-Fl::box_dh(box())); +} + +int Fl_Slider::handle(int event, int X, int Y, int W, int H) { + switch (event) { + case FL_PUSH: + if (!Fl::event_inside(X, Y, W, H)) return 0; + handle_push(); + case FL_DRAG: { + + double val; + if (minimum() == maximum()) + val = 0.5; + else { + val = (value()-minimum())/(maximum()-minimum()); + if (val > 1.0) val = 1.0; + else if (val < 0.0) val = 0.0; + } + + int ww = (horizontal() ? W : H); + int mx = (horizontal() ? Fl::event_x()-X : Fl::event_y()-Y); + int S; + static int offcenter; + + if (type() == FL_HOR_FILL_SLIDER || type() == FL_VERT_FILL_SLIDER) { + + S = 0; + if (event == FL_PUSH) { + int xx = int(val*ww+.5); + offcenter = mx-xx; + if (offcenter < -10 || offcenter > 10) offcenter = 0; + else return 1; + } + + } else { + + S = int(slider_size_*ww+.5); if (S >= ww) return 0; + int T = (horizontal() ? H : W)/2+1; + if (type()==FL_VERT_NICE_SLIDER || type()==FL_HOR_NICE_SLIDER) T += 4; + if (S < T) S = T; + if (event == FL_PUSH) { + int xx = int(val*(ww-S)+.5); + offcenter = mx-xx; + if (offcenter < 0) offcenter = 0; + else if (offcenter > S) offcenter = S; + else return 1; + } + } + + int xx = mx-offcenter; + double v; + char tryAgain = 1; + while (tryAgain) + { + tryAgain = 0; + if (xx < 0) { + xx = 0; + offcenter = mx; if (offcenter < 0) offcenter = 0; + } else if (xx > (ww-S)) { + xx = ww-S; + offcenter = mx-xx; if (offcenter > S) offcenter = S; + } + v = round(xx*(maximum()-minimum())/(ww-S) + minimum()); + // make sure a click outside the sliderbar moves it: + if (event == FL_PUSH && v == value()) { + offcenter = S/2; + event = FL_DRAG; + tryAgain = 1; + } + } + handle_drag(clamp(v)); + } return 1; + case FL_RELEASE: + handle_release(); + return 1; + case FL_KEYBOARD : + switch (Fl::event_key()) { + case FL_Up: + if (horizontal()) return 0; + handle_push(); + handle_drag(clamp(increment(value(),-1))); + handle_release(); + return 1; + case FL_Down: + if (horizontal()) return 0; + handle_push(); + handle_drag(clamp(increment(value(),1))); + handle_release(); + return 1; + case FL_Left: + if (!horizontal()) return 0; + handle_push(); + handle_drag(clamp(increment(value(),-1))); + handle_release(); + return 1; + case FL_Right: + if (!horizontal()) return 0; + handle_push(); + handle_drag(clamp(increment(value(),1))); + handle_release(); + return 1; + default: + return 0; + } + // break not required because of switch... + case FL_FOCUS : + case FL_UNFOCUS : + if (Fl::visible_focus()) { + redraw(); + return 1; + } else return 0; + case FL_ENTER : + case FL_LEAVE : + return 1; + default: + return 0; + } +} + +int Fl_Slider::handle(int event) { + if (event == FL_PUSH && Fl::visible_focus()) { + Fl::focus(this); + redraw(); + } + + return handle(event, + x()+Fl::box_dx(box()), + y()+Fl::box_dy(box()), + w()-Fl::box_dw(box()), + h()-Fl::box_dh(box())); +} + +// +// End of "$Id: Fl_Slider.cxx 5438 2006-09-17 14:58:25Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Sys_Menu_Bar.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Sys_Menu_Bar.cxx new file mode 100644 index 000000000..99da8dbae --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Sys_Menu_Bar.cxx @@ -0,0 +1,334 @@ +// +// "$Id: Fl_Sys_Menu_Bar.cxx 6016 2008-01-09 21:32:40Z matt $" +// +// MacOS system menu bar widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/** + * This code is a quick hack! It was written as a proof of concept. + * It has been tested on the "menubar" sample program and provides + * basic functionality. + * + * To use the System Menu Bar, simply replace the main Fl_Menu_Bar + * in an application with Fl_Sys_Menu_Bar. + * + * FLTK features not supported by the Mac System menu + * + * - no invisible menu items + * - no sybolic labels + * - embossed labels will be underlined instead + * - no font sizes + * - Shortcut Characters should be English alphanumeric only, no modifiers yet + * - no disable main menus + * - changes to menubar in run-time don't update! + * (disable, etc. - toggle and readio button do!) + * + * No care was taken to clean up the menu bar after destruction! + * ::menu(bar) should only be called once! + * Many other calls of the parent class don't work. + * Changing the menu items has no effect on the menu bar. + * Starting with OS X 10.5, FLTK applications must be created as + * a bundle for the System Menu Bar (and maybe other features) to work! + */ + +#if defined(__APPLE__) + +#include +#include +#include + +#include "flstring.h" +#include +#include + +typedef const Fl_Menu_Item *pFl_Menu_Item; + +/** + * copy the text of a menuitem into a buffer. + * Skip all '&' which would mark the shortcut in FLTK + * Skip all Mac control characters ('(', '<', ';', '^', '!' ) + */ +static void catMenuText( const char *src, char *dst ) +{ + char c; + while ( *dst ) + dst++; + if ( *src == '-' ) + src++; + while ( ( c = *src++ ) ) + { + if ( !strchr( "&(<;^!", c ) ) + *dst++ = c; + } + *dst = 0; +} + +/** + * append a marker to identify the menu font style + * labeltype_ && !m->labelfont_ ) + return; + while ( *dst ) + dst++; + + if ( m->labelfont_ & FL_BOLD ) + strcat( dst, "labelfont_ & FL_ITALIC ) + strcat( dst, "labelfont_ & FL_UNDERLINE ) + // strcat( dst, "labeltype_ == FL_EMBOSSED_LABEL ) + strcat( dst, "labeltype_ == FL_ENGRAVED_LABEL ) + strcat( dst, "labeltype_ == FL_SHADOW_LABEL ) + strcat( dst, "labeltype_ == FL_SYMBOL_LABEL ) + ; // not supported +} + +/** + * append a marker to identify the menu shortcut + * shortcut_ ) + return; + if ( m->flags & FL_SUBMENU ) + return; + if ( m->flags & FL_SUBMENU_POINTER ) + return; + char key = m->shortcut_ & 0xff; + if ( !isalnum( key ) ) + return; + + long macMod = kMenuNoCommandModifier; + if ( m->shortcut_ & FL_META ) macMod = kMenuNoModifiers; + if ( m->shortcut_ & FL_SHIFT || isupper(key) ) macMod |= kMenuShiftModifier; + if ( m->shortcut_ & FL_ALT ) macMod |= kMenuOptionModifier; + if ( m->shortcut_ & FL_CTRL ) macMod |= kMenuControlModifier; + + //SetMenuItemKeyGlyph( mh, miCnt, key ); + SetItemCmd( mh, miCnt, toupper(key) ); + SetMenuItemModifiers( mh, miCnt, macMod ); +} + +#if 0 +// this function needs to be verified before we compile it back in. +static void catMenuShortcut( const Fl_Menu_Item *m, char *dst ) +{ + if ( !m->shortcut_ ) + return; + char c = m->shortcut_ & 0xff; + if ( !isalnum( c & 0xff ) ) + return; + while ( *dst ) + dst++; + if ( m->shortcut_ & FL_CTRL ) + { + sprintf( dst, "/%c", toupper( c ) ); + } + //if ( isalnum( mm->shortcut_ ) && !( mm->flags & FL_SUBMENU ) ) + //sprintf( buf+strlen(buf), "/%c", mm->shortcut_ ); +} +#endif + +static void setMenuFlags( MenuHandle mh, int miCnt, const Fl_Menu_Item *m ) +{ + if ( m->flags & FL_MENU_TOGGLE ) + { + SetItemMark( mh, miCnt, ( m->flags & FL_MENU_VALUE ) ? 0x12 : 0 ); + } + else if ( m->flags & FL_MENU_RADIO ) + SetItemMark( mh, miCnt, ( m->flags & FL_MENU_VALUE ) ? 0x13 : 0 ); +} + +static void catMenuFlags( const Fl_Menu_Item *m, char *dst ) +{ + if ( !m->flags ) + return; + if ( m->flags & FL_MENU_INACTIVE ) + strcat( dst, "(" ); +} + +/** + * create a sub menu for a specific menu handle + */ +static void createSubMenu( MenuHandle mh, int &cnt, pFl_Menu_Item &mm ) +{ + char buf[255]; + int miCnt = 1; + while ( mm->text ) + { + MenuHandle smh = 0; + buf[1] = 0; + catMenuFont( mm, buf+1 ); + //catMenuShortcut( mm, buf+1 ); + catMenuText( mm->text, buf+1 ); + catMenuFlags( mm, buf+1 ); + if ( mm->flags & (FL_SUBMENU | FL_SUBMENU_POINTER) ) + { + cnt++; + smh = NewMenu( cnt, (unsigned char*)"\001 " ); + sprintf( buf+1+strlen(buf+1), "/\033!%c", cnt ); + } + if ( mm->flags & FL_MENU_DIVIDER ) + strcat( buf+1, ";-" ); + buf[0] = strlen( buf+1 ); + AppendMenu( mh, (unsigned char*)buf ); + // insert Appearanc manager functions here! + setMenuFlags( mh, miCnt, mm ); + setMenuShortcut( mh, miCnt, mm ); + SetMenuItemRefCon( mh, miCnt, (UInt32)mm ); + miCnt++; + if ( mm->flags & FL_MENU_DIVIDER ) + miCnt++; + if ( mm->flags & FL_SUBMENU ) + { + createSubMenu( smh, cnt, ++mm ); + } + else if ( mm->flags & FL_SUBMENU_POINTER ) + { + const Fl_Menu_Item *smm = (Fl_Menu_Item*)mm->user_data_; + createSubMenu( mh, cnt, smm ); + } + mm++; + } + InsertMenu( mh, -1 ); +} + + +/** + * create a system menu bar using the given list of menu structs + * + * \author Matthias Melcher + * + * @param m list of Fl_Menu_Item + */ +void Fl_Sys_Menu_Bar::menu(const Fl_Menu_Item *m) +{ + fl_open_display(); + Fl_Menu_Bar::menu( m ); + fl_sys_menu_bar = this; + + char buf[255]; + + int cnt = 1; // first menu is no 2. no 1 is the Apple Menu + const Fl_Menu_Item *mm = m; + for (;;) + { + if ( !mm || !mm->text ) + break; + char visible = mm->visible() ? 1 : 0; + buf[1] = 0; + catMenuText( mm->text, buf+1 ); + buf[0] = strlen( buf+1 ); + MenuHandle mh = NewMenu( ++cnt, (unsigned char*)buf ); + if ( mm->flags & FL_MENU_INACTIVE ) { + ChangeMenuAttributes(mh, kMenuAttrAutoDisable, 0); + DisableAllMenuItems(mh); + DisableMenuItem(mh, 0); + } + if ( mm->flags & FL_SUBMENU ) + createSubMenu( mh, cnt, ++mm ); + else if ( mm->flags & FL_SUBMENU_POINTER ) { + const Fl_Menu_Item *smm = (Fl_Menu_Item*)mm->user_data_; + createSubMenu( mh, cnt, smm ); + } + if ( visible ) { + InsertMenu( mh, 0 ); + } + mm++; + } + DrawMenuBar(); +} + +/* +const Fl_Menu_Item* Fl_Sys_Menu_Bar::picked(const Fl_Menu_Item* v) { + Fl_menu_Item *ret = Fl_Menu_Bar::picked( v ); + + if ( m->flags & FL_MENU_TOGGLE ) + { + SetItemMark( mh, miCnt, ( m->flags & FL_MENU_VALUE ) ? 0x12 : 0 ); + } + + return ret; +} +*/ + +void Fl_Sys_Menu_Bar::draw() { +/* -- nothing to do, system should take care of this + draw_box(); + if (!menu() || !menu()->text) return; + const Fl_Menu_Item* m; + int X = x()+6; + for (m=menu(); m->text; m = m->next()) { + int W = m->measure(0,this) + 16; + m->draw(X, y(), W, h(), this); + X += W; + } + */ +} + +/* +int Fl_Menu_Bar::handle(int event) { + const Fl_Menu_Item* v; + if (menu() && menu()->text) switch (event) { + case FL_ENTER: + case FL_LEAVE: + return 1; + case FL_PUSH: + v = 0; + J1: + v = menu()->pulldown(x(), y(), w(), h(), v, this, 0, 1); + picked(v); + return 1; + case FL_SHORTCUT: + if (visible_r()) { + v = menu()->find_shortcut(); + if (v && v->submenu()) goto J1; + } + return test_shortcut() != 0; + } + return 0; +} +*/ + +#endif /* __APPLE__ */ + +// +// End of "$Id: Fl_Sys_Menu_Bar.cxx 6016 2008-01-09 21:32:40Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Tabs.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Tabs.cxx new file mode 100644 index 000000000..62cb71fb3 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Tabs.cxx @@ -0,0 +1,403 @@ +// +// "$Id: Fl_Tabs.cxx 5791 2007-05-01 20:20:21Z matt $" +// +// Tab widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// This is the "file card tabs" interface to allow you to put lots and lots +// of buttons and switches in a panel, as popularized by many toolkits. + +// Each child widget is a card, and it's label() is printed on the card tab. +// Clicking the tab makes that card visible. + +#include +#include +#include +#include +#include + +#define BORDER 2 +#define EXTRASPACE 10 + +// return the left edges of each tab (plus a fake left edge for a tab +// past the right-hand one). These position are actually of the left +// edge of the slope. They are either seperated by the correct distance +// or by EXTRASPACE or by zero. +// Return value is the index of the selected item. + +int Fl_Tabs::tab_positions(int* p, int* wp) { + int selected = 0; + Fl_Widget*const* a = array(); + int i; + char prev_draw_shortcut = fl_draw_shortcut; + fl_draw_shortcut = 1; + + p[0] = Fl::box_dx(box()); + for (i=0; ivisible()) selected = i; + + int wt = 0; int ht = 0; + o->measure_label(wt,ht); + + wp[i] = wt+EXTRASPACE; + p[i+1] = p[i]+wp[i]+BORDER; + } + fl_draw_shortcut = prev_draw_shortcut; + + int r = w(); + if (p[i] <= r) return selected; + // uh oh, they are too big: + // pack them against right edge: + p[i] = r; + for (i = children(); i--;) { + int l = r-wp[i]; + if (p[i+1] < l) l = p[i+1]; + if (p[i] <= l) break; + p[i] = l; + r -= EXTRASPACE; + } + // pack them against left edge and truncate width if they still don't fit: + for (i = 0; i= i*EXTRASPACE) break; + p[i] = i*EXTRASPACE; + int W = w()-1-EXTRASPACE*(children()-i) - p[i]; + if (wp[i] > W) wp[i] = W; + } + // adjust edges according to visiblity: + for (i = children(); i > selected; i--) { + p[i] = p[i-1]+wp[i-1]; + } + return selected; +} + +// return space needed for tabs. Negative to put them on the bottom: +int Fl_Tabs::tab_height() { + int H = h(); + int H2 = y(); + Fl_Widget*const* a = array(); + for (int i=children(); i--;) { + Fl_Widget* o = *a++; + if (o->y() < y()+H) H = o->y()-y(); + if (o->y()+o->h() > H2) H2 = o->y()+o->h(); + } + H2 = y()+h()-H2; + if (H2 > H) return (H2 <= 0) ? 0 : -H2; + else return (H <= 0) ? 0 : H; +} + +// this is used by fluid to pick tabs: +Fl_Widget *Fl_Tabs::which(int event_x, int event_y) { + int H = tab_height(); + if (H < 0) { + if (event_y > y()+h() || event_y < y()+h()+H) return 0; + } else { + if (event_y > y()+H || event_y < y()) return 0; + } + if (event_x < x()) return 0; + int p[128], wp[128]; + tab_positions(p, wp); + for (int i=0; i= 0) { + H += Fl::box_dy(box()); + damage(FL_DAMAGE_SCROLL, x(), y(), w(), H); + } else { + H = Fl::box_dy(box()) - H; + damage(FL_DAMAGE_SCROLL, x(), y() + h() - H, w(), H); + } +} + +int Fl_Tabs::handle(int event) { + + Fl_Widget *o; + int i; + + switch (event) { + + case FL_PUSH: { + int H = tab_height(); + if (H >= 0) { + if (Fl::event_y() > y()+H) return Fl_Group::handle(event); + } else { + if (Fl::event_y() < y()+h()+H) return Fl_Group::handle(event); + }} + case FL_DRAG: + case FL_RELEASE: + o = which(Fl::event_x(), Fl::event_y()); + if (event == FL_RELEASE) { + push(0); + if (o && Fl::visible_focus() && Fl::focus()!=this) { + Fl::focus(this); + redraw_tabs(); + } + if (o && value(o)) { + set_changed(); + do_callback(); + } + Fl_Tooltip::current(o); + } else { + push(o); + } + return 1; + case FL_MOVE: { + int ret = Fl_Group::handle(event); + Fl_Widget *o = Fl_Tooltip::current(), *n = o; + int H = tab_height(); + if ( (H>=0) && (Fl::event_y()>y()+H) ) + return ret; + else if ( (H<0) && (Fl::event_y() < y()+h()+H) ) + return ret; + else { + n = which(Fl::event_x(), Fl::event_y()); + if (!n) n = this; + } + if (n!=o) + Fl_Tooltip::enter(n); + return ret; } + case FL_FOCUS: + case FL_UNFOCUS: + if (!Fl::visible_focus()) return Fl_Group::handle(event); + if (Fl::event() == FL_RELEASE || + Fl::event() == FL_SHORTCUT || + Fl::event() == FL_KEYBOARD || + Fl::event() == FL_FOCUS || + Fl::event() == FL_UNFOCUS) { + redraw_tabs(); + if (Fl::event() == FL_FOCUS || Fl::event() == FL_UNFOCUS) return 0; + else return 1; + } else return Fl_Group::handle(event); + case FL_KEYBOARD: + switch (Fl::event_key()) { + case FL_Left: + if (child(0)->visible()) return 0; + for (i = 1; i < children(); i ++) + if (child(i)->visible()) break; + value(child(i - 1)); + set_changed(); + do_callback(); + return 1; + case FL_Right: + if (child(children() - 1)->visible()) return 0; + for (i = 0; i < children(); i ++) + if (child(i)->visible()) break; + value(child(i + 1)); + set_changed(); + do_callback(); + return 1; + case FL_Down: + redraw(); + return Fl_Group::handle(FL_FOCUS); + default: + break; + } + return Fl_Group::handle(event); + case FL_SHORTCUT: + for (i = 0; i < children(); ++i) { + Fl_Widget *c = child(i); + if (c->test_shortcut(c->label())) { + char sc = !c->visible(); + value(c); + if (sc) set_changed(); + do_callback(); + return 1; + } + } + return Fl_Group::handle(event); + case FL_SHOW: + value(); // update visibilities and fall through + default: + return Fl_Group::handle(event); + + } +} + +int Fl_Tabs::push(Fl_Widget *o) { + if (push_ == o) return 0; + if (push_ && !push_->visible() || o && !o->visible()) + redraw_tabs(); + push_ = o; + return 1; +} + +// The value() is the first visible child (or the last child if none +// are visible) and this also hides any other children. +// This allows the tabs to be deleted, moved to other groups, and +// show()/hide() called without it screwing up. +Fl_Widget* Fl_Tabs::value() { + Fl_Widget* v = 0; + Fl_Widget*const* a = array(); + for (int i=children(); i--;) { + Fl_Widget* o = *a++; + if (v) o->hide(); + else if (o->visible()) v = o; + else if (!i) {o->show(); v = o;} + } + return v; +} + +// Setting the value hides all other children, and makes this one +// visible, iff it is really a child: +int Fl_Tabs::value(Fl_Widget *newvalue) { + Fl_Widget*const* a = array(); + int ret = 0; + for (int i=children(); i--;) { + Fl_Widget* o = *a++; + if (o == newvalue) { + if (!o->visible()) ret = 1; + o->show(); + } else { + o->hide(); + } + } + return ret; +} + +enum {LEFT, RIGHT, SELECTED}; + +void Fl_Tabs::draw() { + Fl_Widget *v = value(); + int H = tab_height(); + + if (damage() & FL_DAMAGE_ALL) { // redraw the entire thing: + Fl_Color c = v ? v->color() : color(); + + draw_box(box(), x(), y()+(H>=0?H:0), w(), h()-(H>=0?H:-H), c); + + if (selection_color() != c) { + // Draw the top 5 lines of the tab pane in the selection color so + // that the user knows which tab is selected... + if (H >= 0) fl_push_clip(x(), y() + H, w(), 5); + else fl_push_clip(x(), y() + h() - H - 4, w(), 5); + + draw_box(box(), x(), y()+(H>=0?H:0), w(), h()-(H>=0?H:-H), + selection_color()); + + fl_pop_clip(); + } + if (v) draw_child(*v); + } else { // redraw the child + if (v) update_child(*v); + } + if (damage() & (FL_DAMAGE_SCROLL|FL_DAMAGE_ALL)) { + int p[128]; int wp[128]; + int selected = tab_positions(p,wp); + int i; + Fl_Widget*const* a = array(); + for (i=0; i selected; i--) + draw_tab(x()+p[i], x()+p[i+1], wp[i], H, a[i], RIGHT); + if (v) { + i = selected; + draw_tab(x()+p[i], x()+p[i+1], wp[i], H, a[i], SELECTED); + } + } +} + +void Fl_Tabs::draw_tab(int x1, int x2, int W, int H, Fl_Widget* o, int what) { + int sel = (what == SELECTED); + int dh = Fl::box_dh(box()); + int dy = Fl::box_dy(box()); + char prev_draw_shortcut = fl_draw_shortcut; + fl_draw_shortcut = 1; + + Fl_Boxtype bt = (o==push_ &&!sel) ? fl_down(box()) : box(); + + // compute offsets to make selected tab look bigger + int yofs = sel ? 0 : BORDER; + + if ((x2 < x1+W) && what == RIGHT) x1 = x2 - W; + + if (H >= 0) { + if (sel) fl_clip(x1, y(), x2 - x1, H + dh - dy); + else fl_clip(x1, y(), x2 - x1, H); + + H += dh; + + Fl_Color c = sel ? selection_color() : o->selection_color(); + + draw_box(bt, x1, y() + yofs, W, H + 10 - yofs, c); + + // Save the previous label color + Fl_Color oc = o->labelcolor(); + + // Draw the label using the current color... + o->labelcolor(sel ? labelcolor() : o->labelcolor()); + o->draw_label(x1, y() + yofs, W, H - yofs, FL_ALIGN_CENTER); + + // Restore the original label color... + o->labelcolor(oc); + + if (Fl::focus() == this && o->visible()) + draw_focus(box(), x1, y(), W, H); + + fl_pop_clip(); + } else { + H = -H; + + if (sel) fl_clip(x1, y() + h() - H - dy, x2 - x1, H + dy); + else fl_clip(x1, y() + h() - H, x2 - x1, H); + + H += dh; + + Fl_Color c = sel ? selection_color() : o->selection_color(); + + draw_box(bt, x1, y() + h() - H - 10, W, H + 10 - yofs, c); + + // Save the previous label color + Fl_Color oc = o->labelcolor(); + + // Draw the label using the current color... + o->labelcolor(sel ? labelcolor() : o->labelcolor()); + o->draw_label(x1, y() + h() - H, W, H - yofs, FL_ALIGN_CENTER); + + // Restore the original label color... + o->labelcolor(oc); + + if (Fl::focus() == this && o->visible()) + draw_focus(box(), x1, y() + h() - H, W, H); + + fl_pop_clip(); + } + fl_draw_shortcut = prev_draw_shortcut; +} + +Fl_Tabs::Fl_Tabs(int X,int Y,int W, int H, const char *l) : + Fl_Group(X,Y,W,H,l) +{ + box(FL_THIN_UP_BOX); + push_ = 0; +} + +// +// End of "$Id: Fl_Tabs.cxx 5791 2007-05-01 20:20:21Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Text_Buffer.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Text_Buffer.cxx new file mode 100644 index 000000000..8872bdf24 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Text_Buffer.cxx @@ -0,0 +1,2534 @@ +// +// "$Id: Fl_Text_Buffer.cxx 6011 2008-01-04 20:32:37Z matt $" +// +// Copyright 2001-2005 by Bill Spitzak and others. +// Original code Copyright Mark Edel. Permission to distribute under +// the LGPL for the FLTK library granted by Mark Edel. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include "flstring.h" +#include +#include +#include + + +#define PREFERRED_GAP_SIZE 1024 +/* Initial size for the buffer gap (empty space +in the buffer where text might be inserted +if the user is typing sequential chars ) */ + +static void histogramCharacters( const char *string, int length, char hist[ 256 ], + int init ); +static void subsChars( char *string, int length, char fromChar, char toChar ); +static char chooseNullSubsChar( char hist[ 256 ] ); +static void insertColInLine( const char *line, char *insLine, int column, int insWidth, + int tabDist, int useTabs, char nullSubsChar, char *outStr, int *outLen, + int *endOffset ); +static void deleteRectFromLine( const char *line, int rectStart, int rectEnd, + int tabDist, int useTabs, char nullSubsChar, char *outStr, int *outLen, + int *endOffset ); +static void overlayRectInLine( const char *line, char *insLine, int rectStart, + int rectEnd, int tabDist, int useTabs, char nullSubsChar, char *outStr, + int *outLen, int *endOffset ); + +static void addPadding( char *string, int startIndent, int toIndent, + int tabDist, int useTabs, char nullSubsChar, int *charsAdded ); +static char *copyLine( const char* text, int *lineLen ); +static int countLines( const char *string ); +static int textWidth( const char *text, int tabDist, char nullSubsChar ); +static char *realignTabs( const char *text, int origIndent, int newIndent, + int tabDist, int useTabs, char nullSubsChar, int *newLength ); +static char *expandTabs( const char *text, int startIndent, int tabDist, + char nullSubsChar, int *newLen ); +static char *unexpandTabs( char *text, int startIndent, int tabDist, + char nullSubsChar, int *newLen ); +static int max( int i1, int i2 ); +static int min( int i1, int i2 ); + +static const char *ControlCodeTable[ 32 ] = { + "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel", + "bs", "ht", "nl", "vt", "np", "cr", "so", "si", + "dle", "dc1", "dc2", "dc3", "dc4", "nak", "syn", "etb", + "can", "em", "sub", "esc", "fs", "gs", "rs", "us"}; + +static char* undobuffer; +static int undobufferlength; +static Fl_Text_Buffer* undowidget; +static int undoat; // points after insertion +static int undocut; // number of characters deleted there +static int undoinsert; // number of characters inserted +static int undoyankcut; // length of valid contents of buffer, even if undocut=0 + +static void undobuffersize(int n) { + if (n > undobufferlength) { + if (undobuffer) { + do {undobufferlength *= 2;} while (undobufferlength < n); + undobuffer = (char*)realloc(undobuffer, undobufferlength); + } else { + undobufferlength = n+9; + undobuffer = (char*)malloc(undobufferlength); + } + } +} + +/* +** Create an empty text buffer of a pre-determined size (use this to +** avoid unnecessary re-allocation if you know exactly how much the buffer +** will need to hold +*/ +Fl_Text_Buffer::Fl_Text_Buffer( int requestedSize ) { + mLength = 0; + mBuf = (char *)malloc( requestedSize + PREFERRED_GAP_SIZE ); + mGapStart = 0; + mGapEnd = PREFERRED_GAP_SIZE; + mTabDist = 8; + mUseTabs = 1; + mPrimary.mSelected = 0; + mPrimary.mRectangular = 0; + mPrimary.mStart = mPrimary.mEnd = 0; + mSecondary.mSelected = 0; + mSecondary.mStart = mSecondary.mEnd = 0; + mSecondary.mRectangular = 0; + mHighlight.mSelected = 0; + mHighlight.mStart = mHighlight.mEnd = 0; + mHighlight.mRectangular = 0; + mNodifyProcs = NULL; + mCbArgs = NULL; + mNModifyProcs = 0; + mNPredeleteProcs = 0; + mPredeleteProcs = NULL; + mPredeleteCbArgs = NULL; + mCursorPosHint = 0; + mNullSubsChar = '\0'; + mCanUndo = 1; +#ifdef PURIFY +{ int i; for (i = mGapStart; i < mGapEnd; i++) mBuf[ i ] = '.'; } +#endif +} + +/* +** Free a text buffer +*/ +Fl_Text_Buffer::~Fl_Text_Buffer() { + free( mBuf ); + if ( mNModifyProcs != 0 ) { + delete[] mNodifyProcs; + delete[] mCbArgs; + } + if ( mNPredeleteProcs != 0 ) { + delete[] mPredeleteProcs; + delete[] mPredeleteCbArgs; + } +} + +/* +** Get the entire contents of a text buffer. Memory is allocated to contain +** the returned string, which the caller must free. +*/ +char * Fl_Text_Buffer::text() { + char *t; + + t = (char *)malloc( mLength + 1 ); + memcpy( t, mBuf, mGapStart ); + memcpy( &t[ mGapStart ], &mBuf[ mGapEnd ], + mLength - mGapStart ); + t[ mLength ] = '\0'; + return t; +} + +/* +** Replace the entire contents of the text buffer +*/ +void Fl_Text_Buffer::text( const char *t ) { + int insertedLength, deletedLength; + const char *deletedText; + + call_predelete_callbacks(0, length()); + + /* Save information for redisplay, and get rid of the old buffer */ + deletedText = text(); + deletedLength = mLength; + free( (void *)mBuf ); + + /* Start a new buffer with a gap of PREFERRED_GAP_SIZE in the center */ + insertedLength = strlen( t ); + mBuf = (char *)malloc( insertedLength + PREFERRED_GAP_SIZE ); + mLength = insertedLength; + mGapStart = insertedLength / 2; + mGapEnd = mGapStart + PREFERRED_GAP_SIZE; + memcpy( mBuf, t, mGapStart ); + memcpy( &mBuf[ mGapEnd ], &t[ mGapStart ], insertedLength - mGapStart ); +#ifdef PURIFY +{ int i; for ( i = mGapStart; i < mGapEnd; i++ ) mBuf[ i ] = '.'; } +#endif + + /* Zero all of the existing selections */ + update_selections( 0, deletedLength, 0 ); + + /* Call the saved display routine(s) to update the screen */ + call_modify_callbacks( 0, deletedLength, insertedLength, 0, deletedText ); + free( (void *)deletedText ); +} + +/* +** Return a copy of the text between "start" and "end" character positions +** from text buffer "buf". Positions start at 0, and the range does not +** include the character pointed to by "end" +*/ +char * Fl_Text_Buffer::text_range( int start, int end ) { + char * s; + int copiedLength, part1Length; + + /* Make sure start and end are ok, and allocate memory for returned string. + If start is bad, return "", if end is bad, adjust it. */ + if ( start < 0 || start > mLength ) { + s = (char *)malloc( 1 ); + s[ 0 ] = '\0'; + return s; + } + if ( end < start ) { + int temp = start; + start = end; + end = temp; + } + if ( end > mLength ) + end = mLength; + copiedLength = end - start; + s = (char *)malloc( copiedLength + 1 ); + + /* Copy the text from the buffer to the returned string */ + if ( end <= mGapStart ) { + memcpy( s, &mBuf[ start ], copiedLength ); + } else if ( start >= mGapStart ) { + memcpy( s, &mBuf[ start + ( mGapEnd - mGapStart ) ], copiedLength ); + } else { + part1Length = mGapStart - start; + memcpy( s, &mBuf[ start ], part1Length ); + memcpy( &s[ part1Length ], &mBuf[ mGapEnd ], copiedLength - part1Length ); + } + s[ copiedLength ] = '\0'; + return s; +} + +/* +** Return the character at buffer position "pos". Positions start at 0. +*/ +char Fl_Text_Buffer::character( int pos ) { + if ( pos < 0 || pos >= mLength ) + return '\0'; + if ( pos < mGapStart ) + return mBuf[ pos ]; + else + return mBuf[ pos + mGapEnd - mGapStart ]; +} + +/* +** Insert null-terminated string "text" at position "pos" in "buf" +*/ +void Fl_Text_Buffer::insert( int pos, const char *s ) { + int nInserted; + + /* if pos is not contiguous to existing text, make it */ + if ( pos > mLength ) pos = mLength; + if ( pos < 0 ) pos = 0; + + /* Even if nothing is deleted, we must call these callbacks */ + call_predelete_callbacks( pos, 0 ); + + /* insert and redisplay */ + nInserted = insert_( pos, s ); + mCursorPosHint = pos + nInserted; + call_modify_callbacks( pos, 0, nInserted, 0, NULL ); +} + +/* +** Delete the characters between "start" and "end", and insert the +** null-terminated string "text" in their place in in "buf" +*/ +void Fl_Text_Buffer::replace( int start, int end, const char *s ) { + const char * deletedText; + int nInserted; + + // Range check... + if (!s) return; + if (start < 0) start = 0; + if (end > mLength) end = mLength; + + call_predelete_callbacks( start, end-start ); + deletedText = text_range( start, end ); + remove_( start, end ); + //undoyankcut = undocut; + nInserted = insert_( start, s ); + mCursorPosHint = start + nInserted; + call_modify_callbacks( start, end - start, nInserted, 0, deletedText ); + free( (void *)deletedText ); +} + +void Fl_Text_Buffer::remove( int start, int end ) { + const char * deletedText; + + /* Make sure the arguments make sense */ + if ( start > end ) { + int temp = start; + start = end; + end = temp; + } + if ( start > mLength ) start = mLength; + if ( start < 0 ) start = 0; + if ( end > mLength ) end = mLength; + if ( end < 0 ) end = 0; + + if (start == end) return; + + call_predelete_callbacks( start, end-start ); + /* Remove and redisplay */ + deletedText = text_range( start, end ); + remove_( start, end ); + mCursorPosHint = start; + call_modify_callbacks( start, end - start, 0, 0, deletedText ); + free( (void *)deletedText ); +} + +void Fl_Text_Buffer::copy( Fl_Text_Buffer *fromBuf, int fromStart, + int fromEnd, int toPos ) { + int copiedLength = fromEnd - fromStart; + int part1Length; + + /* Prepare the buffer to receive the new text. If the new text fits in + the current buffer, just move the gap (if necessary) to where + the text should be inserted. If the new text is too large, reallocate + the buffer with a gap large enough to accomodate the new text and a + gap of PREFERRED_GAP_SIZE */ + if ( copiedLength > mGapEnd - mGapStart ) + reallocate_with_gap( toPos, copiedLength + PREFERRED_GAP_SIZE ); + else if ( toPos != mGapStart ) + move_gap( toPos ); + + /* Insert the new text (toPos now corresponds to the start of the gap) */ + if ( fromEnd <= fromBuf->mGapStart ) { + memcpy( &mBuf[ toPos ], &fromBuf->mBuf[ fromStart ], copiedLength ); + } else if ( fromStart >= fromBuf->mGapStart ) { + memcpy( &mBuf[ toPos ], + &fromBuf->mBuf[ fromStart + ( fromBuf->mGapEnd - fromBuf->mGapStart ) ], + copiedLength ); + } else { + part1Length = fromBuf->mGapStart - fromStart; + memcpy( &mBuf[ toPos ], &fromBuf->mBuf[ fromStart ], part1Length ); + memcpy( &mBuf[ toPos + part1Length ], &fromBuf->mBuf[ fromBuf->mGapEnd ], + copiedLength - part1Length ); + } + mGapStart += copiedLength; + mLength += copiedLength; + update_selections( toPos, 0, copiedLength ); +} + +/* +** remove text according to the undo variables or insert text +** from the undo buffer +*/ +int Fl_Text_Buffer::undo(int *cursorPos) { + if (undowidget != this || !undocut && !undoinsert &&!mCanUndo) return 0; + + int ilen = undocut; + int xlen = undoinsert; + int b = undoat-xlen; + + if (xlen && undoyankcut && !ilen) { + ilen = undoyankcut; + } + + if (xlen && ilen) { + undobuffersize(ilen+1); + undobuffer[ilen] = 0; + char *tmp = strdup(undobuffer); + replace(b, undoat, tmp); + if (cursorPos) *cursorPos = mCursorPosHint; + free(tmp); + } + else if (xlen) { + remove(b, undoat); + if (cursorPos) *cursorPos = mCursorPosHint; + } + else if (ilen) { + undobuffersize(ilen+1); + undobuffer[ilen] = 0; + insert(undoat, undobuffer); + if (cursorPos) *cursorPos = mCursorPosHint; + undoyankcut = 0; + } + + return 1; +} + +/* +** let the undo system know if we can undo changes +*/ +void Fl_Text_Buffer::canUndo(char flag) { + mCanUndo = flag; +} + +/* +** Insert "text" columnwise into buffer starting at displayed character +** position "column" on the line beginning at "startPos". Opens a rectangular +** space the width and height of "text", by moving all text to the right of +** "column" right. If charsInserted and charsDeleted are not NULL, the +** number of characters inserted and deleted in the operation (beginning +** at startPos) are returned in these arguments +*/ +void Fl_Text_Buffer::insert_column( int column, int startPos, const char *s, + int *charsInserted, int *charsDeleted ) { + int nLines, lineStartPos, nDeleted, insertDeleted, nInserted; + const char *deletedText; + + nLines = countLines( s ); + lineStartPos = line_start( startPos ); + nDeleted = line_end( skip_lines( startPos, nLines ) ) - + lineStartPos; + call_predelete_callbacks( lineStartPos, nDeleted ); + deletedText = text_range( lineStartPos, lineStartPos + nDeleted ); + insert_column_( column, lineStartPos, s, &insertDeleted, &nInserted, + &mCursorPosHint ); + if ( nDeleted != insertDeleted ) + Fl::error("Fl_Text_Buffer::insert_column(): internal consistency check ins1 failed"); + call_modify_callbacks( lineStartPos, nDeleted, nInserted, 0, deletedText ); + free( (void *) deletedText ); + if ( charsInserted != NULL ) + * charsInserted = nInserted; + if ( charsDeleted != NULL ) + * charsDeleted = nDeleted; +} + +/* +** Overlay "text" between displayed character positions "rectStart" and +** "rectEnd" on the line beginning at "startPos". If charsInserted and +** charsDeleted are not NULL, the number of characters inserted and deleted +** in the operation (beginning at startPos) are returned in these arguments. +*/ +void Fl_Text_Buffer::overlay_rectangular( int startPos, int rectStart, + int rectEnd, const char *s, int *charsInserted, int *charsDeleted ) { + int nLines, lineStartPos, nDeleted, insertDeleted, nInserted; + const char *deletedText; + + nLines = countLines( s ); + lineStartPos = line_start( startPos ); + nDeleted = line_end( skip_lines( startPos, nLines ) ) - + lineStartPos; + call_predelete_callbacks( lineStartPos, nDeleted ); + deletedText = text_range( lineStartPos, lineStartPos + nDeleted ); + overlay_rectangular_( lineStartPos, rectStart, rectEnd, s, &insertDeleted, + &nInserted, &mCursorPosHint ); + if ( nDeleted != insertDeleted ) + Fl::error("Fl_Text_Buffer::overlay_rectangle(): internal consistency check ovly1 failed"); + call_modify_callbacks( lineStartPos, nDeleted, nInserted, 0, deletedText ); + free( (void *) deletedText ); + if ( charsInserted != NULL ) + * charsInserted = nInserted; + if ( charsDeleted != NULL ) + * charsDeleted = nDeleted; +} + +/* +** Replace a rectangular area in buf, given by "start", "end", "rectStart", +** and "rectEnd", with "text". If "text" is vertically longer than the +** rectangle, add extra lines to make room for it. +*/ +void Fl_Text_Buffer::replace_rectangular( int start, int end, int rectStart, + int rectEnd, const char *s ) { + char *insPtr; + const char *deletedText; + char *insText = (char *)""; + int i, nInsertedLines, nDeletedLines, insLen, hint; + int insertDeleted, insertInserted, deleteInserted; + int linesPadded = 0; + + /* Make sure start and end refer to complete lines, since the + columnar delete and insert operations will replace whole lines */ + start = line_start( start ); + end = line_end( end ); + + call_predelete_callbacks( start, end-start ); + + /* If more lines will be deleted than inserted, pad the inserted text + with newlines to make it as long as the number of deleted lines. This + will indent all of the text to the right of the rectangle to the same + column. If more lines will be inserted than deleted, insert extra + lines in the buffer at the end of the rectangle to make room for the + additional lines in "text" */ + nInsertedLines = countLines( s ); + nDeletedLines = count_lines( start, end ); + if ( nInsertedLines < nDeletedLines ) { + insLen = strlen( s ); + insText = (char *)malloc( insLen + nDeletedLines - nInsertedLines + 1 ); + strcpy( insText, s ); + insPtr = insText + insLen; + for ( i = 0; i < nDeletedLines - nInsertedLines; i++ ) + *insPtr++ = '\n'; + *insPtr = '\0'; + } else if ( nDeletedLines < nInsertedLines ) { + linesPadded = nInsertedLines - nDeletedLines; + for ( i = 0; i < linesPadded; i++ ) + insert_( end, "\n" ); + } /* else nDeletedLines == nInsertedLines; */ + + /* Save a copy of the text which will be modified for the modify CBs */ + deletedText = text_range( start, end ); + + /* Delete then insert */ + remove_rectangular_( start, end, rectStart, rectEnd, &deleteInserted, &hint ); + insert_column_( rectStart, start, insText, &insertDeleted, &insertInserted, + &mCursorPosHint ); + + /* Figure out how many chars were inserted and call modify callbacks */ + if ( insertDeleted != deleteInserted + linesPadded ) + Fl::error("Fl_Text_Buffer::replace_rectangular(): internal consistency check repl1 failed"); + call_modify_callbacks( start, end - start, insertInserted, 0, deletedText ); + free( (void *) deletedText ); + if ( nInsertedLines < nDeletedLines ) + free( (void *) insText ); +} + +/* +** Remove a rectangular swath of characters between character positions start +** and end and horizontal displayed-character offsets rectStart and rectEnd. +*/ +void Fl_Text_Buffer::remove_rectangular( int start, int end, int rectStart, + int rectEnd ) { + const char * deletedText; + int nInserted; + + start = line_start( start ); + end = line_end( end ); + call_predelete_callbacks( start, end-start ); + deletedText = text_range( start, end ); + remove_rectangular_( start, end, rectStart, rectEnd, &nInserted, + &mCursorPosHint ); + call_modify_callbacks( start, end - start, nInserted, 0, deletedText ); + free( (void *) deletedText ); +} + +/* +** Clear a rectangular "hole" out of the buffer between character positions +** start and end and horizontal displayed-character offsets rectStart and +** rectEnd. +*/ +void Fl_Text_Buffer::clear_rectangular( int start, int end, int rectStart, + int rectEnd ) { + int i, nLines; + char *newlineString; + + nLines = count_lines( start, end ); + newlineString = (char *)malloc( nLines + 1 ); + for ( i = 0; i < nLines; i++ ) + newlineString[ i ] = '\n'; + newlineString[ i ] = '\0'; + overlay_rectangular( start, rectStart, rectEnd, newlineString, + NULL, NULL ); + free( (void *) newlineString ); +} + +char * Fl_Text_Buffer::text_in_rectangle( int start, int end, + int rectStart, int rectEnd ) { + int lineStart, selLeft, selRight, len; + char *textOut, *outPtr, *retabbedStr; + const char *textIn; + + start = line_start( start ); + end = line_end( end ); + textOut = (char *)malloc( ( end - start ) + 1 ); + lineStart = start; + outPtr = textOut; + while ( lineStart <= end ) { + rectangular_selection_boundaries( lineStart, rectStart, rectEnd, + &selLeft, &selRight ); + textIn = text_range( selLeft, selRight ); + len = selRight - selLeft; + memcpy( outPtr, textIn, len ); + free( (void *) textIn ); + outPtr += len; + lineStart = line_end( selRight ) + 1; + *outPtr++ = '\n'; + } + if ( outPtr != textOut ) + outPtr--; /* don't leave trailing newline */ + *outPtr = '\0'; + + /* If necessary, realign the tabs in the selection as if the text were + positioned at the left margin */ + retabbedStr = realignTabs( textOut, rectStart, 0, mTabDist, + mUseTabs, mNullSubsChar, &len ); + free( (void *) textOut ); + return retabbedStr; +} + +/* +** Set the hardware tab distance used by all displays for this buffer, +** and used in computing offsets for rectangular selection operations. +*/ +void Fl_Text_Buffer::tab_distance( int tabDist ) { + const char * deletedText; + + /* First call the pre-delete callbacks with the previous tab setting + still active. */ + call_predelete_callbacks( 0, mLength ); + + /* Change the tab setting */ + mTabDist = tabDist; + + /* Force any display routines to redisplay everything (unfortunately, + this means copying the whole buffer contents to provide "deletedText" */ + deletedText = text(); + call_modify_callbacks( 0, mLength, mLength, 0, deletedText ); + free( (void *) deletedText ); +} + +void Fl_Text_Buffer::select( int start, int end ) { + Fl_Text_Selection oldSelection = mPrimary; + + mPrimary.set( start, end ); + redisplay_selection( &oldSelection, &mPrimary ); +} + +void Fl_Text_Buffer::unselect() { + Fl_Text_Selection oldSelection = mPrimary; + + mPrimary.mSelected = 0; + redisplay_selection( &oldSelection, &mPrimary ); +} + +void Fl_Text_Buffer::select_rectangular( int start, int end, int rectStart, + int rectEnd ) { + Fl_Text_Selection oldSelection = mPrimary; + + mPrimary.set_rectangular( start, end, rectStart, rectEnd ); + redisplay_selection( &oldSelection, &mPrimary ); +} + +int Fl_Text_Buffer::selection_position( int *start, int *end + ) { + return mPrimary.position( start, end ); +} + +int Fl_Text_Buffer::selection_position( int *start, int *end, + int *isRect, int *rectStart, int *rectEnd ) { + return mPrimary.position( start, end, isRect, rectStart, + rectEnd ); +} + +char * Fl_Text_Buffer::selection_text() { + return selection_text_( &mPrimary ); +} + +void Fl_Text_Buffer::remove_selection() { + remove_selection_( &mPrimary ); +} + +void Fl_Text_Buffer::replace_selection( const char *s ) { + replace_selection_( &mPrimary, s ); +} + +void Fl_Text_Buffer::secondary_select( int start, int end ) { + Fl_Text_Selection oldSelection = mSecondary; + + mSecondary.set( start, end ); + redisplay_selection( &oldSelection, &mSecondary ); +} + +void Fl_Text_Buffer::secondary_unselect() { + Fl_Text_Selection oldSelection = mSecondary; + + mSecondary.mSelected = 0; + redisplay_selection( &oldSelection, &mSecondary ); +} + +void Fl_Text_Buffer::secondary_select_rectangular( int start, int end, + int rectStart, int rectEnd ) { + Fl_Text_Selection oldSelection = mSecondary; + + mSecondary.set_rectangular( start, end, rectStart, rectEnd ); + redisplay_selection( &oldSelection, &mSecondary ); +} + +int Fl_Text_Buffer::secondary_selection_position( int *start, int *end + ) { + return mSecondary.position( start, end ); +} + +int Fl_Text_Buffer::secondary_selection_position( int *start, int *end, + int *isRect, int *rectStart, int *rectEnd ) { + return mSecondary.position( start, end, isRect, rectStart, + rectEnd ); +} + +char * Fl_Text_Buffer::secondary_selection_text() { + return selection_text_( &mSecondary ); +} + +void Fl_Text_Buffer::remove_secondary_selection() { + remove_selection_( &mSecondary ); +} + +void Fl_Text_Buffer::replace_secondary_selection( const char *s ) { + replace_selection_( &mSecondary, s ); +} + +void Fl_Text_Buffer::highlight( int start, int end ) { + Fl_Text_Selection oldSelection = mHighlight; + + mHighlight.set( start, end ); + redisplay_selection( &oldSelection, &mHighlight ); +} + +void Fl_Text_Buffer::unhighlight() { + Fl_Text_Selection oldSelection = mHighlight; + + mHighlight.mSelected = 0; + redisplay_selection( &oldSelection, &mHighlight ); +} + +void Fl_Text_Buffer::highlight_rectangular( int start, int end, + int rectStart, int rectEnd ) { + Fl_Text_Selection oldSelection = mHighlight; + + mHighlight.set_rectangular( start, end, rectStart, rectEnd ); + redisplay_selection( &oldSelection, &mHighlight ); +} + +int Fl_Text_Buffer::highlight_position( int *start, int *end + ) { + return mHighlight.position( start, end ); +} + +int Fl_Text_Buffer::highlight_position( int *start, int *end, + int *isRect, int *rectStart, int *rectEnd ) { + return mHighlight.position( start, end, isRect, rectStart, + rectEnd ); +} + +char * Fl_Text_Buffer::highlight_text() { + return selection_text_( &mHighlight ); +} + +/* +** Add a callback routine to be called when the buffer is modified +*/ +void Fl_Text_Buffer::add_modify_callback( Fl_Text_Modify_Cb bufModifiedCB, + void *cbArg ) { + Fl_Text_Modify_Cb * newModifyProcs; + void **newCBArgs; + int i; + + newModifyProcs = new Fl_Text_Modify_Cb [ mNModifyProcs + 1 ]; + newCBArgs = new void * [ mNModifyProcs + 1 ]; + for ( i = 0; i < mNModifyProcs; i++ ) { + newModifyProcs[ i + 1 ] = mNodifyProcs[ i ]; + newCBArgs[ i + 1 ] = mCbArgs[ i ]; + } + if ( mNModifyProcs != 0 ) { + delete [] mNodifyProcs; + delete [] mCbArgs; + } + newModifyProcs[ 0 ] = bufModifiedCB; + newCBArgs[ 0 ] = cbArg; + mNModifyProcs++; + mNodifyProcs = newModifyProcs; + mCbArgs = newCBArgs; +} + +void Fl_Text_Buffer::remove_modify_callback( Fl_Text_Modify_Cb bufModifiedCB, + void *cbArg ) { + int i, toRemove = -1; + Fl_Text_Modify_Cb *newModifyProcs; + void **newCBArgs; + + /* find the matching callback to remove */ + for ( i = 0; i < mNModifyProcs; i++ ) { + if ( mNodifyProcs[ i ] == bufModifiedCB && mCbArgs[ i ] == cbArg ) { + toRemove = i; + break; + } + } + if ( toRemove == -1 ) { + Fl::error("Fl_Text_Buffer::remove_modify_callback(): Can't find modify CB to remove"); + return; + } + + /* Allocate new lists for remaining callback procs and args (if + any are left) */ + mNModifyProcs--; + if ( mNModifyProcs == 0 ) { + mNModifyProcs = 0; + delete[] mNodifyProcs; + mNodifyProcs = NULL; + delete[] mCbArgs; + mCbArgs = NULL; + return; + } + newModifyProcs = new Fl_Text_Modify_Cb [ mNModifyProcs ]; + newCBArgs = new void * [ mNModifyProcs ]; + + /* copy out the remaining members and free the old lists */ + for ( i = 0; i < toRemove; i++ ) { + newModifyProcs[ i ] = mNodifyProcs[ i ]; + newCBArgs[ i ] = mCbArgs[ i ]; + } + for ( ; i < mNModifyProcs; i++ ) { + newModifyProcs[ i ] = mNodifyProcs[ i + 1 ]; + newCBArgs[ i ] = mCbArgs[ i + 1 ]; + } + delete[] mNodifyProcs; + delete[] mCbArgs; + mNodifyProcs = newModifyProcs; + mCbArgs = newCBArgs; +} + +/* +** Add a callback routine to be called before text is deleted from the buffer. +*/ +void Fl_Text_Buffer::add_predelete_callback(Fl_Text_Predelete_Cb bufPreDeleteCB, + void *cbArg) { + Fl_Text_Predelete_Cb *newPreDeleteProcs; + void **newCBArgs; + int i; + + newPreDeleteProcs = new Fl_Text_Predelete_Cb[ mNPredeleteProcs + 1 ]; + newCBArgs = new void * [ mNPredeleteProcs + 1 ]; + for ( i = 0; i < mNPredeleteProcs; i++ ) { + newPreDeleteProcs[i + 1] = mPredeleteProcs[i]; + newCBArgs[i + 1] = mPredeleteCbArgs[i]; + } + if (! mNPredeleteProcs != 0) { + delete [] mPredeleteProcs; + delete [] mPredeleteCbArgs; + } + newPreDeleteProcs[0] = bufPreDeleteCB; + newCBArgs[0] = cbArg; + mNPredeleteProcs++; + mPredeleteProcs = newPreDeleteProcs; + mPredeleteCbArgs = newCBArgs; +} + +void Fl_Text_Buffer::remove_predelete_callback( + Fl_Text_Predelete_Cb bufPreDeleteCB, void *cbArg) { + int i, toRemove = -1; + Fl_Text_Predelete_Cb *newPreDeleteProcs; + void **newCBArgs; + + /* find the matching callback to remove */ + for ( i = 0; i < mNPredeleteProcs; i++) { + if (mPredeleteProcs[i] == bufPreDeleteCB && + mPredeleteCbArgs[i] == cbArg) { + toRemove = i; + break; + } + } + if (toRemove == -1) { + Fl::error("Fl_Text_Buffer::remove_predelete_callback(): Can't find pre-delete CB to remove"); + return; + } + + /* Allocate new lists for remaining callback procs and args (if + any are left) */ + mNPredeleteProcs--; + if (mNPredeleteProcs == 0) { + mNPredeleteProcs = 0; + delete[] mPredeleteProcs; + mPredeleteProcs = NULL; + delete[] mPredeleteCbArgs; + mPredeleteCbArgs = NULL; + return; + } + newPreDeleteProcs = new Fl_Text_Predelete_Cb [ mNPredeleteProcs ]; + newCBArgs = new void * [ mNPredeleteProcs ]; + + /* copy out the remaining members and free the old lists */ + for ( i = 0; i < toRemove; i++) { + newPreDeleteProcs[i] = mPredeleteProcs[i]; + newCBArgs[i] = mPredeleteCbArgs[i]; + } + for ( ; i < mNPredeleteProcs; i++) { + newPreDeleteProcs[i] = mPredeleteProcs[i+1]; + newCBArgs[i] = mPredeleteCbArgs[i+1]; + } + delete[] mPredeleteProcs; + delete[] mPredeleteCbArgs; + mPredeleteProcs = newPreDeleteProcs; + mPredeleteCbArgs = newCBArgs; +} + +/* +** Return the text from the entire line containing position "pos" +*/ +char * Fl_Text_Buffer::line_text( int pos ) { + return text_range( line_start( pos ), line_end( pos ) ); +} + +/* +** Find the position of the start of the line containing position "pos" +*/ +int Fl_Text_Buffer::line_start( int pos ) { + if ( !findchar_backward( pos, '\n', &pos ) ) + return 0; + return pos + 1; +} + +/* +** Find the position of the end of the line containing position "pos" +** (which is either a pointer to the newline character ending the line, +** or a pointer to one character beyond the end of the buffer) +*/ +int Fl_Text_Buffer::line_end( int pos ) { + if ( !findchar_forward( pos, '\n', &pos ) ) + pos = mLength; + return pos; +} + +int Fl_Text_Buffer::word_start( int pos ) { + while ( pos && ( isalnum( character( pos ) ) || character( pos ) == '_' ) ) { + pos--; + } + if ( !( isalnum( character( pos ) ) || character( pos ) == '_' ) ) pos++; + return pos; +} + +int Fl_Text_Buffer::word_end( int pos ) { + while (pos < length() && (isalnum(character(pos)) || character(pos) == '_' )) { + pos++; + } + return pos; +} + +/* +** Get a character from the text buffer expanded into it's screen +** representation (which may be several characters for a tab or a +** control code). Returns the number of characters written to "outStr". +** "indent" is the number of characters from the start of the line +** for figuring tabs. Output string is guranteed to be shorter or +** equal in length to FL_TEXT_MAX_EXP_CHAR_LEN +*/ +int Fl_Text_Buffer::expand_character( int pos, int indent, char *outStr ) { + return expand_character( character( pos ), indent, outStr, + mTabDist, mNullSubsChar ); +} + +/* +** Expand a single character from the text buffer into it's screen +** representation (which may be several characters for a tab or a +** control code). Returns the number of characters added to "outStr". +** "indent" is the number of characters from the start of the line +** for figuring tabs. Output string is guranteed to be shorter or +** equal in length to FL_TEXT_MAX_EXP_CHAR_LEN +*/ +int Fl_Text_Buffer::expand_character( char c, int indent, char *outStr, int tabDist, + char nullSubsChar ) { + int i, nSpaces; + + /* Convert tabs to spaces */ + if ( c == '\t' ) { + nSpaces = tabDist - ( indent % tabDist ); + for ( i = 0; i < nSpaces; i++ ) + outStr[ i ] = ' '; + return nSpaces; + } + + /* Convert control codes to readable character sequences */ + /*... is this safe with international character sets? */ + if ( ( ( unsigned char ) c ) <= 31 ) { + sprintf( outStr, "<%s>", ControlCodeTable[ ( unsigned char ) c ] ); + return strlen( outStr ); + } else if ( c == 127 ) { + sprintf( outStr, "" ); + return 5; + } else if ( c == nullSubsChar ) { + sprintf( outStr, "" ); + return 5; + } + + /* Otherwise, just return the character */ + *outStr = c; + return 1; +} + +/* +** Return the length in displayed characters of character "c" expanded +** for display (as discussed above in BufGetExpandedChar). If the +** buffer for which the character width is being measured is doing null +** substitution, nullSubsChar should be passed as that character (or nul +** to ignore). +*/ +int Fl_Text_Buffer::character_width( char c, int indent, int tabDist, char nullSubsChar ) { + /* Note, this code must parallel that in Fl_Text_Buffer::ExpandCharacter */ + if ( c == '\t' ) + return tabDist - ( indent % tabDist ); + else if ( ( ( unsigned char ) c ) <= 31 ) + return strlen( ControlCodeTable[ ( unsigned char ) c ] ) + 2; + else if ( c == 127 ) + return 5; + else if ( c == nullSubsChar ) + return 5; + return 1; +} + +/* +** Count the number of displayed characters between buffer position +** "lineStartPos" and "targetPos". (displayed characters are the characters +** shown on the screen to represent characters in the buffer, where tabs and +** control characters are expanded) +*/ +int Fl_Text_Buffer::count_displayed_characters( int lineStartPos, int targetPos ) { + int pos, charCount = 0; + char expandedChar[ FL_TEXT_MAX_EXP_CHAR_LEN ]; + + pos = lineStartPos; + while ( pos < targetPos ) + charCount += expand_character( pos++, charCount, expandedChar ); + return charCount; +} + +/* +** Count forward from buffer position "startPos" in displayed characters +** (displayed characters are the characters shown on the screen to represent +** characters in the buffer, where tabs and control characters are expanded) +*/ +int Fl_Text_Buffer::skip_displayed_characters( int lineStartPos, int nChars ) { + int pos, charCount = 0; + char c; + + pos = lineStartPos; + while ( charCount < nChars && pos < mLength ) { + c = character( pos ); + if ( c == '\n' ) + return pos; + charCount += character_width( c, charCount, mTabDist, mNullSubsChar ); + pos++; + } + return pos; +} + +/* +** Count the number of newlines between startPos and endPos in buffer "buf". +** The character at position "endPos" is not counted. +*/ +int Fl_Text_Buffer::count_lines( int startPos, int endPos ) { + int pos, gapLen = mGapEnd - mGapStart; + int lineCount = 0; + + pos = startPos; + while ( pos < mGapStart ) { + if ( pos == endPos ) + return lineCount; + if ( mBuf[ pos++ ] == '\n' ) + lineCount++; + } + while ( pos < mLength ) { + if ( pos == endPos ) + return lineCount; + if ( mBuf[ pos++ + gapLen ] == '\n' ) + lineCount++; + } + return lineCount; +} + +/* +** Find the first character of the line "nLines" forward from "startPos" +** in "buf" and return its position +*/ +int Fl_Text_Buffer::skip_lines( int startPos, int nLines ) { + int pos, gapLen = mGapEnd - mGapStart; + int lineCount = 0; + + if ( nLines == 0 ) + return startPos; + + pos = startPos; + while ( pos < mGapStart ) { + if ( mBuf[ pos++ ] == '\n' ) { + lineCount++; + if ( lineCount == nLines ) + return pos; + } + } + while ( pos < mLength ) { + if ( mBuf[ pos++ + gapLen ] == '\n' ) { + lineCount++; + if ( lineCount >= nLines ) + return pos; + } + } + return pos; +} + +/* +** Find the position of the first character of the line "nLines" backwards +** from "startPos" (not counting the character pointed to by "startpos" if +** that is a newline) in "buf". nLines == 0 means find the beginning of +** the line +*/ +int Fl_Text_Buffer::rewind_lines( int startPos, int nLines ) { + int pos, gapLen = mGapEnd - mGapStart; + int lineCount = -1; + + pos = startPos - 1; + if ( pos <= 0 ) + return 0; + + while ( pos >= mGapStart ) { + if ( mBuf[ pos + gapLen ] == '\n' ) { + if ( ++lineCount >= nLines ) + return pos + 1; + } + pos--; + } + while ( pos >= 0 ) { + if ( mBuf[ pos ] == '\n' ) { + if ( ++lineCount >= nLines ) + return pos + 1; + } + pos--; + } + return 0; +} + +/* +** Search forwards in buffer for string "searchString", starting with the +** character "startPos", and returning the result in "foundPos" +** returns 1 if found, 0 if not. +*/ +int Fl_Text_Buffer::search_forward( int startPos, const char *searchString, + int *foundPos, int matchCase ) +{ + if (!searchString) return 0; + int bp; + const char* sp; + while (startPos < length()) { + bp = startPos; + sp = searchString; + do { + if (!*sp) { *foundPos = startPos; return 1; } + } while ((matchCase ? character(bp++) == *sp++ : + toupper(character(bp++)) == toupper(*sp++)) + && bp < length()); + startPos++; + } + return 0; +} + +/* +** Search backwards in buffer for string "searchString", starting with the +** character BEFORE "startPos", returning the result in "foundPos" +** returns 1 if found, 0 if not. +*/ +int Fl_Text_Buffer::search_backward( int startPos, const char *searchString, + int *foundPos, int matchCase ) +{ + if (!searchString) return 0; + int bp; + const char* sp; + while (startPos > 0) { + bp = startPos-1; + sp = searchString+strlen(searchString)-1; + do { + if (sp < searchString) { *foundPos = bp+1; return 1; } + } while ((matchCase ? character(bp--) == *sp-- : + toupper(character(bp--)) == toupper(*sp--)) + && bp >= 0); + startPos--; + } + return 0; +} + +/* +** Search forwards in buffer for characters in "searchChars", starting +** with the character "startPos", and returning the result in "foundPos" +** returns 1 if found, 0 if not. +*/ +int Fl_Text_Buffer::findchars_forward( int startPos, const char *searchChars, + int *foundPos ) { + int pos, gapLen = mGapEnd - mGapStart; + const char *c; + + pos = startPos; + while ( pos < mGapStart ) { + for ( c = searchChars; *c != '\0'; c++ ) { + if ( mBuf[ pos ] == *c ) { + *foundPos = pos; + return 1; + } + } + pos++; + } + while ( pos < mLength ) { + for ( c = searchChars; *c != '\0'; c++ ) { + if ( mBuf[ pos + gapLen ] == *c ) { + *foundPos = pos; + return 1; + } + } + pos++; + } + *foundPos = mLength; + return 0; +} + +/* +** Search backwards in buffer for characters in "searchChars", starting +** with the character BEFORE "startPos", returning the result in "foundPos" +** returns 1 if found, 0 if not. +*/ +int Fl_Text_Buffer::findchars_backward( int startPos, const char *searchChars, + int *foundPos ) { + int pos, gapLen = mGapEnd - mGapStart; + const char *c; + + if ( startPos == 0 ) { + *foundPos = 0; + return 0; + } + pos = startPos == 0 ? 0 : startPos - 1; + while ( pos >= mGapStart ) { + for ( c = searchChars; *c != '\0'; c++ ) { + if ( mBuf[ pos + gapLen ] == *c ) { + *foundPos = pos; + return 1; + } + } + pos--; + } + while ( pos >= 0 ) { + for ( c = searchChars; *c != '\0'; c++ ) { + if ( mBuf[ pos ] == *c ) { + *foundPos = pos; + return 1; + } + } + pos--; + } + *foundPos = 0; + return 0; +} + +/* +** A horrible design flaw in NEdit (from the very start, before we knew that +** NEdit would become so popular), is that it uses C NULL terminated strings +** to hold text. This means editing text containing NUL characters is not +** possible without special consideration. Here is the special consideration. +** The routines below maintain a special substitution-character which stands +** in for a null, and translates strings an buffers back and forth from/to +** the substituted form, figure out what to substitute, and figure out +** when we're in over our heads and no translation is possible. +*/ + +/* +** The primary routine for integrating new text into a text buffer with +** substitution of another character for ascii nuls. This substitutes null +** characters in the string in preparation for being copied or replaced +** into the buffer, and if neccessary, adjusts the buffer as well, in the +** event that the string contains the character it is currently using for +** substitution. Returns 0, if substitution is no longer possible +** because all non-printable characters are already in use. +*/ +int Fl_Text_Buffer::substitute_null_characters( char *string, int len ) { + char histogram[ 256 ]; + + /* Find out what characters the string contains */ + histogramCharacters( string, len, histogram, 1 ); + + /* Does the string contain the null-substitute character? If so, re- + histogram the buffer text to find a character which is ok in both the + string and the buffer, and change the buffer's null-substitution + character. If none can be found, give up and return 0 */ + if ( histogram[ ( unsigned char ) mNullSubsChar ] != 0 ) { + char * bufString; + char newSubsChar; + bufString = (char*)text(); + histogramCharacters( bufString, mLength, histogram, 0 ); + newSubsChar = chooseNullSubsChar( histogram ); + if ( newSubsChar == '\0' ) + return 0; + subsChars( bufString, mLength, mNullSubsChar, newSubsChar ); + remove_( 0, mLength ); + insert_( 0, bufString ); + free( (void *) bufString ); + mNullSubsChar = newSubsChar; + } + + /* If the string contains null characters, substitute them with the + buffer's null substitution character */ + if ( histogram[ 0 ] != 0 ) + subsChars( string, len, '\0', mNullSubsChar ); + return 1; +} + +/* +** Convert strings obtained from buffers which contain null characters, which +** have been substituted for by a special substitution character, back to +** a null-containing string. There is no time penalty for calling this +** routine if no substitution has been done. +*/ +void Fl_Text_Buffer::unsubstitute_null_characters( char *string ) { + register char * c, subsChar = mNullSubsChar; + + if ( subsChar == '\0' ) + return; + for ( c = string; *c != '\0'; c++ ) + if ( *c == subsChar ) + * c = '\0'; +} + +/* +** Create a pseudo-histogram of the characters in a string (don't actually +** count, because we don't want overflow, just mark the character's presence +** with a 1). If init is true, initialize the histogram before acumulating. +** if not, add the new data to an existing histogram. +*/ +static void histogramCharacters( const char *string, int length, char hist[ 256 ], + int init ) { + int i; + const char *c; + + if ( init ) + for ( i = 0; i < 256; i++ ) + hist[ i ] = 0; + for ( c = string; c < &string[ length ]; c++ ) + hist[ *( ( unsigned char * ) c ) ] |= 1; +} + +/* +** Substitute fromChar with toChar in string. +*/ +static void subsChars( char *string, int length, char fromChar, char toChar ) { + char * c; + + for ( c = string; c < &string[ length ]; c++ ) + if ( *c == fromChar ) * c = toChar; +} + +/* +** Search through ascii control characters in histogram in order of least +** likelihood of use, find an unused character to use as a stand-in for a +** null. If the character set is full (no available characters outside of +** the printable set, return the null character. +*/ +static char chooseNullSubsChar( char hist[ 256 ] ) { +#define N_REPLACEMENTS 25 + static char replacements[ N_REPLACEMENTS ] = {1, 2, 3, 4, 5, 6, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 28, 29, 30, 31, 11, 7}; + int i; + for ( i = 0; i < N_REPLACEMENTS; i++ ) + if ( hist[ replacements[ i ] ] == 0 ) + return replacements[ i ]; + return '\0'; +} + +/* +** Internal (non-redisplaying) version of BufInsert. Returns the length of +** text inserted (this is just strlen(text), however this calculation can be +** expensive and the length will be required by any caller who will continue +** on to call redisplay). pos must be contiguous with the existing text in +** the buffer (i.e. not past the end). +*/ +int Fl_Text_Buffer::insert_( int pos, const char *s ) { + int insertedLength = strlen( s ); + + /* Prepare the buffer to receive the new text. If the new text fits in + the current buffer, just move the gap (if necessary) to where + the text should be inserted. If the new text is too large, reallocate + the buffer with a gap large enough to accomodate the new text and a + gap of PREFERRED_GAP_SIZE */ + if ( insertedLength > mGapEnd - mGapStart ) + reallocate_with_gap( pos, insertedLength + PREFERRED_GAP_SIZE ); + else if ( pos != mGapStart ) + move_gap( pos ); + + /* Insert the new text (pos now corresponds to the start of the gap) */ + memcpy( &mBuf[ pos ], s, insertedLength ); + mGapStart += insertedLength; + mLength += insertedLength; + update_selections( pos, 0, insertedLength ); + + if (mCanUndo) { + if ( undowidget==this && undoat==pos && undoinsert ) { + undoinsert += insertedLength; + } + else { + undoinsert = insertedLength; + undoyankcut = (undoat==pos) ? undocut : 0 ; + } + undoat = pos+insertedLength; + undocut = 0; + undowidget = this; + } + + return insertedLength; +} + +/* +** Internal (non-redisplaying) version of BufRemove. Removes the contents +** of the buffer between start and end (and moves the gap to the site of +** the delete). +*/ +void Fl_Text_Buffer::remove_( int start, int end ) { + /* if the gap is not contiguous to the area to remove, move it there */ + + if (mCanUndo) { + if ( undowidget==this && undoat==end && undocut ) { + undobuffersize( undocut+end-start+1 ); + memmove( undobuffer+end-start, undobuffer, undocut ); + undocut += end-start; + } + else { + undocut = end-start; + undobuffersize(undocut); + } + undoat = start; + undoinsert = 0; + undoyankcut = 0; + undowidget = this; + } + + if ( start > mGapStart ) { + if (mCanUndo) + memcpy( undobuffer, mBuf+(mGapEnd-mGapStart)+start, end-start ); + move_gap( start ); + } + else if ( end < mGapStart ) { + if (mCanUndo) + memcpy( undobuffer, mBuf+start, end-start ); + move_gap( end ); + } + else { + int prelen = mGapStart - start; + if (mCanUndo) { + memcpy( undobuffer, mBuf+start, prelen ); + memcpy( undobuffer+prelen, mBuf+mGapEnd, end-start-prelen); + } + } + + /* expand the gap to encompass the deleted characters */ + mGapEnd += end - mGapStart; + mGapStart -= mGapStart - start; + + /* update the length */ + mLength -= end - start; + + /* fix up any selections which might be affected by the change */ + update_selections( start, end - start, 0 ); +} + +/* +** Insert a column of text without calling the modify callbacks. Note that +** in some pathological cases, inserting can actually decrease the size of +** the buffer because of spaces being coalesced into tabs. "nDeleted" and +** "nInserted" return the number of characters deleted and inserted beginning +** at the start of the line containing "startPos". "endPos" returns buffer +** position of the lower left edge of the inserted column (as a hint for +** routines which need to set a cursor position). +*/ +void Fl_Text_Buffer::insert_column_( int column, int startPos, const char *insText, + int *nDeleted, int *nInserted, int *endPos ) { + int nLines, start, end, insWidth, lineStart, lineEnd; + int expReplLen, expInsLen, len, endOffset; + char *c, *outStr, *outPtr, *expText, *insLine; + const char *line; + const char *replText; + const char *insPtr; + + if ( column < 0 ) + column = 0; + + /* Allocate a buffer for the replacement string large enough to hold + possibly expanded tabs in both the inserted text and the replaced + area, as well as per line: 1) an additional 2*FL_TEXT_MAX_EXP_CHAR_LEN + characters for padding where tabs and control characters cross the + column of the selection, 2) up to "column" additional spaces per + line for padding out to the position of "column", 3) padding up + to the width of the inserted text if that must be padded to align + the text beyond the inserted column. (Space for additional + newlines if the inserted text extends beyond the end of the buffer + is counted with the length of insText) */ + start = line_start( startPos ); + nLines = countLines( insText ) + 1; + insWidth = textWidth( insText, mTabDist, mNullSubsChar ); + end = line_end( skip_lines( start, nLines - 1 ) ); + replText = text_range( start, end ); + expText = expandTabs( replText, 0, mTabDist, mNullSubsChar, + &expReplLen ); + free( (void *) replText ); + free( (void *) expText ); + expText = expandTabs( insText, 0, mTabDist, mNullSubsChar, + &expInsLen ); + free( (void *) expText ); + outStr = (char *)malloc( expReplLen + expInsLen + + nLines * ( column + insWidth + FL_TEXT_MAX_EXP_CHAR_LEN ) + 1 ); + + /* Loop over all lines in the buffer between start and end removing the + text between rectStart and rectEnd and padding appropriately. Trim + trailing space from line (whitespace at the ends of lines otherwise + tends to multiply, since additional padding is added to maintain it */ + outPtr = outStr; + lineStart = start; + insPtr = insText; + for (;;) { + lineEnd = line_end( lineStart ); + line = text_range( lineStart, lineEnd ); + insLine = copyLine( insPtr, &len ); + insPtr += len; + insertColInLine( line, insLine, column, insWidth, mTabDist, + mUseTabs, mNullSubsChar, outPtr, &len, &endOffset ); + free( (void *) line ); + free( (void *) insLine ); + for ( c = outPtr + len - 1; c > outPtr && isspace( *c ); c-- ) + len--; + outPtr += len; + *outPtr++ = '\n'; + lineStart = lineEnd < mLength ? lineEnd + 1 : mLength; + if ( *insPtr == '\0' ) + break; + insPtr++; + } + if ( outPtr != outStr ) + outPtr--; /* trim back off extra newline */ + *outPtr = '\0'; + + /* replace the text between start and end with the new stuff */ + remove_( start, end ); + insert_( start, outStr ); + *nInserted = outPtr - outStr; + *nDeleted = end - start; + *endPos = start + ( outPtr - outStr ) - len + endOffset; + free( (void *) outStr ); +} + +/* +** Delete a rectangle of text without calling the modify callbacks. Returns +** the number of characters replacing those between start and end. Note that +** in some pathological cases, deleting can actually increase the size of +** the buffer because of tab expansions. "endPos" returns the buffer position +** of the point in the last line where the text was removed (as a hint for +** routines which need to position the cursor after a delete operation) +*/ +void Fl_Text_Buffer::remove_rectangular_( int start, int end, int rectStart, + int rectEnd, int *replaceLen, int *endPos ) { + int nLines, lineStart, lineEnd, len, endOffset; + char *outStr, *outPtr, *expText; + const char *s, *line; + + /* allocate a buffer for the replacement string large enough to hold + possibly expanded tabs as well as an additional FL_TEXT_MAX_EXP_CHAR_LEN * 2 + characters per line for padding where tabs and control characters cross + the edges of the selection */ + start = line_start( start ); + end = line_end( end ); + nLines = count_lines( start, end ) + 1; + s = text_range( start, end ); + expText = expandTabs( s, 0, mTabDist, mNullSubsChar, &len ); + free( (void *) s ); + free( (void *) expText ); + outStr = (char *)malloc( len + nLines * FL_TEXT_MAX_EXP_CHAR_LEN * 2 + 1 ); + + /* loop over all lines in the buffer between start and end removing + the text between rectStart and rectEnd and padding appropriately */ + lineStart = start; + outPtr = outStr; + endOffset = 0; + while ( lineStart <= mLength && lineStart <= end ) { + lineEnd = line_end( lineStart ); + line = text_range( lineStart, lineEnd ); + deleteRectFromLine( line, rectStart, rectEnd, mTabDist, + mUseTabs, mNullSubsChar, outPtr, &len, &endOffset ); + free( (void *) line ); + outPtr += len; + *outPtr++ = '\n'; + lineStart = lineEnd + 1; + } + if ( outPtr != outStr ) + outPtr--; /* trim back off extra newline */ + *outPtr = '\0'; + + /* replace the text between start and end with the newly created string */ + remove_( start, end ); + insert_( start, outStr ); + *replaceLen = outPtr - outStr; + *endPos = start + ( outPtr - outStr ) - len + endOffset; + free( (void *) outStr ); +} + +/* +** Overlay a rectangular area of text without calling the modify callbacks. +** "nDeleted" and "nInserted" return the number of characters deleted and +** inserted beginning at the start of the line containing "startPos". +** "endPos" returns buffer position of the lower left edge of the inserted +** column (as a hint for routines which need to set a cursor position). +*/ +void Fl_Text_Buffer::overlay_rectangular_(int startPos, int rectStart, + int rectEnd, const char *insText, + int *nDeleted, int *nInserted, + int *endPos ) { + int nLines, start, end, lineStart, lineEnd; + int expInsLen, len, endOffset; + char *c, *outStr, *outPtr, *expText, *insLine; + const char *line; + const char *insPtr; + + /* Allocate a buffer for the replacement string large enough to hold + possibly expanded tabs in the inserted text, as well as per line: 1) + an additional 2*FL_TEXT_MAX_EXP_CHAR_LEN characters for padding where tabs + and control characters cross the column of the selection, 2) up to + "column" additional spaces per line for padding out to the position + of "column", 3) padding up to the width of the inserted text if that + must be padded to align the text beyond the inserted column. (Space + for additional newlines if the inserted text extends beyond the end + of the buffer is counted with the length of insText) */ + start = line_start( startPos ); + nLines = countLines( insText ) + 1; + end = line_end( skip_lines( start, nLines - 1 ) ); + expText = expandTabs( insText, 0, mTabDist, mNullSubsChar, + &expInsLen ); + free( (void *) expText ); + outStr = (char *)malloc( end - start + expInsLen + + nLines * ( rectEnd + FL_TEXT_MAX_EXP_CHAR_LEN ) + 1 ); + + /* Loop over all lines in the buffer between start and end overlaying the + text between rectStart and rectEnd and padding appropriately. Trim + trailing space from line (whitespace at the ends of lines otherwise + tends to multiply, since additional padding is added to maintain it */ + outPtr = outStr; + lineStart = start; + insPtr = insText; + for (;;) { + lineEnd = line_end( lineStart ); + line = text_range( lineStart, lineEnd ); + insLine = copyLine( insPtr, &len ); + insPtr += len; + overlayRectInLine( line, insLine, rectStart, rectEnd, mTabDist, + mUseTabs, mNullSubsChar, outPtr, &len, &endOffset ); + free( (void *) line ); + free( (void *) insLine ); + for ( c = outPtr + len - 1; c > outPtr && isspace( *c ); c-- ) + len--; + outPtr += len; + *outPtr++ = '\n'; + lineStart = lineEnd < mLength ? lineEnd + 1 : mLength; + if ( *insPtr == '\0' ) + break; + insPtr++; + } + if ( outPtr != outStr ) + outPtr--; /* trim back off extra newline */ + *outPtr = '\0'; + + /* replace the text between start and end with the new stuff */ + remove_( start, end ); + insert_( start, outStr ); + *nInserted = outPtr - outStr; + *nDeleted = end - start; + *endPos = start + ( outPtr - outStr ) - len + endOffset; + free( (void *) outStr ); +} + +/* +** Insert characters from single-line string "insLine" in single-line string +** "line" at "column", leaving "insWidth" space before continuing line. +** "outLen" returns the number of characters written to "outStr", "endOffset" +** returns the number of characters from the beginning of the string to +** the right edge of the inserted text (as a hint for routines which need +** to position the cursor). +*/ +static void insertColInLine( const char *line, char *insLine, int column, int insWidth, + int tabDist, int useTabs, char nullSubsChar, char *outStr, int *outLen, + int *endOffset ) { + char * c, *outPtr, *retabbedStr; + const char *linePtr; + int indent, toIndent, len, postColIndent; + + /* copy the line up to "column" */ + outPtr = outStr; + indent = 0; + for ( linePtr = line; *linePtr != '\0'; linePtr++ ) { + len = Fl_Text_Buffer::character_width( *linePtr, indent, tabDist, nullSubsChar ); + if ( indent + len > column ) + break; + indent += len; + *outPtr++ = *linePtr; + } + + /* If "column" falls in the middle of a character, and the character is a + tab, leave it off and leave the indent short and it will get padded + later. If it's a control character, insert it and adjust indent + accordingly. */ + if ( indent < column && *linePtr != '\0' ) { + postColIndent = indent + len; + if ( *linePtr == '\t' ) + linePtr++; + else { + *outPtr++ = *linePtr++; + indent += len; + } + } else + postColIndent = indent; + + /* If there's no text after the column and no text to insert, that's all */ + if ( *insLine == '\0' && *linePtr == '\0' ) { + *outLen = *endOffset = outPtr - outStr; + return; + } + + /* pad out to column if text is too short */ + if ( indent < column ) { + addPadding( outPtr, indent, column, tabDist, useTabs, nullSubsChar, &len ); + outPtr += len; + indent = column; + } + + /* Copy the text from "insLine" (if any), recalculating the tabs as if + the inserted string began at column 0 to its new column destination */ + if ( *insLine != '\0' ) { + retabbedStr = realignTabs( insLine, 0, indent, tabDist, useTabs, + nullSubsChar, &len ); + for ( c = retabbedStr; *c != '\0'; c++ ) { + *outPtr++ = *c; + len = Fl_Text_Buffer::character_width( *c, indent, tabDist, nullSubsChar ); + indent += len; + } + free( (void *) retabbedStr ); + } + + /* If the original line did not extend past "column", that's all */ + if ( *linePtr == '\0' ) { + *outLen = *endOffset = outPtr - outStr; + return; + } + + /* Pad out to column + width of inserted text + (additional original + offset due to non-breaking character at column) */ + toIndent = column + insWidth + postColIndent - column; + addPadding( outPtr, indent, toIndent, tabDist, useTabs, nullSubsChar, &len ); + outPtr += len; + indent = toIndent; + + /* realign tabs for text beyond "column" and write it out */ + retabbedStr = realignTabs( linePtr, postColIndent, indent, tabDist, + useTabs, nullSubsChar, &len ); + strcpy( outPtr, retabbedStr ); + free( (void *) retabbedStr ); + *endOffset = outPtr - outStr; + *outLen = ( outPtr - outStr ) + len; +} + +/* +** Remove characters in single-line string "line" between displayed positions +** "rectStart" and "rectEnd", and write the result to "outStr", which is +** assumed to be large enough to hold the returned string. Note that in +** certain cases, it is possible for the string to get longer due to +** expansion of tabs. "endOffset" returns the number of characters from +** the beginning of the string to the point where the characters were +** deleted (as a hint for routines which need to position the cursor). +*/ +static void deleteRectFromLine( const char *line, int rectStart, int rectEnd, + int tabDist, int useTabs, char nullSubsChar, char *outStr, int *outLen, + int *endOffset ) { + int indent, preRectIndent, postRectIndent, len; + const char *c; + char *retabbedStr, *outPtr; + + /* copy the line up to rectStart */ + outPtr = outStr; + indent = 0; + for ( c = line; *c != '\0'; c++ ) { + if ( indent > rectStart ) + break; + len = Fl_Text_Buffer::character_width( *c, indent, tabDist, nullSubsChar ); + if ( indent + len > rectStart && ( indent == rectStart || *c == '\t' ) ) + break; + indent += len; + *outPtr++ = *c; + } + preRectIndent = indent; + + /* skip the characters between rectStart and rectEnd */ + for ( ; *c != '\0' && indent < rectEnd; c++ ) + indent += Fl_Text_Buffer::character_width( *c, indent, tabDist, nullSubsChar ); + postRectIndent = indent; + + /* If the line ended before rectEnd, there's nothing more to do */ + if ( *c == '\0' ) { + *outPtr = '\0'; + *outLen = *endOffset = outPtr - outStr; + return; + } + + /* fill in any space left by removed tabs or control characters + which straddled the boundaries */ + indent = max( rectStart + postRectIndent - rectEnd, preRectIndent ); + addPadding( outPtr, preRectIndent, indent, tabDist, useTabs, nullSubsChar, + &len ); + outPtr += len; + + /* Copy the rest of the line. If the indentation has changed, preserve + the position of non-whitespace characters by converting tabs to + spaces, then back to tabs with the correct offset */ + retabbedStr = realignTabs( c, postRectIndent, indent, tabDist, useTabs, + nullSubsChar, &len ); + strcpy( outPtr, retabbedStr ); + free( (void *) retabbedStr ); + *endOffset = outPtr - outStr; + *outLen = ( outPtr - outStr ) + len; +} + +/* +** Overlay characters from single-line string "insLine" on single-line string +** "line" between displayed character offsets "rectStart" and "rectEnd". +** "outLen" returns the number of characters written to "outStr", "endOffset" +** returns the number of characters from the beginning of the string to +** the right edge of the inserted text (as a hint for routines which need +** to position the cursor). +*/ +static void overlayRectInLine( const char *line, char *insLine, int rectStart, + int rectEnd, int tabDist, int useTabs, char nullSubsChar, char *outStr, + int *outLen, int *endOffset ) { + char * c, *outPtr, *retabbedStr; + int inIndent, outIndent, len, postRectIndent; + const char *linePtr; + + /* copy the line up to "rectStart" */ + outPtr = outStr; + inIndent = outIndent = 0; + for ( linePtr = line; *linePtr != '\0'; linePtr++ ) { + len = Fl_Text_Buffer::character_width( *linePtr, inIndent, tabDist, nullSubsChar ); + if ( inIndent + len > rectStart ) + break; + inIndent += len; + outIndent += len; + *outPtr++ = *linePtr; + } + + /* If "rectStart" falls in the middle of a character, and the character + is a tab, leave it off and leave the outIndent short and it will get + padded later. If it's a control character, insert it and adjust + outIndent accordingly. */ + if ( inIndent < rectStart && *linePtr != '\0' ) { + if ( *linePtr == '\t' ) { + linePtr++; + inIndent += len; + } else { + *outPtr++ = *linePtr++; + outIndent += len; + inIndent += len; + } + } + + /* skip the characters between rectStart and rectEnd */ + postRectIndent = rectEnd; + for ( ; *linePtr != '\0'; linePtr++ ) { + inIndent += Fl_Text_Buffer::character_width( *linePtr, inIndent, tabDist, nullSubsChar ); + if ( inIndent >= rectEnd ) { + linePtr++; + postRectIndent = inIndent; + break; + } + } + + /* If there's no text after rectStart and no text to insert, that's all */ + if ( *insLine == '\0' && *linePtr == '\0' ) { + *outLen = *endOffset = outPtr - outStr; + return; + } + + /* pad out to rectStart if text is too short */ + if ( outIndent < rectStart ) { + addPadding( outPtr, outIndent, rectStart, tabDist, useTabs, nullSubsChar, + &len ); + outPtr += len; + } + outIndent = rectStart; + + /* Copy the text from "insLine" (if any), recalculating the tabs as if + the inserted string began at column 0 to its new column destination */ + if ( *insLine != '\0' ) { + retabbedStr = realignTabs( insLine, 0, rectStart, tabDist, useTabs, + nullSubsChar, &len ); + for ( c = retabbedStr; *c != '\0'; c++ ) { + *outPtr++ = *c; + len = Fl_Text_Buffer::character_width( *c, outIndent, tabDist, nullSubsChar ); + outIndent += len; + } + free( (void *) retabbedStr ); + } + + /* If the original line did not extend past "rectStart", that's all */ + if ( *linePtr == '\0' ) { + *outLen = *endOffset = outPtr - outStr; + return; + } + + /* Pad out to rectEnd + (additional original offset + due to non-breaking character at right boundary) */ + addPadding( outPtr, outIndent, postRectIndent, tabDist, useTabs, + nullSubsChar, &len ); + outPtr += len; + outIndent = postRectIndent; + + /* copy the text beyond "rectEnd" */ + strcpy( outPtr, linePtr ); + *endOffset = outPtr - outStr; + *outLen = ( outPtr - outStr ) + strlen( linePtr ); +} + +void Fl_Text_Selection::set( int startpos, int endpos ) { + mSelected = startpos != endpos; + mRectangular = 0; + mStart = min( startpos, endpos ); + mEnd = max( startpos, endpos ); +} + +void Fl_Text_Selection::set_rectangular( int startpos, int endpos, + int rectStart, int rectEnd ) { + mSelected = rectStart < rectEnd; + mRectangular = 1; + mStart = startpos; + mEnd = endpos; + mRectStart = rectStart; + mRectEnd = rectEnd; +} + +int Fl_Text_Selection::position( int *startpos, int *endpos ) { + if ( !mSelected ) + return 0; + *startpos = mStart; + *endpos = mEnd; + + return 1; +} + +int Fl_Text_Selection::position( int *startpos, int *endpos, + int *isRect, int *rectStart, int *rectEnd ) { + if ( !mSelected ) + return 0; + *isRect = mRectangular; + *startpos = mStart; + *endpos = mEnd; + if ( mRectangular ) { + *rectStart = mRectStart; + *rectEnd = mRectEnd; + } + return 1; +} + +/* +** Return true if position "pos" with indentation "dispIndex" is in +** the Fl_Text_Selection. +*/ +int Fl_Text_Selection::includes(int pos, int lineStartPos, int dispIndex) { + return selected() && + ( (!rectangular() && pos >= start() && pos < end()) || + (rectangular() && pos >= start() && lineStartPos <= end() && + dispIndex >= rect_start() && dispIndex < rect_end()) + ); +} + + + +char * Fl_Text_Buffer::selection_text_( Fl_Text_Selection *sel ) { + int start, end, isRect, rectStart, rectEnd; + char *s; + + /* If there's no selection, return an allocated empty string */ + if ( !sel->position( &start, &end, &isRect, &rectStart, &rectEnd ) ) { + s = (char *)malloc( 1 ); + *s = '\0'; + return s; + } + + /* If the selection is not rectangular, return the selected range */ + if ( isRect ) + return text_in_rectangle( start, end, rectStart, rectEnd ); + else + return text_range( start, end ); +} + +void Fl_Text_Buffer::remove_selection_( Fl_Text_Selection *sel ) { + int start, end; + int isRect, rectStart, rectEnd; + + if ( !sel->position( &start, &end, &isRect, &rectStart, &rectEnd ) ) + return; + if ( isRect ) + remove_rectangular( start, end, rectStart, rectEnd ); + else { + remove( start, end ); + //undoyankcut = undocut; + } +} + +void Fl_Text_Buffer::replace_selection_( Fl_Text_Selection *sel, const char *s ) { + int start, end, isRect, rectStart, rectEnd; + Fl_Text_Selection oldSelection = *sel; + + /* If there's no selection, return */ + if ( !sel->position( &start, &end, &isRect, &rectStart, &rectEnd ) ) + return; + + /* Do the appropriate type of replace */ + if ( isRect ) + replace_rectangular( start, end, rectStart, rectEnd, s ); + else + replace( start, end, s ); + + /* Unselect (happens automatically in BufReplace, but BufReplaceRect + can't detect when the contents of a selection goes away) */ + sel->mSelected = 0; + redisplay_selection( &oldSelection, sel ); +} + +static void addPadding( char *string, int startIndent, int toIndent, + int tabDist, int useTabs, char nullSubsChar, int *charsAdded ) { + char * outPtr; + int len, indent; + + indent = startIndent; + outPtr = string; + if ( useTabs ) { + while ( indent < toIndent ) { + len = Fl_Text_Buffer::character_width( '\t', indent, tabDist, nullSubsChar ); + if ( len > 1 && indent + len <= toIndent ) { + *outPtr++ = '\t'; + indent += len; + } else { + *outPtr++ = ' '; + indent++; + } + } + } else { + while ( indent < toIndent ) { + *outPtr++ = ' '; + indent++; + } + } + *charsAdded = outPtr - string; +} + +/* +** Call the stored modify callback procedure(s) for this buffer to update the +** changed area(s) on the screen and any other listeners. +*/ +void Fl_Text_Buffer::call_modify_callbacks( int pos, int nDeleted, + int nInserted, int nRestyled, const char *deletedText ) { + int i; + + for ( i = 0; i < mNModifyProcs; i++ ) + ( *mNodifyProcs[ i ] ) ( pos, nInserted, nDeleted, nRestyled, + deletedText, mCbArgs[ i ] ); +} + +/* +** Call the stored pre-delete callback procedure(s) for this buffer to update +** the changed area(s) on the screen and any other listeners. +*/ +void Fl_Text_Buffer::call_predelete_callbacks(int pos, int nDeleted) { + int i; + + for (i=0; imStart; + newStart = newSelection->mStart; + oldEnd = oldSelection->mEnd; + newEnd = newSelection->mEnd; + if ( oldSelection->mRectangular ) + oldEnd++; + if ( newSelection->mRectangular ) + newEnd++; + + /* If the old or new selection is unselected, just redisplay the + single area that is (was) selected and return */ + if ( !oldSelection->mSelected && !newSelection->mSelected ) + return; + if ( !oldSelection->mSelected ) { + call_modify_callbacks( newStart, 0, 0, newEnd - newStart, NULL ); + return; + } + if ( !newSelection->mSelected ) { + call_modify_callbacks( oldStart, 0, 0, oldEnd - oldStart, NULL ); + return; + } + + /* If the selection changed from normal to rectangular or visa versa, or + if a rectangular selection changed boundaries, redisplay everything */ + if ( ( oldSelection->mRectangular && !newSelection->mRectangular ) || + ( !oldSelection->mRectangular && newSelection->mRectangular ) || + ( oldSelection->mRectangular && ( + ( oldSelection->mRectStart != newSelection->mRectStart ) || + ( oldSelection->mRectEnd != newSelection->mRectEnd ) ) ) ) { + call_modify_callbacks( min( oldStart, newStart ), 0, 0, + max( oldEnd, newEnd ) - min( oldStart, newStart ), NULL ); + return; + } + + /* If the selections are non-contiguous, do two separate updates + and return */ + if ( oldEnd < newStart || newEnd < oldStart ) { + call_modify_callbacks( oldStart, 0, 0, oldEnd - oldStart, NULL ); + call_modify_callbacks( newStart, 0, 0, newEnd - newStart, NULL ); + return; + } + + /* Otherwise, separate into 3 separate regions: ch1, and ch2 (the two + changed areas), and the unchanged area of their intersection, + and update only the changed area(s) */ + ch1Start = min( oldStart, newStart ); + ch2End = max( oldEnd, newEnd ); + ch1End = max( oldStart, newStart ); + ch2Start = min( oldEnd, newEnd ); + if ( ch1Start != ch1End ) + call_modify_callbacks( ch1Start, 0, 0, ch1End - ch1Start, NULL ); + if ( ch2Start != ch2End ) + call_modify_callbacks( ch2Start, 0, 0, ch2End - ch2Start, NULL ); +} + +void Fl_Text_Buffer::move_gap( int pos ) { + int gapLen = mGapEnd - mGapStart; + + if ( pos > mGapStart ) + memmove( &mBuf[ mGapStart ], &mBuf[ mGapEnd ], + pos - mGapStart ); + else + memmove( &mBuf[ pos + gapLen ], &mBuf[ pos ], mGapStart - pos ); + mGapEnd += pos - mGapStart; + mGapStart += pos - mGapStart; +} + +/* +** reallocate the text storage in "buf" to have a gap starting at "newGapStart" +** and a gap size of "newGapLen", preserving the buffer's current contents. +*/ +void Fl_Text_Buffer::reallocate_with_gap( int newGapStart, int newGapLen ) { + char * newBuf; + int newGapEnd; + + newBuf = (char *)malloc( mLength + newGapLen ); + newGapEnd = newGapStart + newGapLen; + if ( newGapStart <= mGapStart ) { + memcpy( newBuf, mBuf, newGapStart ); + memcpy( &newBuf[ newGapEnd ], &mBuf[ newGapStart ], + mGapStart - newGapStart ); + memcpy( &newBuf[ newGapEnd + mGapStart - newGapStart ], + &mBuf[ mGapEnd ], mLength - mGapStart ); + } else { /* newGapStart > mGapStart */ + memcpy( newBuf, mBuf, mGapStart ); + memcpy( &newBuf[ mGapStart ], &mBuf[ mGapEnd ], + newGapStart - mGapStart ); + memcpy( &newBuf[ newGapEnd ], + &mBuf[ mGapEnd + newGapStart - mGapStart ], + mLength - newGapStart ); + } + free( (void *) mBuf ); + mBuf = newBuf; + mGapStart = newGapStart; + mGapEnd = newGapEnd; +#ifdef PURIFY +{int i; for ( i = mGapStart; i < mGapEnd; i++ ) mBuf[ i ] = '.'; } +#endif +} + +/* +** Update all of the selections in "buf" for changes in the buffer's text +*/ +void Fl_Text_Buffer::update_selections( int pos, int nDeleted, + int nInserted ) { + mPrimary.update( pos, nDeleted, nInserted ); + mSecondary.update( pos, nDeleted, nInserted ); + mHighlight.update( pos, nDeleted, nInserted ); +} + +/* +** Update an individual selection for changes in the corresponding text +*/ +void Fl_Text_Selection::update( int pos, int nDeleted, + int nInserted ) { + if ( !mSelected || pos > mEnd ) + return; + if ( pos + nDeleted <= mStart ) { + mStart += nInserted - nDeleted; + mEnd += nInserted - nDeleted; + } else if ( pos <= mStart && pos + nDeleted >= mEnd ) { + mStart = pos; + mEnd = pos; + mSelected = 0; + } else if ( pos <= mStart && pos + nDeleted < mEnd ) { + mStart = pos; + mEnd = nInserted + mEnd - nDeleted; + } else if ( pos < mEnd ) { + mEnd += nInserted - nDeleted; + if ( mEnd <= mStart ) + mSelected = 0; + } +} + +/* +** Search forwards in buffer "buf" for character "searchChar", starting +** with the character "startPos", and returning the result in "foundPos" +** returns 1 if found, 0 if not. (The difference between this and +** BufSearchForward is that it's optimized for single characters. The +** overall performance of the text widget is dependent on its ability to +** count lines quickly, hence searching for a single character: newline) +*/ +int Fl_Text_Buffer::findchar_forward( int startPos, char searchChar, + int *foundPos ) { + int pos, gapLen = mGapEnd - mGapStart; + + if (startPos < 0 || startPos >= mLength) { + *foundPos = mLength; + return 0; + } + + pos = startPos; + while ( pos < mGapStart ) { + if ( mBuf[ pos ] == searchChar ) { + *foundPos = pos; + return 1; + } + pos++; + } + while ( pos < mLength ) { + if ( mBuf[ pos + gapLen ] == searchChar ) { + *foundPos = pos; + return 1; + } + pos++; + } + *foundPos = mLength; + return 0; +} + +/* +** Search backwards in buffer "buf" for character "searchChar", starting +** with the character BEFORE "startPos", returning the result in "foundPos" +** returns 1 if found, 0 if not. (The difference between this and +** BufSearchBackward is that it's optimized for single characters. The +** overall performance of the text widget is dependent on its ability to +** count lines quickly, hence searching for a single character: newline) +*/ +int Fl_Text_Buffer::findchar_backward( int startPos, char searchChar, + int *foundPos ) { + int pos, gapLen = mGapEnd - mGapStart; + + if ( startPos <= 0 || startPos > mLength ) { + *foundPos = 0; + return 0; + } + pos = startPos - 1; + while ( pos >= mGapStart ) { + if ( mBuf[ pos + gapLen ] == searchChar ) { + *foundPos = pos; + return 1; + } + pos--; + } + while ( pos >= 0 ) { + if ( mBuf[ pos ] == searchChar ) { + *foundPos = pos; + return 1; + } + pos--; + } + *foundPos = 0; + return 0; +} + +/* +** Copy from "text" to end up to but not including newline (or end of "text") +** and return the copy as the function value, and the length of the line in +** "lineLen" +*/ +static char *copyLine( const char *text, int *lineLen ) { + int len = 0; + const char *c; + char *outStr; + + for ( c = text; *c != '\0' && *c != '\n'; c++ ) + len++; + outStr = (char *)malloc( len + 1 ); + strlcpy( outStr, text, len + 1); + *lineLen = len; + return outStr; +} + +/* +** Count the number of newlines in a null-terminated text string; +*/ +static int countLines( const char *string ) { + const char * c; + int lineCount = 0; + + for ( c = string; *c != '\0'; c++ ) + if ( *c == '\n' ) lineCount++; + return lineCount; +} + +/* +** Measure the width in displayed characters of string "text" +*/ +static int textWidth( const char *text, int tabDist, char nullSubsChar ) { + int width = 0, maxWidth = 0; + const char *c; + + for ( c = text; *c != '\0'; c++ ) { + if ( *c == '\n' ) { + if ( width > maxWidth ) + maxWidth = width; + width = 0; + } else + width += Fl_Text_Buffer::character_width( *c, width, tabDist, nullSubsChar ); + } + if ( width > maxWidth ) + return width; + return maxWidth; +} + +/* +** Find the first and last character position in a line within a rectangular +** selection (for copying). Includes tabs which cross rectStart, but not +** control characters which do so. Leaves off tabs which cross rectEnd. +** +** Technically, the calling routine should convert tab characters which +** cross the right boundary of the selection to spaces which line up with +** the edge of the selection. Unfortunately, the additional memory +** management required in the parent routine to allow for the changes +** in string size is not worth all the extra work just for a couple of +** shifted characters, so if a tab protrudes, just lop it off and hope +** that there are other characters in the selection to establish the right +** margin for subsequent columnar pastes of this data. +*/ +void Fl_Text_Buffer::rectangular_selection_boundaries( int lineStartPos, + int rectStart, int rectEnd, int *selStart, int *selEnd ) { + int pos, width, indent = 0; + char c; + + /* find the start of the selection */ + for ( pos = lineStartPos; pos < mLength; pos++ ) { + c = character( pos ); + if ( c == '\n' ) + break; + width = Fl_Text_Buffer::character_width( c, indent, mTabDist, mNullSubsChar ); + if ( indent + width > rectStart ) { + if ( indent != rectStart && c != '\t' ) { + pos++; + indent += width; + } + break; + } + indent += width; + } + *selStart = pos; + + /* find the end */ + for ( ; pos < mLength; pos++ ) { + c = character( pos ); + if ( c == '\n' ) + break; + width = Fl_Text_Buffer::character_width( c, indent, mTabDist, mNullSubsChar ); + indent += width; + if ( indent > rectEnd ) { + if ( indent - width != rectEnd && c != '\t' ) + pos++; + break; + } + } + *selEnd = pos; +} + +/* +** Adjust the space and tab characters from string "text" so that non-white +** characters remain stationary when the text is shifted from starting at +** "origIndent" to starting at "newIndent". Returns an allocated string +** which must be freed by the caller with XtFree. +*/ +static char *realignTabs( const char *text, int origIndent, int newIndent, + int tabDist, int useTabs, char nullSubsChar, int *newLength ) { + char * expStr, *outStr; + int len; + + /* If the tabs settings are the same, retain original tabs */ + if ( origIndent % tabDist == newIndent % tabDist ) { + len = strlen( text ); + outStr = (char *)malloc( len + 1 ); + strcpy( outStr, text ); + *newLength = len; + return outStr; + } + + /* If the tab settings are not the same, brutally convert tabs to + spaces, then back to tabs in the new position */ + expStr = expandTabs( text, origIndent, tabDist, nullSubsChar, &len ); + if ( !useTabs ) { + *newLength = len; + return expStr; + } + outStr = unexpandTabs( expStr, newIndent, tabDist, nullSubsChar, newLength ); + free( (void *) expStr ); + return outStr; +} + +/* +** Expand tabs to spaces for a block of text. The additional parameter +** "startIndent" if nonzero, indicates that the text is a rectangular selection +** beginning at column "startIndent" +*/ +static char *expandTabs( const char *text, int startIndent, int tabDist, + char nullSubsChar, int *newLen ) { + char * outStr, *outPtr; + const char *c; + int indent, len, outLen = 0; + + /* rehearse the expansion to figure out length for output string */ + indent = startIndent; + for ( c = text; *c != '\0'; c++ ) { + if ( *c == '\t' ) { + len = Fl_Text_Buffer::character_width( *c, indent, tabDist, nullSubsChar ); + outLen += len; + indent += len; + } else if ( *c == '\n' ) { + indent = startIndent; + outLen++; + } else { + indent += Fl_Text_Buffer::character_width( *c, indent, tabDist, nullSubsChar ); + outLen++; + } + } + + /* do the expansion */ + outStr = (char *)malloc( outLen + 1 ); + outPtr = outStr; + indent = startIndent; + for ( c = text; *c != '\0'; c++ ) { + if ( *c == '\t' ) { + len = Fl_Text_Buffer::expand_character( *c, indent, outPtr, tabDist, nullSubsChar ); + outPtr += len; + indent += len; + } else if ( *c == '\n' ) { + indent = startIndent; + *outPtr++ = *c; + } else { + indent += Fl_Text_Buffer::character_width( *c, indent, tabDist, nullSubsChar ); + *outPtr++ = *c; + } + } + outStr[ outLen ] = '\0'; + *newLen = outLen; + return outStr; +} + +/* +** Convert sequences of spaces into tabs. The threshold for conversion is +** when 3 or more spaces can be converted into a single tab, this avoids +** converting double spaces after a period withing a block of text. +*/ +static char *unexpandTabs( char *text, int startIndent, int tabDist, + char nullSubsChar, int *newLen ) { + char * outStr, *outPtr, *c, expandedChar[ FL_TEXT_MAX_EXP_CHAR_LEN ]; + int indent, len; + + outStr = (char *)malloc( strlen( text ) + 1 ); + outPtr = outStr; + indent = startIndent; + for ( c = text; *c != '\0'; ) { + if ( *c == ' ' ) { + len = Fl_Text_Buffer::expand_character( '\t', indent, expandedChar, tabDist, + nullSubsChar ); + if ( len >= 3 && !strncmp( c, expandedChar, len ) ) { + c += len; + *outPtr++ = '\t'; + indent += len; + } else { + *outPtr++ = *c++; + indent++; + } + } else if ( *c == '\n' ) { + indent = startIndent; + *outPtr++ = *c++; + } else { + *outPtr++ = *c++; + indent++; + } + } + *outPtr = '\0'; + *newLen = outPtr - outStr; + return outStr; +} + +static int max( int i1, int i2 ) { + return i1 >= i2 ? i1 : i2; +} + +static int min( int i1, int i2 ) { + return i1 <= i2 ? i1 : i2; +} + +int +Fl_Text_Buffer::insertfile(const char *file, int pos, int buflen) { + FILE *fp; int r; + if (!(fp = fopen(file, "r"))) return 1; + char *buffer = new char[buflen]; + for (; (r = fread(buffer, 1, buflen - 1, fp)) > 0; pos += r) { + buffer[r] = (char)0; + insert(pos, buffer); + } + + int e = ferror(fp) ? 2 : 0; + fclose(fp); + delete[] buffer; + return e; +} + +int +Fl_Text_Buffer::outputfile(const char *file, int start, int end, int buflen) { + FILE *fp; + if (!(fp = fopen(file, "w"))) return 1; + for (int n; (n = min(end - start, buflen)); start += n) { + const char *p = text_range(start, start + n); + int r = fwrite(p, 1, n, fp); + free((void *)p); + if (r != n) break; + } + + int e = ferror(fp) ? 2 : 0; + fclose(fp); + return e; +} + + +// +// End of "$Id: Fl_Text_Buffer.cxx 6011 2008-01-04 20:32:37Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Text_Display.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Text_Display.cxx new file mode 100644 index 000000000..3b2f7b4ac --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Text_Display.cxx @@ -0,0 +1,3272 @@ +// +// "$Id: Fl_Text_Display.cxx 6105 2008-04-21 21:03:22Z matt $" +// +// Copyright 2001-2006 by Bill Spitzak and others. +// Original code Copyright Mark Edel. Permission to distribute under +// the LGPL for the FLTK library granted by Mark Edel. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include "flstring.h" +#include +#include +#include +#include +#include +#include + +#undef min +#undef max + +// Text area margins. Left & right margins should be at least 3 so that +// there is some room for the overhanging parts of the cursor! +#define TOP_MARGIN 1 +#define BOTTOM_MARGIN 1 +#define LEFT_MARGIN 3 +#define RIGHT_MARGIN 3 + +#define NO_HINT -1 + +/* Masks for text drawing methods. These are or'd together to form an + integer which describes what drawing calls to use to draw a string */ +#define FILL_MASK 0x0100 +#define SECONDARY_MASK 0x0200 +#define PRIMARY_MASK 0x0400 +#define HIGHLIGHT_MASK 0x0800 +#define BG_ONLY_MASK 0x1000 +#define TEXT_ONLY_MASK 0x2000 +#define STYLE_LOOKUP_MASK 0xff + +/* Maximum displayable line length (how many characters will fit across the + widest window). This amount of memory is temporarily allocated from the + stack in the draw_vline() method for drawing strings */ +#define MAX_DISP_LINE_LEN 1000 + +static int max( int i1, int i2 ); +static int min( int i1, int i2 ); +static int countlines( const char *string ); + +/* The variables below are used in a timer event to allow smooth + scrolling of the text area when the pointer has left the area. */ +static int scroll_direction = 0; +static int scroll_amount = 0; +static int scroll_y = 0; +static int scroll_x = 0; + +// CET - FIXME +#define TMPFONTWIDTH 6 + +Fl_Text_Display::Fl_Text_Display(int X, int Y, int W, int H, const char* l) + : Fl_Group(X, Y, W, H, l) { + int i; + + mMaxsize = 0; + damage_range1_start = damage_range1_end = -1; + damage_range2_start = damage_range2_end = -1; + dragPos = dragType = dragging = 0; + display_insert_position_hint = 0; + + color(FL_BACKGROUND2_COLOR, FL_SELECTION_COLOR); + box(FL_DOWN_FRAME); + textsize((uchar)FL_NORMAL_SIZE); + textcolor(FL_FOREGROUND_COLOR); + textfont(FL_HELVETICA); + + text_area.x = 0; + text_area.y = 0; + text_area.w = 0; + text_area.h = 0; + + mVScrollBar = new Fl_Scrollbar(0,0,1,1); + mVScrollBar->callback((Fl_Callback*)v_scrollbar_cb, this); + mHScrollBar = new Fl_Scrollbar(0,0,1,1); + mHScrollBar->callback((Fl_Callback*)h_scrollbar_cb, this); + mHScrollBar->type(FL_HORIZONTAL); + + end(); + + scrollbar_width(Fl::scrollbar_size()); + scrollbar_align(FL_ALIGN_BOTTOM_RIGHT); + + mCursorOn = 0; + mCursorPos = 0; + mCursorOldY = -100; + mCursorToHint = NO_HINT; + mCursorStyle = NORMAL_CURSOR; + mCursorPreferredCol = -1; + mBuffer = 0; + mFirstChar = 0; + mLastChar = 0; + mNBufferLines = 0; + mTopLineNum = mTopLineNumHint = 1; + mAbsTopLineNum = 1; + mNeedAbsTopLineNum = 0; + mHorizOffset = mHorizOffsetHint = 0; + + mCursor_color = FL_FOREGROUND_COLOR; + + mFixedFontWidth = -1; + mStyleBuffer = 0; + mStyleTable = 0; + mNStyles = 0; + mNVisibleLines = 1; + mLineStarts = new int[mNVisibleLines]; + mLineStarts[0] = 0; + for (i=1; iremove_modify_callback(buffer_modified_cb, this); + mBuffer->remove_predelete_callback(buffer_predelete_cb, this); + } + if (mLineStarts) delete[] mLineStarts; +} + +/* +** Attach a text buffer to display, replacing the current buffer (if any) +*/ +void Fl_Text_Display::buffer( Fl_Text_Buffer *buf ) { + /* If the text display is already displaying a buffer, clear it off + of the display and remove our callback from it */ + if ( buf == mBuffer) return; + if ( mBuffer != 0 ) { + buffer_modified_cb( 0, 0, mBuffer->length(), 0, 0, this ); + mNBufferLines = 0; + mBuffer->remove_modify_callback( buffer_modified_cb, this ); + mBuffer->remove_predelete_callback( buffer_predelete_cb, this ); + } + + /* Add the buffer to the display, and attach a callback to the buffer for + receiving modification information when the buffer contents change */ + mBuffer = buf; + if (mBuffer) { + mBuffer->add_modify_callback( buffer_modified_cb, this ); + mBuffer->add_predelete_callback( buffer_predelete_cb, this ); + + /* Update the display */ + buffer_modified_cb( 0, buf->length(), 0, 0, 0, this ); + } + + /* Resize the widget to update the screen... */ + resize(x(), y(), w(), h()); +} + +/* +** Attach (or remove) highlight information in text display and redisplay. +** Highlighting information consists of a style buffer which parallels the +** normal text buffer, but codes font and color information for the display; +** a style table which translates style buffer codes (indexed by buffer +** character - 'A') into fonts and colors; and a callback mechanism for +** as-needed highlighting, triggered by a style buffer entry of +** "unfinishedStyle". Style buffer can trigger additional redisplay during +** a normal buffer modification if the buffer contains a primary Fl_Text_Selection +** (see extendRangeForStyleMods for more information on this protocol). +** +** Style buffers, tables and their associated memory are managed by the caller. +*/ +void +Fl_Text_Display::highlight_data(Fl_Text_Buffer *styleBuffer, + const Style_Table_Entry *styleTable, + int nStyles, char unfinishedStyle, + Unfinished_Style_Cb unfinishedHighlightCB, + void *cbArg ) { + mStyleBuffer = styleBuffer; + mStyleTable = styleTable; + mNStyles = nStyles; + mUnfinishedStyle = unfinishedStyle; + mUnfinishedHighlightCB = unfinishedHighlightCB; + mHighlightCBArg = cbArg; + + mStyleBuffer->canUndo(0); +#if 0 + // FIXME: this is in nedit code -- is it needed? + /* Call TextDSetFont to combine font information from style table and + primary font, adjust font-related parameters, and then redisplay */ + TextDSetFont(textD, textD->fontStruct); +#endif + damage(FL_DAMAGE_EXPOSE); +} + +#if 0 + // FIXME: this is in nedit code -- is it needed? +/* +** Change the (non highlight) font +*/ +void TextDSetFont(textDisp *textD, XFontStruct *fontStruct) { + Display *display = XtDisplay(textD->w); + int i, maxAscent = fontStruct->ascent, maxDescent = fontStruct->descent; + int width, height, fontWidth; + Pixel bgPixel, fgPixel, selectFGPixel, selectBGPixel; + Pixel highlightFGPixel, highlightBGPixel; + XGCValues values; + XFontStruct *styleFont; + + /* If font size changes, cursor will be redrawn in a new position */ + blankCursorProtrusions(textD); + + /* If there is a (syntax highlighting) style table in use, find the new + maximum font height for this text display */ + for (i=0; inStyles; i++) { + styleFont = textD->styleTable[i].font; + if (styleFont != NULL && styleFont->ascent > maxAscent) + maxAscent = styleFont->ascent; + if (styleFont != NULL && styleFont->descent > maxDescent) + maxDescent = styleFont->descent; + } + textD->ascent = maxAscent; + textD->descent = maxDescent; + + /* If all of the current fonts are fixed and match in width, compute */ + fontWidth = fontStruct->max_bounds.width; + if (fontWidth != fontStruct->min_bounds.width) + fontWidth = -1; + else { + for (i=0; inStyles; i++) { + styleFont = textD->styleTable[i].font; + if (styleFont != NULL && (styleFont->max_bounds.width != fontWidth || + styleFont->max_bounds.width != styleFont->min_bounds.width)) + fontWidth = -1; + } + } + textD->fixedFontWidth = fontWidth; + + /* Don't let the height dip below one line, or bad things can happen */ + if (textD->height < maxAscent + maxDescent) + textD->height = maxAscent + maxDescent; + + /* Change the font. In most cases, this means re-allocating the + affected GCs (they are shared with other widgets, and if the primary + font changes, must be re-allocated to change it). Unfortunately, + this requres recovering all of the colors from the existing GCs */ + textD->fontStruct = fontStruct; + XGetGCValues(display, textD->gc, GCForeground|GCBackground, &values); + fgPixel = values.foreground; + bgPixel = values.background; + XGetGCValues(display, textD->selectGC, GCForeground|GCBackground, &values); + selectFGPixel = values.foreground; + selectBGPixel = values.background; + XGetGCValues(display, textD->highlightGC,GCForeground|GCBackground,&values); + highlightFGPixel = values.foreground; + highlightBGPixel = values.background; + releaseGC(textD->w, textD->gc); + releaseGC(textD->w, textD->selectGC); + releaseGC(textD->w, textD->highlightGC); + releaseGC(textD->w, textD->selectBGGC); + releaseGC(textD->w, textD->highlightBGGC); + if (textD->lineNumGC != NULL) + releaseGC(textD->w, textD->lineNumGC); + textD->lineNumGC = NULL; + allocateFixedFontGCs(textD, fontStruct, bgPixel, fgPixel, selectFGPixel, + selectBGPixel, highlightFGPixel, highlightBGPixel); + XSetFont(display, textD->styleGC, fontStruct->fid); + + /* Do a full resize to force recalculation of font related parameters */ + width = textD->width; + height = textD->height; + textD->width = textD->height = 0; + TextDResize(textD, width, height); + + /* Redisplay */ + TextDRedisplayRect(textD, textD->left, textD->top, textD->width, + textD->height); + + /* Clean up line number area in case spacing has changed */ + draw_line_numbers(textD, True); +} + +int TextDMinFontWidth(textDisp *textD, Boolean considerStyles) { + int fontWidth = textD->fontStruct->max_bounds.width; + int i; + + if (considerStyles) { + for (i = 0; i < textD->nStyles; ++i) { + int thisWidth = (textD->styleTable[i].font)->min_bounds.width; + if (thisWidth < fontWidth) { + fontWidth = thisWidth; + } + } + } + return(fontWidth); +} + +int TextDMaxFontWidth(textDisp *textD, Boolean considerStyles) { + int fontWidth = textD->fontStruct->max_bounds.width; + int i; + + if (considerStyles) { + for (i = 0; i < textD->nStyles; ++i) { + int thisWidth = (textD->styleTable[i].font)->max_bounds.width; + if (thisWidth > fontWidth) { + fontWidth = thisWidth; + } + } + } + return(fontWidth); +} +#endif + +int Fl_Text_Display::longest_vline() { + int longest = 0; + for (int i = 0; i < mNVisibleLines; i++) + longest = max(longest, measure_vline(i)); + return longest; +} + +/* +** Change the size of the displayed text area +*/ +void Fl_Text_Display::resize(int X, int Y, int W, int H) { +#ifdef DEBUG + printf("Fl_Text_Display::resize(X=%d, Y=%d, W=%d, H=%d)\n", X, Y, W, H); +#endif // DEBUG + const int oldWidth = w(); +#ifdef DEBUG + printf(" oldWidth=%d, mContinuousWrap=%d, mWrapMargin=%d\n", oldWidth, + mContinuousWrap, mWrapMargin); +#endif // DEBUG + Fl_Widget::resize(X,Y,W,H); + if (!buffer()) return; + X += Fl::box_dx(box()); + Y += Fl::box_dy(box()); + W -= Fl::box_dw(box()); + H -= Fl::box_dh(box()); + + text_area.x = X+LEFT_MARGIN; + text_area.y = Y+BOTTOM_MARGIN; + text_area.w = W-LEFT_MARGIN-RIGHT_MARGIN; + text_area.h = H-TOP_MARGIN-BOTTOM_MARGIN; + int i; + + /* Find the new maximum font height for this text display */ + for (i = 0, mMaxsize = fl_height(textfont(), textsize()); i < mNStyles; i++) + mMaxsize = max(mMaxsize, fl_height(mStyleTable[i].font, mStyleTable[i].size)); + + // did we have scrollbars initially? + int hscrollbarvisible = mHScrollBar->visible(); + int vscrollbarvisible = mVScrollBar->visible(); + + // try without scrollbars first + mVScrollBar->clear_visible(); + mHScrollBar->clear_visible(); + + for (int again = 1; again;) { + again = 0; + /* In continuous wrap mode, a change in width affects the total number of + lines in the buffer, and can leave the top line number incorrect, and + the top character no longer pointing at a valid line start */ + if (mContinuousWrap && !mWrapMargin && W!=oldWidth) { + int oldFirstChar = mFirstChar; + mNBufferLines = count_lines(0, buffer()->length(), true); + mFirstChar = line_start(mFirstChar); + mTopLineNum = count_lines(0, mFirstChar, true)+1; + absolute_top_line_number(oldFirstChar); + +#ifdef DEBUG + printf(" mNBufferLines=%d\n", mNBufferLines); +#endif // DEBUG + } + + /* reallocate and update the line starts array, which may have changed + size and / or contents. */ + int nvlines = (text_area.h + mMaxsize - 1) / mMaxsize; + if (nvlines < 1) nvlines = 1; + if (mNVisibleLines != nvlines) { + mNVisibleLines = nvlines; + if (mLineStarts) delete[] mLineStarts; + mLineStarts = new int [mNVisibleLines]; + } + + calc_line_starts(0, mNVisibleLines); + calc_last_char(); + + // figure the scrollbars + if (scrollbar_width()) { + /* Decide if the vertical scroll bar needs to be visible */ + if (scrollbar_align() & (FL_ALIGN_LEFT|FL_ALIGN_RIGHT) && + mNBufferLines >= mNVisibleLines - 1) + { + mVScrollBar->set_visible(); + if (scrollbar_align() & FL_ALIGN_LEFT) { + text_area.x = X+scrollbar_width()+LEFT_MARGIN; + text_area.w = W-scrollbar_width()-LEFT_MARGIN-RIGHT_MARGIN; + mVScrollBar->resize(X, text_area.y-TOP_MARGIN, scrollbar_width(), + text_area.h+TOP_MARGIN+BOTTOM_MARGIN); + } else { + text_area.x = X+LEFT_MARGIN; + text_area.w = W-scrollbar_width()-LEFT_MARGIN-RIGHT_MARGIN; + mVScrollBar->resize(X+W-scrollbar_width(), text_area.y-TOP_MARGIN, + scrollbar_width(), text_area.h+TOP_MARGIN+BOTTOM_MARGIN); + } + } + + /* + Decide if the horizontal scroll bar needs to be visible. If there + is a vertical scrollbar, a horizontal is always created too. This + is because the alternatives are unatractive: + * Dynamically creating a horizontal scrollbar based on the currently + visible lines is what the original nedit does, but it always wastes + space for the scrollbar even when it's not used. Since the FLTK + widget dynamically allocates the space for the scrollbar and + rearranges the widget to make room for it, this would create a very + visually displeasing "bounce" effect when the vertical scrollbar is + dragged. Trust me, I tried it and it looks really bad. + * The other alternative would be to keep track of what the longest + line in the entire buffer is and base the scrollbar on that. I + didn't do this because I didn't see any easy way to do that using + the nedit code and this could involve a lengthy calculation for + large buffers. If an efficient and non-costly way of doing this + can be found, this might be a way to go. + */ + /* WAS: Suggestion: Try turning the horizontal scrollbar on when + you first see a line that is too wide in the window, but then + don't turn it off (ie mix both of your solutions). */ + if (scrollbar_align() & (FL_ALIGN_TOP|FL_ALIGN_BOTTOM) && + (mVScrollBar->visible() || longest_vline() > text_area.w)) + { + if (!mHScrollBar->visible()) { + mHScrollBar->set_visible(); + again = 1; // loop again to see if we now need vert. & recalc sizes + } + if (scrollbar_align() & FL_ALIGN_TOP) { + text_area.y = Y + scrollbar_width()+TOP_MARGIN; + text_area.h = H - scrollbar_width()-TOP_MARGIN-BOTTOM_MARGIN; + mHScrollBar->resize(text_area.x-LEFT_MARGIN, Y, + text_area.w+LEFT_MARGIN+RIGHT_MARGIN, scrollbar_width()); + } else { + text_area.y = Y+TOP_MARGIN; + text_area.h = H - scrollbar_width()-TOP_MARGIN-BOTTOM_MARGIN; + mHScrollBar->resize(text_area.x-LEFT_MARGIN, Y+H-scrollbar_width(), + text_area.w+LEFT_MARGIN+RIGHT_MARGIN, scrollbar_width()); + } + } + } + } + + // user request to change viewport + if (mTopLineNumHint != mTopLineNum || mHorizOffsetHint != mHorizOffset) + scroll_(mTopLineNumHint, mHorizOffsetHint); + + // everything will fit in the viewport + if (mNBufferLines < mNVisibleLines || mBuffer == NULL || mBuffer->length() == 0) + scroll_(1, mHorizOffset); + /* if empty lines become visible, there may be an opportunity to + display more text by scrolling down */ + else while (mLineStarts[mNVisibleLines-2] == -1) + scroll_(mTopLineNum-1, mHorizOffset); + + // user request to display insert position + if (display_insert_position_hint) + display_insert(); + + // in case horizontal offset is now greater than longest line + int maxhoffset = max(0, longest_vline()-text_area.w); + if (mHorizOffset > maxhoffset) + scroll_(mTopLineNumHint, maxhoffset); + + mTopLineNumHint = mTopLineNum; + mHorizOffsetHint = mHorizOffset; + display_insert_position_hint = 0; + + if (mContinuousWrap || + hscrollbarvisible != mHScrollBar->visible() || + vscrollbarvisible != mVScrollBar->visible()) + redraw(); + + update_v_scrollbar(); + update_h_scrollbar(); +} + +/* +** Refresh a rectangle of the text display. left and top are in coordinates of +** the text drawing window +*/ +void Fl_Text_Display::draw_text( int left, int top, int width, int height ) { + int fontHeight, firstLine, lastLine, line; + + /* find the line number range of the display */ + fontHeight = mMaxsize ? mMaxsize : textsize_; + firstLine = ( top - text_area.y - fontHeight + 1 ) / fontHeight; + lastLine = ( top + height - text_area.y ) / fontHeight + 1; + + fl_push_clip( left, top, width, height ); + + /* draw the lines */ + for ( line = firstLine; line <= lastLine; line++ ) + draw_vline( line, left, left + width, 0, INT_MAX ); + + /* draw the line numbers if exposed area includes them */ + if (mLineNumWidth != 0 && left <= mLineNumLeft + mLineNumWidth) + draw_line_numbers(false); + + fl_pop_clip(); +} + +void Fl_Text_Display::redisplay_range(int startpos, int endpos) { + if (damage_range1_start == -1 && damage_range1_end == -1) { + damage_range1_start = startpos; + damage_range1_end = endpos; + } else if ((startpos >= damage_range1_start && startpos <= damage_range1_end) || + (endpos >= damage_range1_start && endpos <= damage_range1_end)) { + damage_range1_start = min(damage_range1_start, startpos); + damage_range1_end = max(damage_range1_end, endpos); + } else if (damage_range2_start == -1 && damage_range2_end == -1) { + damage_range2_start = startpos; + damage_range2_end = endpos; + } else { + damage_range2_start = min(damage_range2_start, startpos); + damage_range2_end = max(damage_range2_end, endpos); + } + damage(FL_DAMAGE_SCROLL); +} +/* +** Refresh all of the text between buffer positions "start" and "end" +** not including the character at the position "end". +** If end points beyond the end of the buffer, refresh the whole display +** after pos, including blank lines which are not technically part of +** any range of characters. +*/ +void Fl_Text_Display::draw_range(int startpos, int endpos) { + int i, startLine, lastLine, startIndex, endIndex; + + /* If the range is outside of the displayed text, just return */ + if ( endpos < mFirstChar || ( startpos > mLastChar && + !empty_vlines() ) ) return; + + /* Clean up the starting and ending values */ + if ( startpos < 0 ) startpos = 0; + if ( startpos > mBuffer->length() ) startpos = mBuffer->length(); + if ( endpos < 0 ) endpos = 0; + if ( endpos > mBuffer->length() ) endpos = mBuffer->length(); + + /* Get the starting and ending lines */ + if ( startpos < mFirstChar ) + startpos = mFirstChar; + if ( !position_to_line( startpos, &startLine ) ) + startLine = mNVisibleLines - 1; + if ( endpos >= mLastChar ) { + lastLine = mNVisibleLines - 1; + } else { + if ( !position_to_line( endpos, &lastLine ) ) { + /* shouldn't happen */ + lastLine = mNVisibleLines - 1; + } + } + + /* Get the starting and ending positions within the lines */ + startIndex = mLineStarts[ startLine ] == -1 ? 0 : + startpos - mLineStarts[ startLine ]; + if ( endpos >= mLastChar ) + endIndex = INT_MAX; + else if ( mLineStarts[ lastLine ] == -1 ) + endIndex = 0; + else + endIndex = endpos - mLineStarts[ lastLine ]; + + /* If the starting and ending lines are the same, redisplay the single + line between "start" and "end" */ + if ( startLine == lastLine ) { + draw_vline( startLine, 0, INT_MAX, startIndex, endIndex ); + return; + } + + /* Redisplay the first line from "start" */ + draw_vline( startLine, 0, INT_MAX, startIndex, INT_MAX ); + + /* Redisplay the lines in between at their full width */ + for ( i = startLine + 1; i < lastLine; i++ ) + draw_vline( i, 0, INT_MAX, 0, INT_MAX ); + + /* Redisplay the last line to "end" */ + draw_vline( lastLine, 0, INT_MAX, 0, endIndex ); +} + +/* +** Set the position of the text insertion cursor for text display +*/ +void Fl_Text_Display::insert_position( int newPos ) { + /* make sure new position is ok, do nothing if it hasn't changed */ + if ( newPos == mCursorPos ) + return; + if ( newPos < 0 ) newPos = 0; + if ( newPos > mBuffer->length() ) newPos = mBuffer->length(); + + /* cursor movement cancels vertical cursor motion column */ + mCursorPreferredCol = -1; + + /* erase the cursor at it's previous position */ + redisplay_range(mCursorPos - 1, mCursorPos + 1); + + mCursorPos = newPos; + + /* draw cursor at its new position */ + redisplay_range(mCursorPos - 1, mCursorPos + 1); +} + +void Fl_Text_Display::show_cursor(int b) { + mCursorOn = b; + redisplay_range(mCursorPos - 1, mCursorPos + 1); +} + +void Fl_Text_Display::cursor_style(int style) { + mCursorStyle = style; + if (mCursorOn) show_cursor(); +} + +void Fl_Text_Display::wrap_mode(int wrap, int wrapMargin) { + mWrapMargin = wrapMargin; + mContinuousWrap = wrap; + + if (buffer()) { + /* wrapping can change the total number of lines, re-count */ + mNBufferLines = count_lines(0, buffer()->length(), true); + + /* changing wrap margins or changing from wrapped mode to non-wrapped + can leave the character at the top no longer at a line start, and/or + change the line number */ + mFirstChar = line_start(mFirstChar); + mTopLineNum = count_lines(0, mFirstChar, true) + 1; + + reset_absolute_top_line_number(); + + /* update the line starts array */ + calc_line_starts(0, mNVisibleLines); + calc_last_char(); + } else { + // No buffer, so just clear the state info for later... + mNBufferLines = 0; + mFirstChar = 0; + mTopLineNum = 1; + mAbsTopLineNum = 0; + } + + resize(x(), y(), w(), h()); +} + +/* +** Insert "text" at the current cursor location. This has the same +** effect as inserting the text into the buffer using BufInsert and +** then moving the insert position after the newly inserted text, except +** that it's optimized to do less redrawing. +*/ +void Fl_Text_Display::insert(const char* text) { + int pos = mCursorPos; + + mCursorToHint = pos + strlen( text ); + mBuffer->insert( pos, text ); + mCursorToHint = NO_HINT; +} + +/* +** Insert "text" (which must not contain newlines), overstriking the current +** cursor location. +*/ +void Fl_Text_Display::overstrike(const char* text) { + int startPos = mCursorPos; + Fl_Text_Buffer *buf = mBuffer; + int lineStart = buf->line_start( startPos ); + int textLen = strlen( text ); + int i, p, endPos, indent, startIndent, endIndent; + const char *c; + char ch, *paddedText = NULL; + + /* determine how many displayed character positions are covered */ + startIndent = mBuffer->count_displayed_characters( lineStart, startPos ); + indent = startIndent; + for ( c = text; *c != '\0'; c++ ) + indent += Fl_Text_Buffer::character_width( *c, indent, buf->tab_distance(), buf->null_substitution_character() ); + endIndent = indent; + + /* find which characters to remove, and if necessary generate additional + padding to make up for removed control characters at the end */ + indent = startIndent; + for ( p = startPos; ; p++ ) { + if ( p == buf->length() ) + break; + ch = buf->character( p ); + if ( ch == '\n' ) + break; + indent += Fl_Text_Buffer::character_width( ch, indent, buf->tab_distance(), buf->null_substitution_character() ); + if ( indent == endIndent ) { + p++; + break; + } else if ( indent > endIndent ) { + if ( ch != '\t' ) { + p++; + paddedText = new char [ textLen + FL_TEXT_MAX_EXP_CHAR_LEN + 1 ]; + strcpy( paddedText, text ); + for ( i = 0; i < indent - endIndent; i++ ) + paddedText[ textLen + i ] = ' '; + paddedText[ textLen + i ] = '\0'; + } + break; + } + } + endPos = p; + + mCursorToHint = startPos + textLen; + buf->replace( startPos, endPos, paddedText == NULL ? text : paddedText ); + mCursorToHint = NO_HINT; + if ( paddedText != NULL ) + delete [] paddedText; +} + +/* +** Translate a buffer text position to the XY location where the top left +** of the cursor would be positioned to point to that character. Returns +** 0 if the position is not displayed because it is VERTICALLY out +** of view. If the position is horizontally out of view, returns the +** X coordinate where the position would be if it were visible. +*/ + +int Fl_Text_Display::position_to_xy( int pos, int* X, int* Y ) { + int charIndex, lineStartPos, fontHeight, lineLen; + int visLineNum, charLen, outIndex, xStep, charStyle; + char expandedChar[ FL_TEXT_MAX_EXP_CHAR_LEN ]; + const char *lineStr; + +// printf("position_to_xy(pos=%d, X=%p, Y=%p)\n", pos, X, Y); + + /* If position is not displayed, return false */ + if (pos < mFirstChar || (pos > mLastChar && !empty_vlines())) { +// printf(" returning 0\n" +// " mFirstChar=%d, mLastChar=%d, empty_vlines()=0\n", +// mFirstChar, mLastChar); + return 0; + } + + /* Calculate Y coordinate */ + if (!position_to_line(pos, &visLineNum)) { +// puts(" returning 0\n" +// " position_to_line()=0"); + return 0; + } + + if (visLineNum < 0 || visLineNum > mNBufferLines) { +// printf(" returning 0\n" +// " visLineNum=%d, mNBufferLines=%d\n", +// visLineNum, mNBufferLines); + return 0; + } + + fontHeight = mMaxsize; + *Y = text_area.y + visLineNum * fontHeight; + + /* Get the text, length, and buffer position of the line. If the position + is beyond the end of the buffer and should be at the first position on + the first empty line, don't try to get or scan the text */ + lineStartPos = mLineStarts[visLineNum]; + if ( lineStartPos == -1 ) { + *X = text_area.x - mHorizOffset; + return 1; + } + lineLen = vline_length( visLineNum ); + lineStr = mBuffer->text_range( lineStartPos, lineStartPos + lineLen ); + + /* Step through character positions from the beginning of the line + to "pos" to calculate the X coordinate */ + xStep = text_area.x - mHorizOffset; + outIndex = 0; + for ( charIndex = 0; charIndex < lineLen && charIndex < pos - lineStartPos; charIndex++ ) { + charLen = Fl_Text_Buffer::expand_character( lineStr[ charIndex ], outIndex, expandedChar, + mBuffer->tab_distance(), mBuffer->null_substitution_character() ); + charStyle = position_style( lineStartPos, lineLen, charIndex, + outIndex ); + xStep += string_width( expandedChar, charLen, charStyle ); + outIndex += charLen; + } + *X = xStep; + free((char *)lineStr); + return 1; +} + +/* +** Find the line number of position "pos". Note: this only works for +** displayed lines. If the line is not displayed, the function returns +** 0 (without the mLineStarts array it could turn in to very long +** calculation involving scanning large amounts of text in the buffer). +** If continuous wrap mode is on, returns the absolute line number (as opposed +** to the wrapped line number which is used for scrolling). +*/ +int Fl_Text_Display::position_to_linecol( int pos, int* lineNum, int* column ) { + int retVal; + + /* In continuous wrap mode, the absolute (non-wrapped) line count is + maintained separately, as needed. Only return it if we're actually + keeping track of it and pos is in the displayed text */ + if (mContinuousWrap) { + if (!maintaining_absolute_top_line_number() || + pos < mFirstChar || pos > mLastChar) + return 0; + *lineNum = mAbsTopLineNum + buffer()->count_lines(mFirstChar, pos); + *column + = buffer()->count_displayed_characters(buffer()->line_start(pos), pos); + return 1; + } + + retVal = position_to_line( pos, lineNum ); + if ( retVal ) { + *column = mBuffer->count_displayed_characters( + mLineStarts[ *lineNum ], pos ); + *lineNum += mTopLineNum; + } + return retVal; +} + +/* +** Return 1 if position (X, Y) is inside of the primary Fl_Text_Selection +*/ +int Fl_Text_Display::in_selection( int X, int Y ) { + int row, column, pos = xy_to_position( X, Y, CHARACTER_POS ); + Fl_Text_Buffer *buf = mBuffer; + + xy_to_rowcol( X, Y, &row, &column, CHARACTER_POS ); + if (range_touches_selection(buf->primary_selection(), mFirstChar, mLastChar)) + column = wrapped_column(row, column); + return buf->primary_selection()->includes(pos, buf->line_start( pos ), column); +} + +/* +** Correct a column number based on an unconstrained position (as returned by +** TextDXYToUnconstrainedPosition) to be relative to the last actual newline +** in the buffer before the row and column position given, rather than the +** last line start created by line wrapping. This is an adapter +** for rectangular selections and code written before continuous wrap mode, +** which thinks that the unconstrained column is the number of characters +** from the last newline. Obviously this is time consuming, because it +** invloves character re-counting. +*/ +int Fl_Text_Display::wrapped_column(int row, int column) { + int lineStart, dispLineStart; + + if (!mContinuousWrap || row < 0 || row > mNVisibleLines) + return column; + dispLineStart = mLineStarts[row]; + if (dispLineStart == -1) + return column; + lineStart = buffer()->line_start(dispLineStart); + return column + + buffer()->count_displayed_characters(lineStart, dispLineStart); +} + +/* +** Correct a row number from an unconstrained position (as returned by +** TextDXYToUnconstrainedPosition) to a straight number of newlines from the +** top line of the display. Because rectangular selections are based on +** newlines, rather than display wrapping, and anywhere a rectangular selection +** needs a row, it needs it in terms of un-wrapped lines. +*/ +int Fl_Text_Display::wrapped_row(int row) { + if (!mContinuousWrap || row < 0 || row > mNVisibleLines) + return row; + return buffer()->count_lines(mFirstChar, mLineStarts[row]); +} + +/* +** Scroll the display to bring insertion cursor into view. +** +** Note: it would be nice to be able to do this without counting lines twice +** (scroll_() counts them too) and/or to count from the most efficient +** starting point, but the efficiency of this routine is not as important to +** the overall performance of the text display. +*/ +void Fl_Text_Display::display_insert() { + int hOffset, topLine, X, Y; + hOffset = mHorizOffset; + topLine = mTopLineNum; + +// FIXME: I don't understand this well enough to know if it is correct +// it is different than nedit 5.3 + if (insert_position() < mFirstChar) { + topLine -= count_lines(insert_position(), mFirstChar, false); + } else if (mLineStarts[mNVisibleLines-2] != -1) { + int lastChar = line_end(mLineStarts[mNVisibleLines-2],true); + if (insert_position() >= lastChar) + topLine + += count_lines(lastChar - (wrap_uses_character(mLastChar) ? 0 : 1), + insert_position(), false); + } + + /* Find the new setting for horizontal offset (this is a bit ungraceful). + If the line is visible, just use PositionToXY to get the position + to scroll to, otherwise, do the vertical scrolling first, then the + horizontal */ + if (!position_to_xy( mCursorPos, &X, &Y )) { + scroll_(topLine, hOffset); + if (!position_to_xy( mCursorPos, &X, &Y )) { + #ifdef DEBUG + printf ("*** display_insert/position_to_xy # GIVE UP !\n"); fflush(stdout); + #endif // DEBUG + return; /* Give up, it's not worth it (but why does it fail?) */ + } + } + if (X > text_area.x + text_area.w) + hOffset += X-(text_area.x + text_area.w); + else if (X < text_area.x) + hOffset += X-text_area.x; + + /* Do the scroll */ + if (topLine != mTopLineNum || hOffset != mHorizOffset) + scroll_(topLine, hOffset); +} + +void Fl_Text_Display::show_insert_position() { + display_insert_position_hint = 1; + resize(x(), y(), w(), h()); +} + +/* +** Cursor movement functions +*/ +int Fl_Text_Display::move_right() { + if ( mCursorPos >= mBuffer->length() ) + return 0; + insert_position( mCursorPos + 1 ); + return 1; +} + +int Fl_Text_Display::move_left() { + if ( mCursorPos <= 0 ) + return 0; + insert_position( mCursorPos - 1 ); + return 1; +} + +int Fl_Text_Display::move_up() { + int lineStartPos, column, prevLineStartPos, newPos, visLineNum; + + /* Find the position of the start of the line. Use the line starts array + if possible */ + if ( position_to_line( mCursorPos, &visLineNum ) ) + lineStartPos = mLineStarts[ visLineNum ]; + else { + lineStartPos = line_start( mCursorPos ); + visLineNum = -1; + } + if ( lineStartPos == 0 ) + return 0; + + /* Decide what column to move to, if there's a preferred column use that */ + column = mCursorPreferredCol >= 0 ? mCursorPreferredCol : + mBuffer->count_displayed_characters( lineStartPos, mCursorPos ); + + /* count forward from the start of the previous line to reach the column */ + if ( visLineNum != -1 && visLineNum != 0 ) + prevLineStartPos = mLineStarts[ visLineNum - 1 ]; + else + prevLineStartPos = rewind_lines( lineStartPos, 1 ); + newPos = mBuffer->skip_displayed_characters( prevLineStartPos, column ); + if (mContinuousWrap) + newPos = min(newPos, line_end(prevLineStartPos, true)); + + /* move the cursor */ + insert_position( newPos ); + + /* if a preferred column wasn't aleady established, establish it */ + mCursorPreferredCol = column; + return 1; +} + +int Fl_Text_Display::move_down() { + int lineStartPos, column, nextLineStartPos, newPos, visLineNum; + + if ( mCursorPos == mBuffer->length() ) + return 0; + if ( position_to_line( mCursorPos, &visLineNum ) ) + lineStartPos = mLineStarts[ visLineNum ]; + else { + lineStartPos = line_start( mCursorPos ); + visLineNum = -1; + } + column = mCursorPreferredCol >= 0 ? mCursorPreferredCol : + mBuffer->count_displayed_characters( lineStartPos, mCursorPos ); + nextLineStartPos = skip_lines( lineStartPos, 1, true ); + newPos = mBuffer->skip_displayed_characters( nextLineStartPos, column ); + if (mContinuousWrap) + newPos = min(newPos, line_end(nextLineStartPos, true)); + + insert_position( newPos ); + mCursorPreferredCol = column; + return 1; +} + +/* +** Same as BufCountLines, but takes in to account wrapping if wrapping is +** turned on. If the caller knows that startPos is at a line start, it +** can pass "startPosIsLineStart" as True to make the call more efficient +** by avoiding the additional step of scanning back to the last newline. +*/ +int Fl_Text_Display::count_lines(int startPos, int endPos, + bool startPosIsLineStart) { + int retLines, retPos, retLineStart, retLineEnd; + +#ifdef DEBUG + printf("Fl_Text_Display::count_lines(startPos=%d, endPos=%d, startPosIsLineStart=%d\n", + startPos, endPos, startPosIsLineStart); +#endif // DEBUG + + /* If we're not wrapping use simple (and more efficient) BufCountLines */ + if (!mContinuousWrap) + return buffer()->count_lines(startPos, endPos); + + wrapped_line_counter(buffer(), startPos, endPos, INT_MAX, + startPosIsLineStart, 0, &retPos, &retLines, &retLineStart, + &retLineEnd); + +#ifdef DEBUG + printf(" # after WLC: retPos=%d, retLines=%d, retLineStart=%d, retLineEnd=%d\n", + retPos, retLines, retLineStart, retLineEnd); +#endif // DEBUG + + return retLines; +} + +/* +** Same as BufCountForwardNLines, but takes in to account line breaks when +** wrapping is turned on. If the caller knows that startPos is at a line start, +** it can pass "startPosIsLineStart" as True to make the call more efficient +** by avoiding the additional step of scanning back to the last newline. +*/ +int Fl_Text_Display::skip_lines(int startPos, int nLines, + bool startPosIsLineStart) { + int retLines, retPos, retLineStart, retLineEnd; + + /* if we're not wrapping use more efficient BufCountForwardNLines */ + if (!mContinuousWrap) + return buffer()->skip_lines(startPos, nLines); + + /* wrappedLineCounter can't handle the 0 lines case */ + if (nLines == 0) + return startPos; + + /* use the common line counting routine to count forward */ + wrapped_line_counter(buffer(), startPos, buffer()->length(), + nLines, startPosIsLineStart, 0, &retPos, &retLines, &retLineStart, + &retLineEnd); + return retPos; +} + +/* +** Same as BufEndOfLine, but takes in to account line breaks when wrapping +** is turned on. If the caller knows that startPos is at a line start, it +** can pass "startPosIsLineStart" as True to make the call more efficient +** by avoiding the additional step of scanning back to the last newline. +** +** Note that the definition of the end of a line is less clear when continuous +** wrap is on. With continuous wrap off, it's just a pointer to the newline +** that ends the line. When it's on, it's the character beyond the last +** DISPLAYABLE character on the line, where a whitespace character which has +** been "converted" to a newline for wrapping is not considered displayable. +** Also note that, a line can be wrapped at a non-whitespace character if the +** line had no whitespace. In this case, this routine returns a pointer to +** the start of the next line. This is also consistent with the model used by +** visLineLength. +*/ +int Fl_Text_Display::line_end(int pos, bool startPosIsLineStart) { + int retLines, retPos, retLineStart, retLineEnd; + + /* If we're not wrapping use more efficien BufEndOfLine */ + if (!mContinuousWrap) + return buffer()->line_end(pos); + + if (pos == buffer()->length()) + return pos; + wrapped_line_counter(buffer(), pos, buffer()->length(), 1, + startPosIsLineStart, 0, &retPos, &retLines, &retLineStart, + &retLineEnd); + return retLineEnd; +} + +/* +** Same as BufStartOfLine, but returns the character after last wrap point +** rather than the last newline. +*/ +int Fl_Text_Display::line_start(int pos) { + int retLines, retPos, retLineStart, retLineEnd; + + /* If we're not wrapping, use the more efficient BufStartOfLine */ + if (!mContinuousWrap) + return buffer()->line_start(pos); + + wrapped_line_counter(buffer(), buffer()->line_start(pos), pos, INT_MAX, true, 0, + &retPos, &retLines, &retLineStart, &retLineEnd); + return retLineStart; +} + +/* +** Same as BufCountBackwardNLines, but takes in to account line breaks when +** wrapping is turned on. +*/ +int Fl_Text_Display::rewind_lines(int startPos, int nLines) { + Fl_Text_Buffer *buf = buffer(); + int pos, lineStart, retLines, retPos, retLineStart, retLineEnd; + + /* If we're not wrapping, use the more efficient BufCountBackwardNLines */ + if (!mContinuousWrap) + return buf->rewind_lines(startPos, nLines); + + pos = startPos; + for (;;) { + lineStart = buf->line_start(pos); + wrapped_line_counter(buf, lineStart, pos, INT_MAX, + true, 0, &retPos, &retLines, &retLineStart, &retLineEnd, false); + if (retLines > nLines) + return skip_lines(lineStart, retLines-nLines, + true); + nLines -= retLines; + pos = lineStart - 1; + if (pos < 0) + return 0; + nLines -= 1; + } +} + +static inline int fl_isseparator(int c) { + return c != '$' && c != '_' && (isspace(c) || ispunct(c)); +} + +void Fl_Text_Display::next_word() { + int pos = insert_position(); + while (pos < buffer()->length() && !fl_isseparator(buffer()->character(pos))) { + pos++; + } + while (pos < buffer()->length() && fl_isseparator(buffer()->character(pos))) { + pos++; + } + + insert_position( pos ); +} + +void Fl_Text_Display::previous_word() { + int pos = insert_position(); + if (pos==0) return; + pos--; + while (pos && fl_isseparator(buffer()->character(pos))) { + pos--; + } + while (pos && !fl_isseparator(buffer()->character(pos))) { + pos--; + } + if (fl_isseparator(buffer()->character(pos))) pos++; + + insert_position( pos ); +} + +/* +** Callback attached to the text buffer to receive delete information before +** the modifications are actually made. +*/ +void Fl_Text_Display::buffer_predelete_cb(int pos, int nDeleted, void *cbArg) { + Fl_Text_Display *textD = (Fl_Text_Display *)cbArg; + if (textD->mContinuousWrap && + (textD->mFixedFontWidth == -1 || textD->mModifyingTabDistance)) + /* Note: we must perform this measurement, even if there is not a + single character deleted; the number of "deleted" lines is the + number of visual lines spanned by the real line in which the + modification takes place. + Also, a modification of the tab distance requires the same + kind of calculations in advance, even if the font width is "fixed", + because when the width of the tab characters changes, the layout + of the text may be completely different. */ + textD->measure_deleted_lines(pos, nDeleted); + else + textD->mSuppressResync = 0; /* Probably not needed, but just in case */ +} + +/* +** Callback attached to the text buffer to receive modification information +*/ +void Fl_Text_Display::buffer_modified_cb( int pos, int nInserted, int nDeleted, + int nRestyled, const char *deletedText, void *cbArg ) { + int linesInserted, linesDeleted, startDispPos, endDispPos; + Fl_Text_Display *textD = ( Fl_Text_Display * ) cbArg; + Fl_Text_Buffer *buf = textD->mBuffer; + int oldFirstChar = textD->mFirstChar; + int scrolled, origCursorPos = textD->mCursorPos; + int wrapModStart, wrapModEnd; + + /* buffer modification cancels vertical cursor motion column */ + if ( nInserted != 0 || nDeleted != 0 ) + textD->mCursorPreferredCol = -1; + + /* Count the number of lines inserted and deleted, and in the case + of continuous wrap mode, how much has changed */ + if (textD->mContinuousWrap) { + textD->find_wrap_range(deletedText, pos, nInserted, nDeleted, + &wrapModStart, &wrapModEnd, &linesInserted, &linesDeleted); + } else { + linesInserted = nInserted == 0 ? 0 : + buf->count_lines( pos, pos + nInserted ); + linesDeleted = nDeleted == 0 ? 0 : countlines( deletedText ); + } + + /* Update the line starts and mTopLineNum */ + if ( nInserted != 0 || nDeleted != 0 ) { + if (textD->mContinuousWrap) { + textD->update_line_starts( wrapModStart, wrapModEnd-wrapModStart, + nDeleted + pos-wrapModStart + (wrapModEnd-(pos+nInserted)), + linesInserted, linesDeleted, &scrolled ); + } else { + textD->update_line_starts( pos, nInserted, nDeleted, linesInserted, + linesDeleted, &scrolled ); + } + } else + scrolled = 0; + + /* If we're counting non-wrapped lines as well, maintain the absolute + (non-wrapped) line number of the text displayed */ + if (textD->maintaining_absolute_top_line_number() && + (nInserted != 0 || nDeleted != 0)) { + if (pos + nDeleted < oldFirstChar) + textD->mAbsTopLineNum += buf->count_lines(pos, pos + nInserted) - + countlines(deletedText); + else if (pos < oldFirstChar) + textD->reset_absolute_top_line_number(); + } + + /* Update the line count for the whole buffer */ + textD->mNBufferLines += linesInserted - linesDeleted; + + /* Update the cursor position */ + if ( textD->mCursorToHint != NO_HINT ) { + textD->mCursorPos = textD->mCursorToHint; + textD->mCursorToHint = NO_HINT; + } else if ( textD->mCursorPos > pos ) { + if ( textD->mCursorPos < pos + nDeleted ) + textD->mCursorPos = pos; + else + textD->mCursorPos += nInserted - nDeleted; + } + + // refigure scrollbars & stuff + textD->resize(textD->x(), textD->y(), textD->w(), textD->h()); + + // don't need to do anything else if not visible? + if (!textD->visible_r()) return; + + /* If the changes caused scrolling, re-paint everything and we're done. */ + if ( scrolled ) { + textD->damage(FL_DAMAGE_EXPOSE); + if ( textD->mStyleBuffer ) /* See comments in extendRangeForStyleMods */ + textD->mStyleBuffer->primary_selection()->selected(0); + return; + } + + /* If the changes didn't cause scrolling, decide the range of characters + that need to be re-painted. Also if the cursor position moved, be + sure that the redisplay range covers the old cursor position so the + old cursor gets erased, and erase the bits of the cursor which extend + beyond the left and right edges of the text. */ + startDispPos = textD->mContinuousWrap ? wrapModStart : pos; + if ( origCursorPos == startDispPos && textD->mCursorPos != startDispPos ) + startDispPos = min( startDispPos, origCursorPos - 1 ); + if ( linesInserted == linesDeleted ) { + if ( nInserted == 0 && nDeleted == 0 ) + endDispPos = pos + nRestyled; + else { + endDispPos = textD->mContinuousWrap ? wrapModEnd : + buf->line_end( pos + nInserted ) + 1; + // CET - FIXME if ( origCursorPos >= startDispPos && + // ( origCursorPos <= endDispPos || endDispPos == buf->length() ) ) + } + + if (linesInserted > 1) textD->draw_line_numbers(false); + } else { + endDispPos = textD->mLastChar + 1; + // CET - FIXME if ( origCursorPos >= pos ) + /* If more than one line is inserted/deleted, a line break may have + been inserted or removed in between, and the line numbers may + have changed. If only one line is altered, line numbers cannot + be affected (the insertion or removal of a line break always + results in at least two lines being redrawn). */ + textD->draw_line_numbers(false); + } + + /* If there is a style buffer, check if the modification caused additional + changes that need to be redisplayed. (Redisplaying separately would + cause double-redraw on almost every modification involving styled + text). Extend the redraw range to incorporate style changes */ + if ( textD->mStyleBuffer ) + textD->extend_range_for_styles( &startDispPos, &endDispPos ); + + /* Redisplay computed range */ + textD->redisplay_range( startDispPos, endDispPos ); +} + +/* +** In continuous wrap mode, internal line numbers are calculated after +** wrapping. A separate non-wrapped line count is maintained when line +** numbering is turned on. There is some performance cost to maintaining this +** line count, so normally absolute line numbers are not tracked if line +** numbering is off. This routine allows callers to specify that they still +** want this line count maintained (for use via TextDPosToLineAndCol). +** More specifically, this allows the line number reported in the statistics +** line to be calibrated in absolute lines, rather than post-wrapped lines. +*/ +void Fl_Text_Display::maintain_absolute_top_line_number(int state) { + mNeedAbsTopLineNum = state; + reset_absolute_top_line_number(); +} + +/* +** Returns the absolute (non-wrapped) line number of the first line displayed. +** Returns 0 if the absolute top line number is not being maintained. +*/ +int Fl_Text_Display::get_absolute_top_line_number() { + if (!mContinuousWrap) + return mTopLineNum; + if (maintaining_absolute_top_line_number()) + return mAbsTopLineNum; + return 0; +} + +/* +** Re-calculate absolute top line number for a change in scroll position. +*/ +void Fl_Text_Display::absolute_top_line_number(int oldFirstChar) { + if (maintaining_absolute_top_line_number()) { + if (mFirstChar < oldFirstChar) + mAbsTopLineNum -= buffer()->count_lines(mFirstChar, oldFirstChar); + else + mAbsTopLineNum += buffer()->count_lines(oldFirstChar, mFirstChar); + } +} + +/* +** Return true if a separate absolute top line number is being maintained +** (for displaying line numbers or showing in the statistics line). +*/ +int Fl_Text_Display::maintaining_absolute_top_line_number() { + return mContinuousWrap && + (mLineNumWidth != 0 || mNeedAbsTopLineNum); +} + +/* +** Count lines from the beginning of the buffer to reestablish the +** absolute (non-wrapped) top line number. If mode is not continuous wrap, +** or the number is not being maintained, does nothing. +*/ +void Fl_Text_Display::reset_absolute_top_line_number() { + mAbsTopLineNum = 1; + absolute_top_line_number(0); +} + +/* +** Find the line number of position "pos" relative to the first line of +** displayed text. Returns 0 if the line is not displayed. +*/ +int Fl_Text_Display::position_to_line( int pos, int *lineNum ) { + int i; + + *lineNum = 0; + if ( pos < mFirstChar ) return 0; + if ( pos > mLastChar ) { + if ( empty_vlines() ) { + if ( mLastChar < mBuffer->length() ) { + if ( !position_to_line( mLastChar, lineNum ) ) { + Fl::error("Fl_Text_Display::position_to_line(): Consistency check ptvl failed"); + return 0; + } + return ++( *lineNum ) <= mNVisibleLines - 1; + } else { + position_to_line( mLastChar - 1, lineNum ); + return 1; + } + } + return 0; + } + + for ( i = mNVisibleLines - 1; i >= 0; i-- ) { + if ( mLineStarts[ i ] != -1 && pos >= mLineStarts[ i ] ) { + *lineNum = i; + return 1; + } + } + return 0; /* probably never be reached */ +} + +/* +** Draw the text on a single line represented by "visLineNum" (the +** number of lines down from the top of the display), limited by +** "leftClip" and "rightClip" window coordinates and "leftCharIndex" and +** "rightCharIndex" character positions (not including the character at +** position "rightCharIndex"). +*/ +void Fl_Text_Display::draw_vline(int visLineNum, int leftClip, int rightClip, + int leftCharIndex, int rightCharIndex) { + Fl_Text_Buffer * buf = mBuffer; + int i, X, Y, startX, charIndex, lineStartPos, lineLen, fontHeight; + int stdCharWidth, charWidth, startIndex, charStyle, style; + int charLen, outStartIndex, outIndex; + int dispIndexOffset; + char expandedChar[ FL_TEXT_MAX_EXP_CHAR_LEN ], outStr[ MAX_DISP_LINE_LEN ]; + char *outPtr; + const char *lineStr; + +// printf("draw_vline(visLineNum=%d, leftClip=%d, rightClip=%d, leftCharIndex=%d, rightCharIndex=%d)\n", +// visLineNum, leftClip, rightClip, leftCharIndex, rightCharIndex); +// printf("nNVisibleLines=%d\n", mNVisibleLines); + + /* If line is not displayed, skip it */ + if ( visLineNum < 0 || visLineNum >= mNVisibleLines ) + return; + + /* Calculate Y coordinate of the string to draw */ + fontHeight = mMaxsize; + Y = text_area.y + visLineNum * fontHeight; + + /* Get the text, length, and buffer position of the line to display */ + lineStartPos = mLineStarts[ visLineNum ]; +// printf("lineStartPos=%d\n", lineStartPos); + if ( lineStartPos == -1 ) { + lineLen = 0; + lineStr = NULL; + } else { + lineLen = vline_length( visLineNum ); + lineStr = buf->text_range( lineStartPos, lineStartPos + lineLen ); + } + + /* Space beyond the end of the line is still counted in units of characters + of a standardized character width (this is done mostly because style + changes based on character position can still occur in this region due + to rectangular Fl_Text_Selections). stdCharWidth must be non-zero to + prevent a potential infinite loop if X does not advance */ + stdCharWidth = TMPFONTWIDTH; //mFontStruct->max_bounds.width; + if ( stdCharWidth <= 0 ) { + Fl::error("Fl_Text_Display::draw_vline(): bad font measurement"); + free((void *)lineStr); + return; + } + + /* Shrink the clipping range to the active display area */ + leftClip = max( text_area.x, leftClip ); + rightClip = min( rightClip, text_area.x + text_area.w ); + + /* Rectangular Fl_Text_Selections are based on "real" line starts (after + a newline or start of buffer). Calculate the difference between the + last newline position and the line start we're using. Since scanning + back to find a newline is expensive, only do so if there's actually a + rectangular Fl_Text_Selection which needs it */ + if (mContinuousWrap && (range_touches_selection(buf->primary_selection(), + lineStartPos, lineStartPos + lineLen) || range_touches_selection( + buf->secondary_selection(), lineStartPos, lineStartPos + lineLen) || + range_touches_selection(buf->highlight_selection(), lineStartPos, + lineStartPos + lineLen))) { + dispIndexOffset = buf->count_displayed_characters( + buf->line_start(lineStartPos), lineStartPos); + } else + dispIndexOffset = 0; + + /* Step through character positions from the beginning of the line (even if + that's off the left edge of the displayed area) to find the first + character position that's not clipped, and the X coordinate for drawing + that character */ + X = text_area.x - mHorizOffset; + outIndex = 0; + for ( charIndex = 0; ; charIndex++ ) { + charLen = charIndex >= lineLen ? 1 : + Fl_Text_Buffer::expand_character( lineStr[ charIndex ], outIndex, + expandedChar, buf->tab_distance(), buf->null_substitution_character() ); + style = position_style( lineStartPos, lineLen, charIndex, + outIndex + dispIndexOffset ); + charWidth = charIndex >= lineLen ? stdCharWidth : + string_width( expandedChar, charLen, style ); + if ( X + charWidth >= leftClip && charIndex >= leftCharIndex ) { + startIndex = charIndex; + outStartIndex = outIndex; + startX = X; + break; + } + X += charWidth; + outIndex += charLen; + } + + /* Scan character positions from the beginning of the clipping range, and + draw parts whenever the style changes (also note if the cursor is on + this line, and where it should be drawn to take advantage of the x + position which we've gone to so much trouble to calculate) */ + /* since characters between style may overlap, we draw the full + background first */ + int sX = startX; + outPtr = outStr; + outIndex = outStartIndex; + X = startX; + for ( charIndex = startIndex; charIndex < rightCharIndex; charIndex++ ) { + charLen = charIndex >= lineLen ? 1 : + Fl_Text_Buffer::expand_character( lineStr[ charIndex ], outIndex, expandedChar, + buf->tab_distance(), buf->null_substitution_character() ); + charStyle = position_style( lineStartPos, lineLen, charIndex, + outIndex + dispIndexOffset ); + for ( i = 0; i < charLen; i++ ) { + if ( i != 0 && charIndex < lineLen && lineStr[ charIndex ] == '\t' ) + charStyle = position_style( lineStartPos, lineLen, + charIndex, outIndex + dispIndexOffset ); + if ( charStyle != style ) { + draw_string( style|BG_ONLY_MASK, sX, Y, X, outStr, outPtr - outStr ); + outPtr = outStr; + sX = X; + style = charStyle; + } + if ( charIndex < lineLen ) { + *outPtr = expandedChar[ i ]; + charWidth = string_width( &expandedChar[ i ], 1, charStyle ); + } else + charWidth = stdCharWidth; + outPtr++; + X += charWidth; + outIndex++; + } + if ( outPtr - outStr + FL_TEXT_MAX_EXP_CHAR_LEN >= MAX_DISP_LINE_LEN || X >= rightClip ) + break; + } + draw_string( style|BG_ONLY_MASK, sX, Y, X, outStr, outPtr - outStr ); + + /* now draw the text over the previously erased background */ + outPtr = outStr; + outIndex = outStartIndex; + X = startX; + for ( charIndex = startIndex; charIndex < rightCharIndex; charIndex++ ) { + charLen = charIndex >= lineLen ? 1 : + Fl_Text_Buffer::expand_character( lineStr[ charIndex ], outIndex, expandedChar, + buf->tab_distance(), buf->null_substitution_character() ); + charStyle = position_style( lineStartPos, lineLen, charIndex, + outIndex + dispIndexOffset ); + for ( i = 0; i < charLen; i++ ) { + if ( i != 0 && charIndex < lineLen && lineStr[ charIndex ] == '\t' ) + charStyle = position_style( lineStartPos, lineLen, + charIndex, outIndex + dispIndexOffset ); + if ( charStyle != style ) { + draw_string( style|TEXT_ONLY_MASK, startX, Y, X, outStr, outPtr - outStr ); + outPtr = outStr; + startX = X; + style = charStyle; + } + if ( charIndex < lineLen ) { + *outPtr = expandedChar[ i ]; + charWidth = string_width( &expandedChar[ i ], 1, charStyle ); + } else + charWidth = stdCharWidth; + outPtr++; + X += charWidth; + outIndex++; + } + if ( outPtr - outStr + FL_TEXT_MAX_EXP_CHAR_LEN >= MAX_DISP_LINE_LEN || X >= rightClip ) + break; + } + + /* Draw the remaining style segment */ + draw_string( style|TEXT_ONLY_MASK, startX, Y, X, outStr, outPtr - outStr ); + + /* Draw the cursor if part of it appeared on the redisplayed part of + this line. Also check for the cases which are not caught as the + line is scanned above: when the cursor appears at the very end + of the redisplayed section. */ + /* CET - FIXME + if ( mCursorOn ) + { + if ( hasCursor ) + draw_cursor( cursorX, Y ); + else if ( charIndex < lineLen && ( lineStartPos + charIndex + 1 == cursorPos ) + && X == rightClip ) + { + if ( cursorPos >= buf->length() ) + draw_cursor( X - 1, Y ); + else + { + draw_cursor( X - 1, Y ); + } + } + } + */ + if ( lineStr != NULL ) + free((void *)lineStr); +} + +/* +** Draw a string or blank area according to parameter "style", using the +** appropriate colors and drawing method for that style, with top left +** corner at X, y. If style says to draw text, use "string" as source of +** characters, and draw "nChars", if style is FILL, erase +** rectangle where text would have drawn from X to toX and from Y to +** the maximum Y extent of the current font(s). +*/ +void Fl_Text_Display::draw_string( int style, int X, int Y, int toX, + const char *string, int nChars ) { + const Style_Table_Entry * styleRec; + + /* Draw blank area rather than text, if that was the request */ + if ( style & FILL_MASK ) { + if (style & TEXT_ONLY_MASK) return; + clear_rect( style, X, Y, toX - X, mMaxsize ); + return; + } + + /* Set font, color, and gc depending on style. For normal text, GCs + for normal drawing, or drawing within a Fl_Text_Selection or highlight are + pre-allocated and pre-configured. For syntax highlighting, GCs are + configured here, on the fly. */ + + Fl_Font font = textfont(); + int fsize = textsize(); + Fl_Color foreground; + Fl_Color background; + + if ( style & STYLE_LOOKUP_MASK ) { + int si = (style & STYLE_LOOKUP_MASK) - 'A'; + if (si < 0) si = 0; + else if (si >= mNStyles) si = mNStyles - 1; + + styleRec = mStyleTable + si; + font = styleRec->font; + fsize = styleRec->size; + + if (style & PRIMARY_MASK) { + if (Fl::focus() == this) background = selection_color(); + else background = fl_color_average(color(), selection_color(), 0.4f); + } else if (style & HIGHLIGHT_MASK) { + if (Fl::focus() == this) background = fl_color_average(color(), selection_color(), 0.5f); + else background = fl_color_average(color(), selection_color(), 0.6f); + } else background = color(); + foreground = fl_contrast(styleRec->color, background); + } else if (style & PRIMARY_MASK) { + if (Fl::focus() == this) background = selection_color(); + else background = fl_color_average(color(), selection_color(), 0.4f); + foreground = fl_contrast(textcolor(), background); + } else if (style & HIGHLIGHT_MASK) { + if (Fl::focus() == this) background = fl_color_average(color(), selection_color(), 0.5f); + else background = fl_color_average(color(), selection_color(), 0.6f); + foreground = fl_contrast(textcolor(), background); + } else { + foreground = textcolor(); + background = color(); + } + + if (!(style & TEXT_ONLY_MASK)) { + fl_color( background ); + fl_rectf( X, Y, toX - X, mMaxsize ); + } + if (!(style & BG_ONLY_MASK)) { + fl_color( foreground ); + fl_font( font, fsize ); + fl_draw( string, nChars, X, Y + mMaxsize - fl_descent()); + } + + // CET - FIXME + /* If any space around the character remains unfilled (due to use of + different sized fonts for highlighting), fill in above or below + to erase previously drawn characters */ + /* + if (fs->ascent < mAscent) + clear_rect( style, X, Y, toX - X, mAscent - fs->ascent); + if (fs->descent < mDescent) + clear_rect( style, X, Y + mAscent + fs->descent, toX - x, + mDescent - fs->descent); + */ + /* Underline if style is secondary Fl_Text_Selection */ + + /* + if (style & SECONDARY_MASK) + XDrawLine(XtDisplay(mW), XtWindow(mW), gc, x, + y + mAscent, toX - 1, Y + fs->ascent); + */ +} + + +/* +** Clear a rectangle with the appropriate background color for "style" +*/ +void Fl_Text_Display::clear_rect( int style, int X, int Y, + int width, int height ) { + /* A width of zero means "clear to end of window" to XClearArea */ + if ( width == 0 ) + return; + + if (style & PRIMARY_MASK) { + if (Fl::focus()==this) { + fl_color(selection_color()); + } else { + fl_color(fl_color_average(color(), selection_color(), 0.4f)); + } + } else if (style & HIGHLIGHT_MASK) { + if (Fl::focus()==this) { + fl_color(fl_color_average(color(), selection_color(), 0.5f)); + } else { + fl_color(fl_color_average(color(), selection_color(), 0.6f)); + } + } else { + fl_color( color() ); + } + fl_rectf( X, Y, width, height ); +} + + +/* +** Draw a cursor with top center at X, y. +*/ +void Fl_Text_Display::draw_cursor( int X, int Y ) { + typedef struct { + int x1, y1, x2, y2; + } + Segment; + + Segment segs[ 5 ]; + int left, right, cursorWidth, midY; + // int fontWidth = mFontStruct->min_bounds.width, nSegs = 0; + int fontWidth = TMPFONTWIDTH; // CET - FIXME + int nSegs = 0; + int fontHeight = mMaxsize; + int bot = Y + fontHeight - 1; + + if ( X < text_area.x - 1 || X > text_area.x + text_area.w ) + return; + + /* For cursors other than the block, make them around 2/3 of a character + width, rounded to an even number of pixels so that X will draw an + odd number centered on the stem at x. */ + cursorWidth = 4; //(fontWidth/3) * 2; + left = X - cursorWidth / 2; + right = left + cursorWidth; + + /* Create segments and draw cursor */ + if ( mCursorStyle == CARET_CURSOR ) { + midY = bot - fontHeight / 5; + segs[ 0 ].x1 = left; segs[ 0 ].y1 = bot; segs[ 0 ].x2 = X; segs[ 0 ].y2 = midY; + segs[ 1 ].x1 = X; segs[ 1 ].y1 = midY; segs[ 1 ].x2 = right; segs[ 1 ].y2 = bot; + segs[ 2 ].x1 = left; segs[ 2 ].y1 = bot; segs[ 2 ].x2 = X; segs[ 2 ].y2 = midY - 1; + segs[ 3 ].x1 = X; segs[ 3 ].y1 = midY - 1; segs[ 3 ].x2 = right; segs[ 3 ].y2 = bot; + nSegs = 4; + } else if ( mCursorStyle == NORMAL_CURSOR ) { + segs[ 0 ].x1 = left; segs[ 0 ].y1 = Y; segs[ 0 ].x2 = right; segs[ 0 ].y2 = Y; + segs[ 1 ].x1 = X; segs[ 1 ].y1 = Y; segs[ 1 ].x2 = X; segs[ 1 ].y2 = bot; + segs[ 2 ].x1 = left; segs[ 2 ].y1 = bot; segs[ 2 ].x2 = right; segs[ 2 ].y2 = bot; + nSegs = 3; + } else if ( mCursorStyle == HEAVY_CURSOR ) { + segs[ 0 ].x1 = X - 1; segs[ 0 ].y1 = Y; segs[ 0 ].x2 = X - 1; segs[ 0 ].y2 = bot; + segs[ 1 ].x1 = X; segs[ 1 ].y1 = Y; segs[ 1 ].x2 = X; segs[ 1 ].y2 = bot; + segs[ 2 ].x1 = X + 1; segs[ 2 ].y1 = Y; segs[ 2 ].x2 = X + 1; segs[ 2 ].y2 = bot; + segs[ 3 ].x1 = left; segs[ 3 ].y1 = Y; segs[ 3 ].x2 = right; segs[ 3 ].y2 = Y; + segs[ 4 ].x1 = left; segs[ 4 ].y1 = bot; segs[ 4 ].x2 = right; segs[ 4 ].y2 = bot; + nSegs = 5; + } else if ( mCursorStyle == DIM_CURSOR ) { + midY = Y + fontHeight / 2; + segs[ 0 ].x1 = X; segs[ 0 ].y1 = Y; segs[ 0 ].x2 = X; segs[ 0 ].y2 = Y; + segs[ 1 ].x1 = X; segs[ 1 ].y1 = midY; segs[ 1 ].x2 = X; segs[ 1 ].y2 = midY; + segs[ 2 ].x1 = X; segs[ 2 ].y1 = bot; segs[ 2 ].x2 = X; segs[ 2 ].y2 = bot; + nSegs = 3; + } else if ( mCursorStyle == BLOCK_CURSOR ) { + right = X + fontWidth; + segs[ 0 ].x1 = X; segs[ 0 ].y1 = Y; segs[ 0 ].x2 = right; segs[ 0 ].y2 = Y; + segs[ 1 ].x1 = right; segs[ 1 ].y1 = Y; segs[ 1 ].x2 = right; segs[ 1 ].y2 = bot; + segs[ 2 ].x1 = right; segs[ 2 ].y1 = bot; segs[ 2 ].x2 = X; segs[ 2 ].y2 = bot; + segs[ 3 ].x1 = X; segs[ 3 ].y1 = bot; segs[ 3 ].x2 = X; segs[ 3 ].y2 = Y; + nSegs = 4; + } + fl_color( mCursor_color ); + + for ( int k = 0; k < nSegs; k++ ) { + fl_line( segs[ k ].x1, segs[ k ].y1, segs[ k ].x2, segs[ k ].y2 ); + } +} + +/* +** Determine the drawing method to use to draw a specific character from "buf". +** "lineStartPos" gives the character index where the line begins, "lineIndex", +** the number of characters past the beginning of the line, and "dispIndex", +** the number of displayed characters past the beginning of the line. Passing +** lineStartPos of -1 returns the drawing style for "no text". +** +** Why not just: position_style(pos)? Because style applies to blank areas +** of the window beyond the text boundaries, and because this routine must also +** decide whether a position is inside of a rectangular Fl_Text_Selection, and do +** so efficiently, without re-counting character positions from the start of the +** line. +** +** Note that style is a somewhat incorrect name, drawing method would +** be more appropriate. +*/ +int Fl_Text_Display::position_style( int lineStartPos, + int lineLen, int lineIndex, int dispIndex ) { + Fl_Text_Buffer * buf = mBuffer; + Fl_Text_Buffer *styleBuf = mStyleBuffer; + int pos, style = 0; + + if ( lineStartPos == -1 || buf == NULL ) + return FILL_MASK; + + pos = lineStartPos + min( lineIndex, lineLen ); + + if ( lineIndex >= lineLen ) + style = FILL_MASK; + else if ( styleBuf != NULL ) { + style = ( unsigned char ) styleBuf->character( pos ); + if (style == mUnfinishedStyle && mUnfinishedHighlightCB) { + /* encountered "unfinished" style, trigger parsing */ + (mUnfinishedHighlightCB)( pos, mHighlightCBArg); + style = (unsigned char) styleBuf->character( pos); + } + } + if (buf->primary_selection()->includes(pos, lineStartPos, dispIndex)) + style |= PRIMARY_MASK; + if (buf->highlight_selection()->includes(pos, lineStartPos, dispIndex)) + style |= HIGHLIGHT_MASK; + if (buf->secondary_selection()->includes(pos, lineStartPos, dispIndex)) + style |= SECONDARY_MASK; + return style; +} + +/* +** Find the width of a string in the font of a particular style +*/ +int Fl_Text_Display::string_width( const char *string, int length, int style ) { + Fl_Font font; + int fsize; + + if ( style & STYLE_LOOKUP_MASK ) { + int si = (style & STYLE_LOOKUP_MASK) - 'A'; + if (si < 0) si = 0; + else if (si >= mNStyles) si = mNStyles - 1; + + font = mStyleTable[si].font; + fsize = mStyleTable[si].size; + } else { + font = textfont(); + fsize = textsize(); + } + fl_font( font, fsize ); + + return ( int ) ( fl_width( string, length ) ); +} + +/* +** Translate window coordinates to the nearest (insert cursor or character +** cell) text position. The parameter posType specifies how to interpret the +** position: CURSOR_POS means translate the coordinates to the nearest cursor +** position, and CHARACTER_POS means return the position of the character +** closest to (X, Y). +*/ +int Fl_Text_Display::xy_to_position( int X, int Y, int posType ) { + int charIndex, lineStart, lineLen, fontHeight; + int charWidth, charLen, charStyle, visLineNum, xStep, outIndex; + char expandedChar[ FL_TEXT_MAX_EXP_CHAR_LEN ]; + const char *lineStr; + + /* Find the visible line number corresponding to the Y coordinate */ + fontHeight = mMaxsize; + visLineNum = ( Y - text_area.y ) / fontHeight; + if ( visLineNum < 0 ) + return mFirstChar; + if ( visLineNum >= mNVisibleLines ) + visLineNum = mNVisibleLines - 1; + + /* Find the position at the start of the line */ + lineStart = mLineStarts[ visLineNum ]; + + /* If the line start was empty, return the last position in the buffer */ + if ( lineStart == -1 ) + return mBuffer->length(); + + /* Get the line text and its length */ + lineLen = vline_length( visLineNum ); + lineStr = mBuffer->text_range( lineStart, lineStart + lineLen ); + + /* Step through character positions from the beginning of the line + to find the character position corresponding to the X coordinate */ + xStep = text_area.x - mHorizOffset; + outIndex = 0; + for ( charIndex = 0; charIndex < lineLen; charIndex++ ) { + charLen = Fl_Text_Buffer::expand_character( lineStr[ charIndex ], outIndex, expandedChar, + mBuffer->tab_distance(), mBuffer->null_substitution_character() ); + charStyle = position_style( lineStart, lineLen, charIndex, outIndex ); + charWidth = string_width( expandedChar, charLen, charStyle ); + if ( X < xStep + ( posType == CURSOR_POS ? charWidth / 2 : charWidth ) ) { + free((char *)lineStr); + return lineStart + charIndex; + } + xStep += charWidth; + outIndex += charLen; + } + + /* If the X position was beyond the end of the line, return the position + of the newline at the end of the line */ + free((char *)lineStr); + return lineStart + lineLen; +} + +/* +** Translate window coordinates to the nearest row and column number for +** positioning the cursor. This, of course, makes no sense when the font is +** proportional, since there are no absolute columns. The parameter posType +** specifies how to interpret the position: CURSOR_POS means translate the +** coordinates to the nearest position between characters, and CHARACTER_POS +** means translate the position to the nearest character cell. +*/ +void Fl_Text_Display::xy_to_rowcol( int X, int Y, int *row, + int *column, int posType ) { + int fontHeight = mMaxsize; + int fontWidth = TMPFONTWIDTH; //mFontStruct->max_bounds.width; + + /* Find the visible line number corresponding to the Y coordinate */ + *row = ( Y - text_area.y ) / fontHeight; + if ( *row < 0 ) * row = 0; + if ( *row >= mNVisibleLines ) * row = mNVisibleLines - 1; + *column = ( ( X - text_area.x ) + mHorizOffset + + ( posType == CURSOR_POS ? fontWidth / 2 : 0 ) ) / fontWidth; + if ( *column < 0 ) * column = 0; +} + +/* +** Offset the line starts array, mTopLineNum, mFirstChar and lastChar, for a new +** vertical scroll position given by newTopLineNum. If any currently displayed +** lines will still be visible, salvage the line starts values, otherwise, +** count lines from the nearest known line start (start or end of buffer, or +** the closest value in the mLineStarts array) +*/ +void Fl_Text_Display::offset_line_starts( int newTopLineNum ) { + int oldTopLineNum = mTopLineNum; + int oldFirstChar = mFirstChar; + int lineDelta = newTopLineNum - oldTopLineNum; + int nVisLines = mNVisibleLines; + int *lineStarts = mLineStarts; + int i, lastLineNum; + Fl_Text_Buffer *buf = mBuffer; + + /* If there was no offset, nothing needs to be changed */ + if ( lineDelta == 0 ) + return; + + /* Find the new value for mFirstChar by counting lines from the nearest + known line start (start or end of buffer, or the closest value in the + lineStarts array) */ + lastLineNum = oldTopLineNum + nVisLines - 1; + if ( newTopLineNum < oldTopLineNum && newTopLineNum < -lineDelta ) { + mFirstChar = skip_lines( 0, newTopLineNum - 1, true ); + } else if ( newTopLineNum < oldTopLineNum ) { + mFirstChar = rewind_lines( mFirstChar, -lineDelta ); + } else if ( newTopLineNum < lastLineNum ) { + mFirstChar = lineStarts[ newTopLineNum - oldTopLineNum ]; + } else if ( newTopLineNum - lastLineNum < mNBufferLines - newTopLineNum ) { + mFirstChar = skip_lines( lineStarts[ nVisLines - 1 ], + newTopLineNum - lastLineNum, true ); + } else { + mFirstChar = rewind_lines( buf->length(), mNBufferLines - newTopLineNum + 1 ); + } + + /* Fill in the line starts array */ + if ( lineDelta < 0 && -lineDelta < nVisLines ) { + for ( i = nVisLines - 1; i >= -lineDelta; i-- ) + lineStarts[ i ] = lineStarts[ i + lineDelta ]; + calc_line_starts( 0, -lineDelta ); + } else if ( lineDelta > 0 && lineDelta < nVisLines ) { + for ( i = 0; i < nVisLines - lineDelta; i++ ) + lineStarts[ i ] = lineStarts[ i + lineDelta ]; + calc_line_starts( nVisLines - lineDelta, nVisLines - 1 ); + } else + calc_line_starts( 0, nVisLines ); + + /* Set lastChar and mTopLineNum */ + calc_last_char(); + mTopLineNum = newTopLineNum; + + /* If we're numbering lines or being asked to maintain an absolute line + number, re-calculate the absolute line number */ + absolute_top_line_number(oldFirstChar); +} + +/* +** Update the line starts array, mTopLineNum, mFirstChar and lastChar for text +** display "textD" after a modification to the text buffer, given by the +** position where the change began "pos", and the nmubers of characters +** and lines inserted and deleted. +*/ +void Fl_Text_Display::update_line_starts( int pos, int charsInserted, + int charsDeleted, int linesInserted, int linesDeleted, int *scrolled ) { + int * lineStarts = mLineStarts; + int i, lineOfPos, lineOfEnd, nVisLines = mNVisibleLines; + int charDelta = charsInserted - charsDeleted; + int lineDelta = linesInserted - linesDeleted; + + /* If all of the changes were before the displayed text, the display + doesn't change, just update the top line num and offset the line + start entries and first and last characters */ + if ( pos + charsDeleted < mFirstChar ) { + mTopLineNum += lineDelta; + for ( i = 0; i < nVisLines && lineStarts[i] != -1; i++ ) + lineStarts[ i ] += charDelta; + mFirstChar += charDelta; + mLastChar += charDelta; + *scrolled = 0; + return; + } + + /* The change began before the beginning of the displayed text, but + part or all of the displayed text was deleted */ + if ( pos < mFirstChar ) { + /* If some text remains in the window, anchor on that */ + if ( position_to_line( pos + charsDeleted, &lineOfEnd ) && + ++lineOfEnd < nVisLines && lineStarts[ lineOfEnd ] != -1 ) { + mTopLineNum = max( 1, mTopLineNum + lineDelta ); + mFirstChar = rewind_lines( + lineStarts[ lineOfEnd ] + charDelta, lineOfEnd ); + /* Otherwise anchor on original line number and recount everything */ + } else { + if ( mTopLineNum > mNBufferLines + lineDelta ) { + mTopLineNum = 1; + mFirstChar = 0; + } else + mFirstChar = skip_lines( 0, mTopLineNum - 1, true ); + } + calc_line_starts( 0, nVisLines - 1 ); + /* calculate lastChar by finding the end of the last displayed line */ + calc_last_char(); + *scrolled = 1; + return; + } + + /* If the change was in the middle of the displayed text (it usually is), + salvage as much of the line starts array as possible by moving and + offsetting the entries after the changed area, and re-counting the + added lines or the lines beyond the salvaged part of the line starts + array */ + if ( pos <= mLastChar ) { + /* find line on which the change began */ + position_to_line( pos, &lineOfPos ); + /* salvage line starts after the changed area */ + if ( lineDelta == 0 ) { + for ( i = lineOfPos + 1; i < nVisLines && lineStarts[ i ] != -1; i++ ) + lineStarts[ i ] += charDelta; + } else if ( lineDelta > 0 ) { + for ( i = nVisLines - 1; i >= lineOfPos + lineDelta + 1; i-- ) + lineStarts[ i ] = lineStarts[ i - lineDelta ] + + ( lineStarts[ i - lineDelta ] == -1 ? 0 : charDelta ); + } else /* (lineDelta < 0) */ { + for ( i = max( 0, lineOfPos + 1 ); i < nVisLines + lineDelta; i++ ) + lineStarts[ i ] = lineStarts[ i - lineDelta ] + + ( lineStarts[ i - lineDelta ] == -1 ? 0 : charDelta ); + } + /* fill in the missing line starts */ + if ( linesInserted >= 0 ) + calc_line_starts( lineOfPos + 1, lineOfPos + linesInserted ); + if ( lineDelta < 0 ) + calc_line_starts( nVisLines + lineDelta, nVisLines ); + /* calculate lastChar by finding the end of the last displayed line */ + calc_last_char(); + *scrolled = 0; + return; + } + + /* Change was past the end of the displayed text, but displayable by virtue + of being an insert at the end of the buffer into visible blank lines */ + if ( empty_vlines() ) { + position_to_line( pos, &lineOfPos ); + calc_line_starts( lineOfPos, lineOfPos + linesInserted ); + calc_last_char(); + *scrolled = 0; + return; + } + + /* Change was beyond the end of the buffer and not visible, do nothing */ + *scrolled = 0; +} + +/* +** Scan through the text in the "textD"'s buffer and recalculate the line +** starts array values beginning at index "startLine" and continuing through +** (including) "endLine". It assumes that the line starts entry preceding +** "startLine" (or mFirstChar if startLine is 0) is good, and re-counts +** newlines to fill in the requested entries. Out of range values for +** "startLine" and "endLine" are acceptable. +*/ +void Fl_Text_Display::calc_line_starts( int startLine, int endLine ) { + int startPos, bufLen = mBuffer->length(); + int line, lineEnd, nextLineStart, nVis = mNVisibleLines; + int *lineStarts = mLineStarts; + + /* Clean up (possibly) messy input parameters */ + if ( endLine < 0 ) endLine = 0; + if ( endLine >= nVis ) endLine = nVis - 1; + if ( startLine < 0 ) startLine = 0; + if ( startLine >= nVis ) startLine = nVis - 1; + if ( startLine > endLine ) + return; + + /* Find the last known good line number -> position mapping */ + if ( startLine == 0 ) { + lineStarts[ 0 ] = mFirstChar; + startLine = 1; + } + startPos = lineStarts[ startLine - 1 ]; + + /* If the starting position is already past the end of the text, + fill in -1's (means no text on line) and return */ + if ( startPos == -1 ) { + for ( line = startLine; line <= endLine; line++ ) + lineStarts[ line ] = -1; + return; + } + + /* Loop searching for ends of lines and storing the positions of the + start of the next line in lineStarts */ + for ( line = startLine; line <= endLine; line++ ) { + find_line_end(startPos, true, &lineEnd, &nextLineStart); + startPos = nextLineStart; + if ( startPos >= bufLen ) { + /* If the buffer ends with a newline or line break, put + buf->length() in the next line start position (instead of + a -1 which is the normal marker for an empty line) to + indicate that the cursor may safely be displayed there */ + if ( line == 0 || ( lineStarts[ line - 1 ] != bufLen && + lineEnd != nextLineStart ) ) { + lineStarts[ line ] = bufLen; + line++; + } + break; + } + lineStarts[ line ] = startPos; + } + + /* Set any entries beyond the end of the text to -1 */ + for ( ; line <= endLine; line++ ) + lineStarts[ line ] = -1; +} + +/* +** Given a Fl_Text_Display with a complete, up-to-date lineStarts array, update +** the lastChar entry to point to the last buffer position displayed. +*/ +void Fl_Text_Display::calc_last_char() { + int i; + for (i = mNVisibleLines - 1; i >= 0 && mLineStarts[i] == -1; i--) ; + mLastChar = i < 0 ? 0 : line_end(mLineStarts[i], true); +} + +void Fl_Text_Display::scroll(int topLineNum, int horizOffset) { + mTopLineNumHint = topLineNum; + mHorizOffsetHint = horizOffset; + resize(x(), y(), w(), h()); +} + +void Fl_Text_Display::scroll_(int topLineNum, int horizOffset) { + /* Limit the requested scroll position to allowable values */ + if (topLineNum > mNBufferLines + 3 - mNVisibleLines) + topLineNum = mNBufferLines + 3 - mNVisibleLines; + if (topLineNum < 1) topLineNum = 1; + + if (horizOffset > longest_vline() - text_area.w) + horizOffset = longest_vline() - text_area.w; + if (horizOffset < 0) horizOffset = 0; + + /* Do nothing if scroll position hasn't actually changed or there's no + window to draw in yet */ + if (mHorizOffset == horizOffset && mTopLineNum == topLineNum) + return; + + /* If the vertical scroll position has changed, update the line + starts array and related counters in the text display */ + offset_line_starts(topLineNum); + + /* Just setting mHorizOffset is enough information for redisplay */ + mHorizOffset = horizOffset; + + // redraw all text + damage(FL_DAMAGE_EXPOSE); +} + +/* +** Update the minimum, maximum, slider size, page increment, and value +** for vertical scroll bar. +*/ +void Fl_Text_Display::update_v_scrollbar() { + /* The Vert. scroll bar value and slider size directly represent the top + line number, and the number of visible lines respectively. The scroll + bar maximum value is chosen to generally represent the size of the whole + buffer, with minor adjustments to keep the scroll bar widget happy */ +#ifdef DEBUG + printf("Fl_Text_Display::update_v_scrollbar():\n" + " mTopLineNum=%d, mNVisibleLines=%d, mNBufferLines=%d\n", + mTopLineNum, mNVisibleLines, mNBufferLines); +#endif // DEBUG + + mVScrollBar->value(mTopLineNum, mNVisibleLines, 1, mNBufferLines+2); + mVScrollBar->linesize(3); +} + +/* +** Update the minimum, maximum, slider size, page increment, and value +** for the horizontal scroll bar. +*/ +void Fl_Text_Display::update_h_scrollbar() { + int sliderMax = max(longest_vline(), text_area.w + mHorizOffset); + mHScrollBar->value( mHorizOffset, text_area.w, 0, sliderMax ); +} + +/* +** Callbacks for drag or valueChanged on scroll bars +*/ +void Fl_Text_Display::v_scrollbar_cb(Fl_Scrollbar* b, Fl_Text_Display* textD) { + if (b->value() == textD->mTopLineNum) return; + textD->scroll(b->value(), textD->mHorizOffset); +} + +void Fl_Text_Display::h_scrollbar_cb(Fl_Scrollbar* b, Fl_Text_Display* textD) { + if (b->value() == textD->mHorizOffset) return; + textD->scroll(textD->mTopLineNum, b->value()); +} + +/* +** Refresh the line number area. If clearAll is False, writes only over +** the character cell areas. Setting clearAll to True will clear out any +** stray marks outside of the character cell area, which might have been +** left from before a resize or font change. +*/ +void Fl_Text_Display::draw_line_numbers(bool /*clearAll*/) { +#if 0 + // FIXME: don't want this yet, so will leave for another time + + int y, line, visLine, nCols, lineStart; + char lineNumString[12]; + int lineHeight = mMaxsize ? mMaxsize : textsize_; + int charWidth = TMPFONTWIDTH; //mFontStruct->max_bounds.width; + + /* Don't draw if mLineNumWidth == 0 (line numbers are hidden), or widget is + not yet realized */ + if (mLineNumWidth == 0 || visible_r()) + return; + + /* GC is allocated on demand, since not everyone will use line numbering */ + if (textD->lineNumGC == NULL) { + XGCValues values; + values.foreground = textD->lineNumFGPixel; + values.background = textD->bgPixel; + values.font = textD->fontStruct->fid; + textD->lineNumGC = XtGetGC(textD->w, + GCFont| GCForeground | GCBackground, &values); + } + + /* Erase the previous contents of the line number area, if requested */ + if (clearAll) + XClearArea(XtDisplay(textD->w), XtWindow(textD->w), textD->lineNumLeft, + textD->top, textD->lineNumWidth, textD->height, False); + + /* Draw the line numbers, aligned to the text */ + nCols = min(11, textD->lineNumWidth / charWidth); + y = textD->top; + line = getAbsTopLineNum(textD); + for (visLine=0; visLine < textD->nVisibleLines; visLine++) { + lineStart = textD->lineStarts[visLine]; + if (lineStart != -1 && (lineStart==0 || + BufGetCharacter(textD->buffer, lineStart-1)=='\n')) { + sprintf(lineNumString, "%*d", nCols, line); + XDrawImageString(XtDisplay(textD->w), XtWindow(textD->w), + textD->lineNumGC, textD->lineNumLeft, y + textD->ascent, + lineNumString, strlen(lineNumString)); + line++; + } else { + XClearArea(XtDisplay(textD->w), XtWindow(textD->w), + textD->lineNumLeft, y, textD->lineNumWidth, + textD->ascent + textD->descent, False); + if (visLine == 0) + line++; + } + y += lineHeight; + } +#endif +} + +static int max( int i1, int i2 ) { + return i1 >= i2 ? i1 : i2; +} + +static int min( int i1, int i2 ) { + return i1 <= i2 ? i1 : i2; +} + +/* +** Count the number of newlines in a null-terminated text string; +*/ +static int countlines( const char *string ) { + const char * c; + int lineCount = 0; + + if (!string) return 0; + + for ( c = string; *c != '\0'; c++ ) + if ( *c == '\n' ) lineCount++; + return lineCount; +} + +/* +** Return the width in pixels of the displayed line pointed to by "visLineNum" +*/ +int Fl_Text_Display::measure_vline( int visLineNum ) { + int i, width = 0, len, style, lineLen = vline_length( visLineNum ); + int charCount = 0, lineStartPos = mLineStarts[ visLineNum ]; + char expandedChar[ FL_TEXT_MAX_EXP_CHAR_LEN ]; + + if (lineStartPos < 0 || lineLen == 0) return 0; + if ( mStyleBuffer == NULL ) { + for ( i = 0; i < lineLen; i++ ) { + len = mBuffer->expand_character( lineStartPos + i, + charCount, expandedChar ); + + fl_font( textfont(), textsize() ); + + width += ( int ) fl_width( expandedChar, len ); + + charCount += len; + } + } else { + for ( i = 0; i < lineLen; i++ ) { + len = mBuffer->expand_character( lineStartPos + i, + charCount, expandedChar ); + style = ( unsigned char ) mStyleBuffer->character( + lineStartPos + i ) - 'A'; + + if (style < 0) style = 0; + else if (style >= mNStyles) style = mNStyles - 1; + + fl_font( mStyleTable[ style ].font, mStyleTable[ style ].size ); + + width += ( int ) fl_width( expandedChar, len ); + + charCount += len; + } + } + return width; +} + +/* +** Return true if there are lines visible with no corresponding buffer text +*/ +int Fl_Text_Display::empty_vlines() { + return mNVisibleLines > 0 && + mLineStarts[ mNVisibleLines - 1 ] == -1; +} + +/* +** Return the length of a line (number of displayable characters) by examining +** entries in the line starts array rather than by scanning for newlines +*/ +int Fl_Text_Display::vline_length( int visLineNum ) { + int nextLineStart, lineStartPos; + + if (visLineNum < 0 || visLineNum >= mNVisibleLines) + return (0); + + lineStartPos = mLineStarts[ visLineNum ]; + + if ( lineStartPos == -1 ) + return 0; + if ( visLineNum + 1 >= mNVisibleLines ) + return mLastChar - lineStartPos; + nextLineStart = mLineStarts[ visLineNum + 1 ]; + if ( nextLineStart == -1 ) + return mLastChar - lineStartPos; + if (wrap_uses_character(nextLineStart-1)) + return nextLineStart-1 - lineStartPos; + return nextLineStart - lineStartPos; +} + +/* +** When continuous wrap is on, and the user inserts or deletes characters, +** wrapping can happen before and beyond the changed position. This routine +** finds the extent of the changes, and counts the deleted and inserted lines +** over that range. It also attempts to minimize the size of the range to +** what has to be counted and re-displayed, so the results can be useful +** both for delimiting where the line starts need to be recalculated, and +** for deciding what part of the text to redisplay. +*/ +void Fl_Text_Display::find_wrap_range(const char *deletedText, int pos, + int nInserted, int nDeleted, int *modRangeStart, int *modRangeEnd, + int *linesInserted, int *linesDeleted) { + int length, retPos, retLines, retLineStart, retLineEnd; + Fl_Text_Buffer *deletedTextBuf, *buf = buffer(); + int nVisLines = mNVisibleLines; + int *lineStarts = mLineStarts; + int countFrom, countTo, lineStart, adjLineStart, i; + int visLineNum = 0, nLines = 0; + + /* + ** Determine where to begin searching: either the previous newline, or + ** if possible, limit to the start of the (original) previous displayed + ** line, using information from the existing line starts array + */ + if (pos >= mFirstChar && pos <= mLastChar) { + for (i=nVisLines-1; i>0; i--) + if (lineStarts[i] != -1 && pos >= lineStarts[i]) + break; + if (i > 0) { + countFrom = lineStarts[i-1]; + visLineNum = i-1; + } else + countFrom = buf->line_start(pos); + } else + countFrom = buf->line_start(pos); + + + /* + ** Move forward through the (new) text one line at a time, counting + ** displayed lines, and looking for either a real newline, or for the + ** line starts to re-sync with the original line starts array + */ + lineStart = countFrom; + *modRangeStart = countFrom; + for (;;) { + + /* advance to the next line. If the line ended in a real newline + or the end of the buffer, that's far enough */ + wrapped_line_counter(buf, lineStart, buf->length(), 1, true, 0, + &retPos, &retLines, &retLineStart, &retLineEnd); + if (retPos >= buf->length()) { + countTo = buf->length(); + *modRangeEnd = countTo; + if (retPos != retLineEnd) + nLines++; + break; + } else + lineStart = retPos; + nLines++; + if (lineStart > pos + nInserted && + buf->character(lineStart-1) == '\n') { + countTo = lineStart; + *modRangeEnd = lineStart; + break; + } + + /* Don't try to resync in continuous wrap mode with non-fixed font + sizes; it would result in a chicken-and-egg dependency between + the calculations for the inserted and the deleted lines. + If we're in that mode, the number of deleted lines is calculated in + advance, without resynchronization, so we shouldn't resynchronize + for the inserted lines either. */ + if (mSuppressResync) + continue; + + /* check for synchronization with the original line starts array + before pos, if so, the modified range can begin later */ + if (lineStart <= pos) { + while (visLineNum pos + nInserted) { + adjLineStart = lineStart - nInserted + nDeleted; + while (visLineNumcopy(buffer(), countFrom, pos, 0); + if (nDeleted != 0) + deletedTextBuf->insert(pos-countFrom, deletedText); + deletedTextBuf->copy(buffer(), + pos+nInserted, countTo, pos-countFrom+nDeleted); + /* Note that we need to take into account an offset for the style buffer: + the deletedTextBuf can be out of sync with the style buffer. */ + wrapped_line_counter(deletedTextBuf, 0, length, INT_MAX, true, + countFrom, &retPos, &retLines, &retLineStart, &retLineEnd, false); + delete deletedTextBuf; + *linesDeleted = retLines; + mSuppressResync = 0; +} + +/* +** This is a stripped-down version of the findWrapRange() function above, +** intended to be used to calculate the number of "deleted" lines during +** a buffer modification. It is called _before_ the modification takes place. +** +** This function should only be called in continuous wrap mode with a +** non-fixed font width. In that case, it is impossible to calculate +** the number of deleted lines, because the necessary style information +** is no longer available _after_ the modification. In other cases, we +** can still perform the calculation afterwards (possibly even more +** efficiently). +*/ +void Fl_Text_Display::measure_deleted_lines(int pos, int nDeleted) { + int retPos, retLines, retLineStart, retLineEnd; + Fl_Text_Buffer *buf = buffer(); + int nVisLines = mNVisibleLines; + int *lineStarts = mLineStarts; + int countFrom, lineStart; + int nLines = 0, i; + /* + ** Determine where to begin searching: either the previous newline, or + ** if possible, limit to the start of the (original) previous displayed + ** line, using information from the existing line starts array + */ + if (pos >= mFirstChar && pos <= mLastChar) { + for (i=nVisLines-1; i>0; i--) + if (lineStarts[i] != -1 && pos >= lineStarts[i]) + break; + if (i > 0) countFrom = lineStarts[i-1]; + else countFrom = buf->line_start(pos); + } else + countFrom = buf->line_start(pos); + + /* + ** Move forward through the (new) text one line at a time, counting + ** displayed lines, and looking for either a real newline, or for the + ** line starts to re-sync with the original line starts array + */ + lineStart = countFrom; + for (;;) { + /* advance to the next line. If the line ended in a real newline + or the end of the buffer, that's far enough */ + wrapped_line_counter(buf, lineStart, buf->length(), 1, true, 0, + &retPos, &retLines, &retLineStart, &retLineEnd); + if (retPos >= buf->length()) { + if (retPos != retLineEnd) + nLines++; + break; + } else + lineStart = retPos; + nLines++; + if (lineStart > pos + nDeleted && + buf->character(lineStart-1) == '\n') { + break; + } + + /* Unlike in the findWrapRange() function above, we don't try to + resync with the line starts, because we don't know the length + of the inserted text yet, nor the updated style information. + + Because of that, we also shouldn't resync with the line starts + after the modification either, because we must perform the + calculations for the deleted and inserted lines in the same way. + + This can result in some unnecessary recalculation and redrawing + overhead, and therefore we should only use this two-phase mode + of calculation when it's really needed (continuous wrap + variable + font width). */ + } + mNLinesDeleted = nLines; + mSuppressResync = 1; +} + +/* +** Count forward from startPos to either maxPos or maxLines (whichever is +** reached first), and return all relevant positions and line count. +** The provided textBuffer may differ from the actual text buffer of the +** widget. In that case it must be a (partial) copy of the actual text buffer +** and the styleBufOffset argument must indicate the starting position of the +** copy, to take into account the correct style information. +** +** Returned values: +** +** retPos: Position where counting ended. When counting lines, the +** position returned is the start of the line "maxLines" +** lines beyond "startPos". +** retLines: Number of line breaks counted +** retLineStart: Start of the line where counting ended +** retLineEnd: End position of the last line traversed +*/ +void Fl_Text_Display::wrapped_line_counter(Fl_Text_Buffer *buf, int startPos, + int maxPos, int maxLines, bool startPosIsLineStart, int styleBufOffset, + int *retPos, int *retLines, int *retLineStart, int *retLineEnd, + bool countLastLineMissingNewLine) { + int lineStart, newLineStart = 0, b, p, colNum, wrapMargin; + int maxWidth, i, foundBreak, width; + bool countPixels; + int nLines = 0, tabDist = buffer()->tab_distance(); + unsigned char c; + char nullSubsChar = buffer()->null_substitution_character(); + + /* If the font is fixed, or there's a wrap margin set, it's more efficient + to measure in columns, than to count pixels. Determine if we can count + in columns (countPixels == False) or must count pixels (countPixels == + True), and set the wrap target for either pixels or columns */ + if (mFixedFontWidth != -1 || mWrapMargin != 0) { + countPixels = false; + wrapMargin = mWrapMargin ? mWrapMargin : text_area.w / (mFixedFontWidth + 1); + maxWidth = INT_MAX; + } else { + countPixels = true; + wrapMargin = INT_MAX; + maxWidth = text_area.w; + } + + /* Find the start of the line if the start pos is not marked as a + line start. */ + if (startPosIsLineStart) + lineStart = startPos; + else + lineStart = line_start(startPos); + + /* + ** Loop until position exceeds maxPos or line count exceeds maxLines. + ** (actually, contines beyond maxPos to end of line containing maxPos, + ** in case later characters cause a word wrap back before maxPos) + */ + colNum = 0; + width = 0; + for (p=lineStart; plength(); p++) { + c = (unsigned char)buf->character(p); + + /* If the character was a newline, count the line and start over, + otherwise, add it to the width and column counts */ + if (c == '\n') { + if (p >= maxPos) { + *retPos = maxPos; + *retLines = nLines; + *retLineStart = lineStart; + *retLineEnd = maxPos; + return; + } + nLines++; + if (nLines >= maxLines) { + *retPos = p + 1; + *retLines = nLines; + *retLineStart = p + 1; + *retLineEnd = p; + return; + } + lineStart = p + 1; + colNum = 0; + width = 0; + } else { + colNum += Fl_Text_Buffer::character_width(c, colNum, tabDist, nullSubsChar); + if (countPixels) + width += measure_proportional_character(c, colNum, p+styleBufOffset); + } + + /* If character exceeded wrap margin, find the break point + and wrap there */ + if (colNum > wrapMargin || width > maxWidth) { + foundBreak = false; + for (b=p; b>=lineStart; b--) { + c = (unsigned char)buf->character(b); + if (c == '\t' || c == ' ') { + newLineStart = b + 1; + if (countPixels) { + colNum = 0; + width = 0; + for (i=b+1; icharacter(i), colNum, + i+styleBufOffset); + colNum++; + } + } else + colNum = buf->count_displayed_characters(b+1, p+1); + foundBreak = true; + break; + } + } + if (!foundBreak) { /* no whitespace, just break at margin */ + newLineStart = max(p, lineStart+1); + colNum = Fl_Text_Buffer::character_width(c, colNum, tabDist, nullSubsChar); + if (countPixels) + width = measure_proportional_character(c, colNum, p+styleBufOffset); + } + if (p >= maxPos) { + *retPos = maxPos; + *retLines = maxPos < newLineStart ? nLines : nLines + 1; + *retLineStart = maxPos < newLineStart ? lineStart : + newLineStart; + *retLineEnd = maxPos; + return; + } + nLines++; + if (nLines >= maxLines) { + *retPos = foundBreak ? b + 1 : max(p, lineStart+1); + *retLines = nLines; + *retLineStart = lineStart; + *retLineEnd = foundBreak ? b : p; + return; + } + lineStart = newLineStart; + } + } + + /* reached end of buffer before reaching pos or line target */ + *retPos = buf->length(); + *retLines = nLines; + if (countLastLineMissingNewLine && colNum > 0) + ++(*retLines); + *retLineStart = lineStart; + *retLineEnd = buf->length(); +} + +/* +** Measure the width in pixels of a character "c" at a particular column +** "colNum" and buffer position "pos". This is for measuring characters in +** proportional or mixed-width highlighting fonts. +** +** A note about proportional and mixed-width fonts: the mixed width and +** proportional font code in nedit does not get much use in general editing, +** because nedit doesn't allow per-language-mode fonts, and editing programs +** in a proportional font is usually a bad idea, so very few users would +** choose a proportional font as a default. There are still probably mixed- +** width syntax highlighting cases where things don't redraw properly for +** insertion/deletion, though static display and wrapping and resizing +** should now be solid because they are now used for online help display. +*/ +int Fl_Text_Display::measure_proportional_character(char c, int colNum, int pos) { + int charLen, style; + char expChar[ FL_TEXT_MAX_EXP_CHAR_LEN ]; + Fl_Text_Buffer *styleBuf = mStyleBuffer; + + charLen = Fl_Text_Buffer::expand_character(c, colNum, expChar, + buffer()->tab_distance(), buffer()->null_substitution_character()); + if (styleBuf == 0) { + style = 0; + } else { + style = (unsigned char)styleBuf->character(pos); + if (style == mUnfinishedStyle && mUnfinishedHighlightCB) { + /* encountered "unfinished" style, trigger parsing */ + (mUnfinishedHighlightCB)(pos, mHighlightCBArg); + style = (unsigned char)styleBuf->character(pos); + } + } + return string_width(expChar, charLen, style); +} + +/* +** Finds both the end of the current line and the start of the next line. Why? +** In continuous wrap mode, if you need to know both, figuring out one from the +** other can be expensive or error prone. The problem comes when there's a +** trailing space or tab just before the end of the buffer. To translate an +** end of line value to or from the next lines start value, you need to know +** whether the trailing space or tab is being used as a line break or just a +** normal character, and to find that out would otherwise require counting all +** the way back to the beginning of the line. +*/ +void Fl_Text_Display::find_line_end(int startPos, bool startPosIsLineStart, + int *lineEnd, int *nextLineStart) { + int retLines, retLineStart; + + /* if we're not wrapping use more efficient BufEndOfLine */ + if (!mContinuousWrap) { + *lineEnd = buffer()->line_end(startPos); + *nextLineStart = min(buffer()->length(), *lineEnd + 1); + return; + } + + /* use the wrapped line counter routine to count forward one line */ + wrapped_line_counter(buffer(), startPos, buffer()->length(), + 1, startPosIsLineStart, 0, nextLineStart, &retLines, + &retLineStart, lineEnd); + return; +} + +/* +** Line breaks in continuous wrap mode usually happen at newlines or +** whitespace. This line-terminating character is not included in line +** width measurements and has a special status as a non-visible character. +** However, lines with no whitespace are wrapped without the benefit of a +** line terminating character, and this distinction causes endless trouble +** with all of the text display code which was originally written without +** continuous wrap mode and always expects to wrap at a newline character. +** +** Given the position of the end of the line, as returned by TextDEndOfLine +** or BufEndOfLine, this returns true if there is a line terminating +** character, and false if there's not. On the last character in the +** buffer, this function can't tell for certain whether a trailing space was +** used as a wrap point, and just guesses that it wasn't. So if an exact +** accounting is necessary, don't use this function. +*/ +int Fl_Text_Display::wrap_uses_character(int lineEndPos) { + char c; + + if (!mContinuousWrap || lineEndPos == buffer()->length()) + return 1; + + c = buffer()->character(lineEndPos); + return c == '\n' || ((c == '\t' || c == ' ') && + lineEndPos + 1 != buffer()->length()); +} + +/* +** Return true if the selection "sel" is rectangular, and touches a +** buffer position withing "rangeStart" to "rangeEnd" +*/ +int Fl_Text_Display::range_touches_selection(Fl_Text_Selection *sel, + int rangeStart, int rangeEnd) { + return sel->selected() && sel->rectangular() && sel->end() >= rangeStart && + sel->start() <= rangeEnd; +} + +/* +** Extend the range of a redraw request (from *start to *end) with additional +** redraw requests resulting from changes to the attached style buffer (which +** contains auxiliary information for coloring or styling text). +*/ +void Fl_Text_Display::extend_range_for_styles( int *startpos, int *endpos ) { + Fl_Text_Selection * sel = mStyleBuffer->primary_selection(); + int extended = 0; + + /* The peculiar protocol used here is that modifications to the style + buffer are marked by selecting them with the buffer's primary Fl_Text_Selection. + The style buffer is usually modified in response to a modify callback on + the text buffer BEFORE Fl_Text_Display.c's modify callback, so that it can keep + the style buffer in step with the text buffer. The style-update + callback can't just call for a redraw, because Fl_Text_Display hasn't processed + the original text changes yet. Anyhow, to minimize redrawing and to + avoid the complexity of scheduling redraws later, this simple protocol + tells the text display's buffer modify callback to extend it's redraw + range to show the text color/and font changes as well. */ + if ( sel->selected() ) { + if ( sel->start() < *startpos ) { + *startpos = sel->start(); + extended = 1; + } + if ( sel->end() > *endpos ) { + *endpos = sel->end(); + extended = 1; + } + } + + /* If the Fl_Text_Selection was extended due to a style change, and some of the + fonts don't match in spacing, extend redraw area to end of line to + redraw characters exposed by possible font size changes */ + if ( mFixedFontWidth == -1 && extended ) + *endpos = mBuffer->line_end( *endpos ) + 1; +} + +// The draw() method. It tries to minimize what is draw as much as possible. +void Fl_Text_Display::draw(void) { + // don't even try if there is no associated text buffer! + if (!buffer()) { draw_box(); return; } + + fl_push_clip(x(),y(),w(),h()); // prevent drawing outside widget area + + // draw the non-text, non-scrollbar areas. + if (damage() & FL_DAMAGE_ALL) { +// printf("drawing all (box = %d)\n", box()); + // draw the box() + int W = w(), H = h(); + draw_box(box(), x(), y(), W, H, color()); + + if (mHScrollBar->visible()) + W -= scrollbar_width(); + if (mVScrollBar->visible()) + H -= scrollbar_width(); + + // left margin + fl_rectf(text_area.x-LEFT_MARGIN, text_area.y-TOP_MARGIN, + LEFT_MARGIN, text_area.h+TOP_MARGIN+BOTTOM_MARGIN, + color()); + + // right margin + fl_rectf(text_area.x+text_area.w, text_area.y-TOP_MARGIN, + RIGHT_MARGIN, text_area.h+TOP_MARGIN+BOTTOM_MARGIN, + color()); + + // top margin + fl_rectf(text_area.x, text_area.y-TOP_MARGIN, + text_area.w, TOP_MARGIN, color()); + + // bottom margin + fl_rectf(text_area.x, text_area.y+text_area.h, + text_area.w, BOTTOM_MARGIN, color()); + + // draw that little box in the corner of the scrollbars + if (mVScrollBar->visible() && mHScrollBar->visible()) + fl_rectf(mVScrollBar->x(), mHScrollBar->y(), + mVScrollBar->w(), mHScrollBar->h(), + FL_GRAY); + + // blank the previous cursor protrusions + } + else if (damage() & (FL_DAMAGE_SCROLL | FL_DAMAGE_EXPOSE)) { +// printf("blanking previous cursor extrusions at Y: %d\n", mCursorOldY); + // CET - FIXME - save old cursor position instead and just draw side needed? + fl_push_clip(text_area.x-LEFT_MARGIN, + text_area.y, + text_area.w+LEFT_MARGIN+RIGHT_MARGIN, + text_area.h); + fl_rectf(text_area.x-LEFT_MARGIN, mCursorOldY, + LEFT_MARGIN, mMaxsize, color()); + fl_rectf(text_area.x+text_area.w, mCursorOldY, + RIGHT_MARGIN, mMaxsize, color()); + fl_pop_clip(); + } + + // draw the scrollbars + if (damage() & (FL_DAMAGE_ALL | FL_DAMAGE_CHILD)) { + mVScrollBar->damage(FL_DAMAGE_ALL); + mHScrollBar->damage(FL_DAMAGE_ALL); + } + update_child(*mVScrollBar); + update_child(*mHScrollBar); + + // draw all of the text + if (damage() & (FL_DAMAGE_ALL | FL_DAMAGE_EXPOSE)) { + //printf("drawing all text\n"); + int X, Y, W, H; + if (fl_clip_box(text_area.x, text_area.y, text_area.w, text_area.h, + X, Y, W, H)) { + // Draw text using the intersected clipping box... + // (this sets the clipping internally) + draw_text(X, Y, W, H); + } else { + // Draw the whole area... + draw_text(text_area.x, text_area.y, text_area.w, text_area.h); + } + } + else if (damage() & FL_DAMAGE_SCROLL) { + // draw some lines of text + fl_push_clip(text_area.x, text_area.y, + text_area.w, text_area.h); + //printf("drawing text from %d to %d\n", damage_range1_start, damage_range1_end); + draw_range(damage_range1_start, damage_range1_end); + if (damage_range2_end != -1) { + //printf("drawing text from %d to %d\n", damage_range2_start, damage_range2_end); + draw_range(damage_range2_start, damage_range2_end); + } + damage_range1_start = damage_range1_end = -1; + damage_range2_start = damage_range2_end = -1; + fl_pop_clip(); + } + + // draw the text cursor + if (damage() & (FL_DAMAGE_ALL | FL_DAMAGE_SCROLL | FL_DAMAGE_EXPOSE) + && !buffer()->primary_selection()->selected() && + mCursorOn && Fl::focus() == this ) { + fl_push_clip(text_area.x-LEFT_MARGIN, + text_area.y, + text_area.w+LEFT_MARGIN+RIGHT_MARGIN, + text_area.h); + + int X, Y; + if (position_to_xy(mCursorPos, &X, &Y)) draw_cursor(X, Y); +// else puts("position_to_xy() failed - unable to draw cursor!"); + //printf("drew cursor at pos: %d (%d,%d)\n", mCursorPos, X, Y); + mCursorOldY = Y; + fl_pop_clip(); + } + fl_pop_clip(); +} + +// this processes drag events due to mouse for Fl_Text_Display and +// also drags due to cursor movement with shift held down for +// Fl_Text_Editor +void fl_text_drag_me(int pos, Fl_Text_Display* d) { + if (d->dragType == Fl_Text_Display::DRAG_CHAR) { + if (pos >= d->dragPos) { + d->buffer()->select(d->dragPos, pos); + } else { + d->buffer()->select(pos, d->dragPos); + } + d->insert_position(pos); + } else if (d->dragType == Fl_Text_Display::DRAG_WORD) { + if (pos >= d->dragPos) { + d->insert_position(d->word_end(pos)); + d->buffer()->select(d->word_start(d->dragPos), d->word_end(pos)); + } else { + d->insert_position(d->word_start(pos)); + d->buffer()->select(d->word_start(pos), d->word_end(d->dragPos)); + } + } else if (d->dragType == Fl_Text_Display::DRAG_LINE) { + if (pos >= d->dragPos) { + d->insert_position(d->buffer()->line_end(pos)+1); + d->buffer()->select(d->buffer()->line_start(d->dragPos), + d->buffer()->line_end(pos)+1); + } else { + d->insert_position(d->buffer()->line_start(pos)); + d->buffer()->select(d->buffer()->line_start(pos), + d->buffer()->line_end(d->dragPos)+1); + } + } +} + +// This timer event scrolls the text view proportionally to +// how far the mouse pointer has left the text area. This +// allows for smooth scrolling without "wiggeling" the mouse. +void Fl_Text_Display::scroll_timer_cb(void *user_data) { + Fl_Text_Display *w = (Fl_Text_Display*)user_data; + int pos; + switch (scroll_direction) { + case 1: // mouse is to the right, scroll left + w->scroll(w->mTopLineNum, w->mHorizOffset + scroll_amount); + pos = w->xy_to_position(w->text_area.x + w->text_area.w, scroll_y, CURSOR_POS); + break; + case 2: // mouse is to the left, scroll right + w->scroll(w->mTopLineNum, w->mHorizOffset + scroll_amount); + pos = w->xy_to_position(w->text_area.x, scroll_y, CURSOR_POS); + break; + case 3: // mouse is above, scroll down + w->scroll(w->mTopLineNum + scroll_amount, w->mHorizOffset); + pos = w->xy_to_position(scroll_x, w->text_area.y, CURSOR_POS); + break; + case 4: // mouse is below, scroll up + w->scroll(w->mTopLineNum + scroll_amount, w->mHorizOffset); + pos = w->xy_to_position(scroll_x, w->text_area.y + w->text_area.h, CURSOR_POS); + break; + default: + return; + } + fl_text_drag_me(pos, w); + Fl::repeat_timeout(.1, scroll_timer_cb, user_data); +} + + +int Fl_Text_Display::handle(int event) { + if (!buffer()) return 0; + // This isn't very elegant! + if (!Fl::event_inside(text_area.x, text_area.y, text_area.w, text_area.h) && + !dragging && event != FL_LEAVE && event != FL_ENTER && + event != FL_MOVE && event != FL_FOCUS && event != FL_UNFOCUS && + event != FL_KEYBOARD && event != FL_KEYUP) { + return Fl_Group::handle(event); + } + + switch (event) { + case FL_ENTER: + case FL_MOVE: + if (active_r()) { + if (Fl::event_inside(text_area.x, text_area.y, text_area.w, + text_area.h)) window()->cursor(FL_CURSOR_INSERT); + else window()->cursor(FL_CURSOR_DEFAULT); + return 1; + } else { + return 0; + } + + case FL_LEAVE: + case FL_HIDE: + if (active_r() && window()) { + window()->cursor(FL_CURSOR_DEFAULT); + + return 1; + } else { + return 0; + } + + case FL_PUSH: { + if (active_r() && window()) { + if (Fl::event_inside(text_area.x, text_area.y, text_area.w, + text_area.h)) window()->cursor(FL_CURSOR_INSERT); + else window()->cursor(FL_CURSOR_DEFAULT); + } + + if (Fl::focus() != this) { + Fl::focus(this); + handle(FL_FOCUS); + } + if (Fl_Group::handle(event)) return 1; + if (Fl::event_state()&FL_SHIFT) return handle(FL_DRAG); + dragging = 1; + int pos = xy_to_position(Fl::event_x(), Fl::event_y(), CURSOR_POS); + dragType = Fl::event_clicks(); + dragPos = pos; + if (dragType == DRAG_CHAR) + buffer()->unselect(); + else if (dragType == DRAG_WORD) + buffer()->select(word_start(pos), word_end(pos)); + else if (dragType == DRAG_LINE) + buffer()->select(buffer()->line_start(pos), buffer()->line_end(pos)+1); + + if (buffer()->primary_selection()->selected()) + insert_position(buffer()->primary_selection()->end()); + else + insert_position(pos); + show_insert_position(); + return 1; + } + + case FL_DRAG: { + if (dragType < 0) return 1; + int X = Fl::event_x(), Y = Fl::event_y(), pos; + // if we leave the text_area, we start a timer event + // that will take care of scrolling and selecting + if (Y < text_area.y) { + scroll_x = X; + scroll_amount = (Y - text_area.y) / 5 - 1; + if (!scroll_direction) { + Fl::add_timeout(.01, scroll_timer_cb, this); + } + scroll_direction = 3; + } else if (Y >= text_area.y+text_area.h) { + scroll_x = X; + scroll_amount = (Y - text_area.y - text_area.h) / 5 + 1; + if (!scroll_direction) { + Fl::add_timeout(.01, scroll_timer_cb, this); + } + scroll_direction = 4; + } else if (X < text_area.x) { + scroll_y = Y; + scroll_amount = (X - text_area.x) / 2 - 1; + if (!scroll_direction) { + Fl::add_timeout(.01, scroll_timer_cb, this); + } + scroll_direction = 2; + } else if (X >= text_area.x+text_area.w) { + scroll_y = Y; + scroll_amount = (X - text_area.x - text_area.w) / 2 + 1; + if (!scroll_direction) { + Fl::add_timeout(.01, scroll_timer_cb, this); + } + scroll_direction = 1; + } else { + if (scroll_direction) { + Fl::remove_timeout(scroll_timer_cb, this); + scroll_direction = 0; + } + pos = xy_to_position(X, Y, CURSOR_POS); + fl_text_drag_me(pos, this); + } + return 1; + } + + case FL_RELEASE: { + dragging = 0; + if (scroll_direction) { + Fl::remove_timeout(scroll_timer_cb, this); + scroll_direction = 0; + } + + // convert from WORD or LINE selection to CHAR + if (insert_position() >= dragPos) + dragPos = buffer()->primary_selection()->start(); + else + dragPos = buffer()->primary_selection()->end(); + dragType = DRAG_CHAR; + + const char* copy = buffer()->selection_text(); + if (*copy) Fl::copy(copy, strlen(copy), 0); + free((void*)copy); + return 1; + } + + case FL_MOUSEWHEEL: + if (Fl::event_dy()) return mVScrollBar->handle(event); + else return mHScrollBar->handle(event); + + case FL_UNFOCUS: + if (active_r() && window()) window()->cursor(FL_CURSOR_DEFAULT); + case FL_FOCUS: + if (buffer()->selected()) { + int start, end; + if (buffer()->selection_position(&start, &end)) + redisplay_range(start, end); + } + if (buffer()->secondary_selected()) { + int start, end; + if (buffer()->secondary_selection_position(&start, &end)) + redisplay_range(start, end); + } + if (buffer()->highlight()) { + int start, end; + if (buffer()->highlight_position(&start, &end)) + redisplay_range(start, end); + } + return 1; + + case FL_KEYBOARD: + // Copy? + if ((Fl::event_state()&(FL_CTRL|FL_COMMAND)) && Fl::event_key()=='c') { + if (!buffer()->selected()) return 1; + const char *copy = buffer()->selection_text(); + if (*copy) Fl::copy(copy, strlen(copy), 1); + free((void*)copy); + return 1; + } + + // Select all ? + if ((Fl::event_state()&(FL_CTRL|FL_COMMAND)) && Fl::event_key()=='a') { + buffer()->select(0,buffer()->length()); + return 1; + } + + if (mVScrollBar->handle(event)) return 1; + if (mHScrollBar->handle(event)) return 1; + + break; + } + + return 0; +} + + +// +// End of "$Id: Fl_Text_Display.cxx 6105 2008-04-21 21:03:22Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Text_Editor.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Text_Editor.cxx new file mode 100644 index 000000000..b8cbfc678 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Text_Editor.cxx @@ -0,0 +1,492 @@ +// +// "$Id: Fl_Text_Editor.cxx 5671 2007-02-08 07:58:47Z matt $" +// +// Copyright 2001-2006 by Bill Spitzak and others. +// Original code Copyright Mark Edel. Permission to distribute under +// the LGPL for the FLTK library granted by Mark Edel. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include "flstring.h" +#include +#include +#include +#include +#include + + +Fl_Text_Editor::Fl_Text_Editor(int X, int Y, int W, int H, const char* l) + : Fl_Text_Display(X, Y, W, H, l) { + mCursorOn = 1; + insert_mode_ = 1; + key_bindings = 0; + + // handle the default key bindings + add_default_key_bindings(&key_bindings); + + // handle everything else + default_key_function(kf_default); +} + +Fl_Text_Editor::Key_Binding* Fl_Text_Editor::global_key_bindings = 0; + +// These are the default key bindings every widget should start with +static struct { + int key; + int state; + Fl_Text_Editor::Key_Func func; +} default_key_bindings[] = { + { FL_Escape, FL_TEXT_EDITOR_ANY_STATE, Fl_Text_Editor::kf_ignore }, + { FL_Enter, FL_TEXT_EDITOR_ANY_STATE, Fl_Text_Editor::kf_enter }, + { FL_KP_Enter, FL_TEXT_EDITOR_ANY_STATE, Fl_Text_Editor::kf_enter }, + { FL_BackSpace, FL_TEXT_EDITOR_ANY_STATE, Fl_Text_Editor::kf_backspace }, + { FL_Insert, FL_TEXT_EDITOR_ANY_STATE, Fl_Text_Editor::kf_insert }, + { FL_Delete, FL_TEXT_EDITOR_ANY_STATE, Fl_Text_Editor::kf_delete }, + { FL_Home, 0, Fl_Text_Editor::kf_move }, + { FL_End, 0, Fl_Text_Editor::kf_move }, + { FL_Left, 0, Fl_Text_Editor::kf_move }, + { FL_Up, 0, Fl_Text_Editor::kf_move }, + { FL_Right, 0, Fl_Text_Editor::kf_move }, + { FL_Down, 0, Fl_Text_Editor::kf_move }, + { FL_Page_Up, 0, Fl_Text_Editor::kf_move }, + { FL_Page_Down, 0, Fl_Text_Editor::kf_move }, + { FL_Home, FL_SHIFT, Fl_Text_Editor::kf_shift_move }, + { FL_End, FL_SHIFT, Fl_Text_Editor::kf_shift_move }, + { FL_Left, FL_SHIFT, Fl_Text_Editor::kf_shift_move }, + { FL_Up, FL_SHIFT, Fl_Text_Editor::kf_shift_move }, + { FL_Right, FL_SHIFT, Fl_Text_Editor::kf_shift_move }, + { FL_Down, FL_SHIFT, Fl_Text_Editor::kf_shift_move }, + { FL_Page_Up, FL_SHIFT, Fl_Text_Editor::kf_shift_move }, + { FL_Page_Down, FL_SHIFT, Fl_Text_Editor::kf_shift_move }, + { FL_Home, FL_CTRL, Fl_Text_Editor::kf_ctrl_move }, + { FL_End, FL_CTRL, Fl_Text_Editor::kf_ctrl_move }, + { FL_Left, FL_CTRL, Fl_Text_Editor::kf_ctrl_move }, + { FL_Up, FL_CTRL, Fl_Text_Editor::kf_ctrl_move }, + { FL_Right, FL_CTRL, Fl_Text_Editor::kf_ctrl_move }, + { FL_Down, FL_CTRL, Fl_Text_Editor::kf_ctrl_move }, + { FL_Page_Up, FL_CTRL, Fl_Text_Editor::kf_ctrl_move }, + { FL_Page_Down, FL_CTRL, Fl_Text_Editor::kf_ctrl_move }, + { FL_Home, FL_CTRL|FL_SHIFT, Fl_Text_Editor::kf_c_s_move }, + { FL_End, FL_CTRL|FL_SHIFT, Fl_Text_Editor::kf_c_s_move }, + { FL_Left, FL_CTRL|FL_SHIFT, Fl_Text_Editor::kf_c_s_move }, + { FL_Up, FL_CTRL|FL_SHIFT, Fl_Text_Editor::kf_c_s_move }, + { FL_Right, FL_CTRL|FL_SHIFT, Fl_Text_Editor::kf_c_s_move }, + { FL_Down, FL_CTRL|FL_SHIFT, Fl_Text_Editor::kf_c_s_move }, + { FL_Page_Up, FL_CTRL|FL_SHIFT, Fl_Text_Editor::kf_c_s_move }, + { FL_Page_Down, FL_CTRL|FL_SHIFT, Fl_Text_Editor::kf_c_s_move }, +//{ FL_Clear, 0, Fl_Text_Editor::delete_to_eol }, + { 'z', FL_CTRL, Fl_Text_Editor::kf_undo }, + { '/', FL_CTRL, Fl_Text_Editor::kf_undo }, + { 'x', FL_CTRL, Fl_Text_Editor::kf_cut }, + { FL_Delete, FL_SHIFT, Fl_Text_Editor::kf_cut }, + { 'c', FL_CTRL, Fl_Text_Editor::kf_copy }, + { FL_Insert, FL_CTRL, Fl_Text_Editor::kf_copy }, + { 'v', FL_CTRL, Fl_Text_Editor::kf_paste }, + { FL_Insert, FL_SHIFT, Fl_Text_Editor::kf_paste }, + { 'a', FL_CTRL, Fl_Text_Editor::kf_select_all }, + +#ifdef __APPLE__ + // Define CMD+key accelerators... + { 'z', FL_COMMAND, Fl_Text_Editor::kf_undo }, + { 'x', FL_COMMAND, Fl_Text_Editor::kf_cut }, + { 'c', FL_COMMAND, Fl_Text_Editor::kf_copy }, + { 'v', FL_COMMAND, Fl_Text_Editor::kf_paste }, + { 'a', FL_COMMAND, Fl_Text_Editor::kf_select_all }, +#endif // __APPLE__ + + { 0, 0, 0 } +}; + +void Fl_Text_Editor::add_default_key_bindings(Key_Binding** list) { + for (int i = 0; default_key_bindings[i].key; i++) { + add_key_binding(default_key_bindings[i].key, + default_key_bindings[i].state, + default_key_bindings[i].func, + list); + } +} + +Fl_Text_Editor::Key_Func +Fl_Text_Editor::bound_key_function(int key, int state, Key_Binding* list) { + Key_Binding* cur; + for (cur = list; cur; cur = cur->next) + if (cur->key == key) + if (cur->state == FL_TEXT_EDITOR_ANY_STATE || cur->state == state) + break; + if (!cur) return 0; + return cur->function; +} + +void +Fl_Text_Editor::remove_all_key_bindings(Key_Binding** list) { + Key_Binding *cur, *next; + for (cur = *list; cur; cur = next) { + next = cur->next; + delete cur; + } + *list = 0; +} + +void +Fl_Text_Editor::remove_key_binding(int key, int state, Key_Binding** list) { + Key_Binding *cur, *last = 0; + for (cur = *list; cur; last = cur, cur = cur->next) + if (cur->key == key && cur->state == state) break; + if (!cur) return; + if (last) last->next = cur->next; + else *list = cur->next; + delete cur; +} + +void +Fl_Text_Editor::add_key_binding(int key, int state, Key_Func function, + Key_Binding** list) { + Key_Binding* kb = new Key_Binding; + kb->key = key; + kb->state = state; + kb->function = function; + kb->next = *list; + *list = kb; +} + +//////////////////////////////////////////////////////////////// + +#define NORMAL_INPUT_MOVE 0 + +static void kill_selection(Fl_Text_Editor* e) { + if (e->buffer()->selected()) { + e->insert_position(e->buffer()->primary_selection()->start()); + e->buffer()->remove_selection(); + } +} + +int Fl_Text_Editor::kf_default(int c, Fl_Text_Editor* e) { + if (!c || (!isprint(c) && c != '\t')) return 0; + char s[2] = "\0"; + s[0] = (char)c; + kill_selection(e); + if (e->insert_mode()) e->insert(s); + else e->overstrike(s); + e->show_insert_position(); + e->set_changed(); + if (e->when()&FL_WHEN_CHANGED) e->do_callback(); + return 1; +} + +int Fl_Text_Editor::kf_ignore(int, Fl_Text_Editor*) { + return 0; // don't handle +} + +int Fl_Text_Editor::kf_backspace(int, Fl_Text_Editor* e) { + if (!e->buffer()->selected() && e->move_left()) + e->buffer()->select(e->insert_position(), e->insert_position()+1); + kill_selection(e); + e->show_insert_position(); + e->set_changed(); + if (e->when()&FL_WHEN_CHANGED) e->do_callback(); + return 1; +} + +int Fl_Text_Editor::kf_enter(int, Fl_Text_Editor* e) { + kill_selection(e); + e->insert("\n"); + e->show_insert_position(); + e->set_changed(); + if (e->when()&FL_WHEN_CHANGED) e->do_callback(); + return 1; +} + +extern void fl_text_drag_me(int pos, Fl_Text_Display* d); + +int Fl_Text_Editor::kf_move(int c, Fl_Text_Editor* e) { + int i; + int selected = e->buffer()->selected(); + if (!selected) + e->dragPos = e->insert_position(); + e->buffer()->unselect(); + switch (c) { + case FL_Home: + e->insert_position(e->buffer()->line_start(e->insert_position())); + break; + case FL_End: + e->insert_position(e->buffer()->line_end(e->insert_position())); + break; + case FL_Left: + e->move_left(); + break; + case FL_Right: + e->move_right(); + break; + case FL_Up: + e->move_up(); + break; + case FL_Down: + e->move_down(); + break; + case FL_Page_Up: + for (i = 0; i < e->mNVisibleLines - 1; i++) e->move_up(); + break; + case FL_Page_Down: + for (i = 0; i < e->mNVisibleLines - 1; i++) e->move_down(); + break; + } + e->show_insert_position(); + return 1; +} + +int Fl_Text_Editor::kf_shift_move(int c, Fl_Text_Editor* e) { + kf_move(c, e); + fl_text_drag_me(e->insert_position(), e); + return 1; +} + +int Fl_Text_Editor::kf_ctrl_move(int c, Fl_Text_Editor* e) { + if (!e->buffer()->selected()) + e->dragPos = e->insert_position(); + if (c != FL_Up && c != FL_Down) { + e->buffer()->unselect(); + e->show_insert_position(); + } + switch (c) { + case FL_Home: + e->insert_position(0); + e->scroll(0, 0); + break; + case FL_End: + e->insert_position(e->buffer()->length()); + e->scroll(e->count_lines(0, e->buffer()->length(), 1), 0); + break; + case FL_Left: + e->previous_word(); + break; + case FL_Right: + e->next_word(); + break; + case FL_Up: + e->scroll(e->mTopLineNum-1, e->mHorizOffset); + break; + case FL_Down: + e->scroll(e->mTopLineNum+1, e->mHorizOffset); + break; + case FL_Page_Up: + e->insert_position(e->mLineStarts[0]); + break; + case FL_Page_Down: + e->insert_position(e->mLineStarts[e->mNVisibleLines-2]); + break; + } + return 1; +} + +int Fl_Text_Editor::kf_c_s_move(int c, Fl_Text_Editor* e) { + kf_ctrl_move(c, e); + fl_text_drag_me(e->insert_position(), e); + return 1; +} + +int Fl_Text_Editor::kf_home(int, Fl_Text_Editor* e) { + return kf_move(FL_Home, e); +} + +int Fl_Text_Editor::kf_end(int, Fl_Text_Editor* e) { + return kf_move(FL_End, e); +} + +int Fl_Text_Editor::kf_left(int, Fl_Text_Editor* e) { + return kf_move(FL_Left, e); +} + +int Fl_Text_Editor::kf_up(int, Fl_Text_Editor* e) { + return kf_move(FL_Up, e); +} + +int Fl_Text_Editor::kf_right(int, Fl_Text_Editor* e) { + return kf_move(FL_Right, e); +} + +int Fl_Text_Editor::kf_down(int, Fl_Text_Editor* e) { + return kf_move(FL_Down, e); +} + +int Fl_Text_Editor::kf_page_up(int, Fl_Text_Editor* e) { + return kf_move(FL_Page_Up, e); +} + +int Fl_Text_Editor::kf_page_down(int, Fl_Text_Editor* e) { + return kf_move(FL_Page_Down, e); +} + + +int Fl_Text_Editor::kf_insert(int, Fl_Text_Editor* e) { + e->insert_mode(e->insert_mode() ? 0 : 1); + return 1; +} + +int Fl_Text_Editor::kf_delete(int, Fl_Text_Editor* e) { + if (!e->buffer()->selected()) + e->buffer()->select(e->insert_position(), e->insert_position()+1); + kill_selection(e); + e->show_insert_position(); + e->set_changed(); + if (e->when()&FL_WHEN_CHANGED) e->do_callback(); + return 1; +} + +int Fl_Text_Editor::kf_copy(int, Fl_Text_Editor* e) { + if (!e->buffer()->selected()) return 1; + const char *copy = e->buffer()->selection_text(); + if (*copy) Fl::copy(copy, strlen(copy), 1); + free((void*)copy); + e->show_insert_position(); + return 1; +} + +int Fl_Text_Editor::kf_cut(int c, Fl_Text_Editor* e) { + kf_copy(c, e); + kill_selection(e); + e->set_changed(); + if (e->when()&FL_WHEN_CHANGED) e->do_callback(); + return 1; +} + +int Fl_Text_Editor::kf_paste(int, Fl_Text_Editor* e) { + kill_selection(e); + Fl::paste(*e, 1); + e->show_insert_position(); + e->set_changed(); + if (e->when()&FL_WHEN_CHANGED) e->do_callback(); + return 1; +} + +int Fl_Text_Editor::kf_select_all(int, Fl_Text_Editor* e) { + e->buffer()->select(0, e->buffer()->length()); + return 1; +} + +int Fl_Text_Editor::kf_undo(int , Fl_Text_Editor* e) { + e->buffer()->unselect(); + int crsr; + int ret = e->buffer()->undo(&crsr); + e->insert_position(crsr); + e->show_insert_position(); + e->set_changed(); + if (e->when()&FL_WHEN_CHANGED) e->do_callback(); + return ret; +} + +int Fl_Text_Editor::handle_key() { + // Call FLTK's rules to try to turn this into a printing character. + // This uses the right-hand ctrl key as a "compose prefix" and returns + // the changes that should be made to the text, as a number of + // bytes to delete and a string to insert: + int del; + if (Fl::compose(del)) { + if (del) buffer()->select(insert_position()-del, insert_position()); + kill_selection(this); + if (Fl::event_length()) { + if (insert_mode()) insert(Fl::event_text()); + else overstrike(Fl::event_text()); + } + show_insert_position(); + set_changed(); + if (when()&FL_WHEN_CHANGED) do_callback(); + return 1; + } + + int key = Fl::event_key(), state = Fl::event_state(), c = Fl::event_text()[0]; + state &= FL_SHIFT|FL_CTRL|FL_ALT|FL_META; // only care about these states + Key_Func f; + f = bound_key_function(key, state, global_key_bindings); + if (!f) f = bound_key_function(key, state, key_bindings); + if (f) return f(key, this); + if (default_key_function_ && !state) return default_key_function_(c, this); + return 0; +} + +void Fl_Text_Editor::maybe_do_callback() { +// printf("Fl_Text_Editor::maybe_do_callback()\n"); +// printf("changed()=%d, when()=%x\n", changed(), when()); + if (changed() || (when()&FL_WHEN_NOT_CHANGED)) do_callback(); +} + +int Fl_Text_Editor::handle(int event) { + if (!buffer()) return 0; + + switch (event) { + case FL_FOCUS: + show_cursor(mCursorOn); // redraws the cursor + if (buffer()->selected()) redraw(); // Redraw selections... + Fl::focus(this); + return 1; + + case FL_UNFOCUS: + show_cursor(mCursorOn); // redraws the cursor + if (buffer()->selected()) redraw(); // Redraw selections... + case FL_HIDE: + if (when() & FL_WHEN_RELEASE) maybe_do_callback(); + return 1; + + case FL_KEYBOARD: + if (active_r() && window() && this == Fl::belowmouse()) + window()->cursor(FL_CURSOR_NONE); + return handle_key(); + + case FL_PASTE: + if (!Fl::event_text()) { + fl_beep(); + return 1; + } + buffer()->remove_selection(); + if (insert_mode()) insert(Fl::event_text()); + else overstrike(Fl::event_text()); + show_insert_position(); + set_changed(); + if (when()&FL_WHEN_CHANGED) do_callback(); + return 1; + + case FL_ENTER: +// MRS: WIN32 only? Need to test! +// case FL_MOVE: + show_cursor(mCursorOn); + return 1; + + case FL_PUSH: + if (Fl::event_button() == 2) { + // don't let the text_display see this event + if (Fl_Group::handle(event)) return 1; + dragType = -1; + Fl::paste(*this, 0); + Fl::focus(this); + set_changed(); + if (when()&FL_WHEN_CHANGED) do_callback(); + return 1; + } + break; + } + + return Fl_Text_Display::handle(event); +} + +// +// End of "$Id: Fl_Text_Editor.cxx 5671 2007-02-08 07:58:47Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Tile.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Tile.cxx new file mode 100644 index 000000000..c1d0cf6a7 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Tile.cxx @@ -0,0 +1,207 @@ +// +// "$Id: Fl_Tile.cxx 5606 2007-01-18 10:01:24Z matt $" +// +// Tile widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Group of 2 or 4 "tiles" that can be resized by dragging border +// The size of the first child determines where the resize border is. +// The resizebox is used to limit where the border can be dragged to. + +#include +#include +#include +#include + +// Drag the edges that were initially at oldx,oldy to newx,newy: +// pass zero as oldx or oldy to disable drag in that direction: + +void Fl_Tile::position(int oix, int oiy, int newx, int newy) { + Fl_Widget*const* a = array(); + short* p = sizes(); + p += 8; // skip group & resizable's saved size + for (int i=children(); i--; p += 4) { + Fl_Widget* o = *a++; + if (o == resizable()) continue; + int X = o->x(); + int R = X+o->w(); + if (oix) { + int t = p[0]; + if (t == oix || t>oix && Xnewx) X = newx; + t = p[1]; + if (t == oix || t>oix && Rnewx) R = newx; + } + int Y = o->y(); + int B = Y+o->h(); + if (oiy) { + int t = p[2]; + if (t == oiy || t>oiy && Ynewy) Y = newy; + t = p[3]; + if (t == oiy || t>oiy && Bnewy) B = newy; + } + o->damage_resize(X,Y,R-X,B-Y); + } +} + +// move the lower-right corner (sort of): +void Fl_Tile::resize(int X,int Y,int W,int H) { + //Fl_Group::resize(X, Y, W, H); + //return; + // remember how much to move the child widgets: + int dx = X-x(); + int dy = Y-y(); + int dw = W-w(); + int dh = H-h(); + short* p = sizes(); + // resize this (skip the Fl_Group resize): + Fl_Widget::resize(X,Y,W,H); + // find bottom-right of resiable: + int OR = p[5]; + int NR = X+W-(p[1]-OR); + int OB = p[7]; + int NB = Y+H-(p[3]-OB); + // move everything to be on correct side of new resizable: + Fl_Widget*const* a = array(); + p += 8; + for (int i=children(); i--;) { + Fl_Widget* o = *a++; + int xx = o->x()+dx; + int R = xx+o->w(); + if (*p++ >= OR) xx += dw; else if (xx > NR) xx = NR; + if (*p++ >= OR) R += dw; else if (R > NR) R = NR; + int yy = o->y()+dy; + int B = yy+o->h(); + if (*p++ >= OB) yy += dh; else if (yy > NB) yy = NB; + if (*p++ >= OB) B += dh; else if (B > NB) B = NB; + o->resize(xx,yy,R-xx,B-yy); + // do *not* call o->redraw() here! If you do, and the tile is inside a + // scroll, it'll set the damage areas wrong for all children! + } +} + +static void set_cursor(Fl_Tile*t, Fl_Cursor c) { + static Fl_Cursor cursor; + if (cursor == c || !t->window()) return; + cursor = c; +#ifdef __sgi + t->window()->cursor(c,FL_RED,FL_WHITE); +#else + t->window()->cursor(c); +#endif +} + +static Fl_Cursor cursors[4] = { + FL_CURSOR_DEFAULT, + FL_CURSOR_WE, + FL_CURSOR_NS, + FL_CURSOR_MOVE}; + +int Fl_Tile::handle(int event) { + static int sdrag; + static int sdx, sdy; + static int sx, sy; +#define DRAGH 1 +#define DRAGV 2 +#define GRABAREA 4 + + int mx = Fl::event_x(); + int my = Fl::event_y(); + + switch (event) { + + case FL_MOVE: + case FL_ENTER: + case FL_PUSH: { + int mindx = 100; + int mindy = 100; + int oldx = 0; + int oldy = 0; + Fl_Widget*const* a = array(); + short* q = sizes(); + short* p = q+8; + for (int i=children(); i--; p += 4) { + Fl_Widget* o = *a++; + if (o == resizable()) continue; + if (p[1]y()<=my+GRABAREA && o->y()+o->h()>=my-GRABAREA) { + int t = mx - (o->x()+o->w()); + if (abs(t) < mindx) { + sdx = t; + mindx = abs(t); + oldx = p[1]; + } + } + if (p[3]x()<=mx+GRABAREA && o->x()+o->w()>=mx-GRABAREA) { + int t = my - (o->y()+o->h()); + if (abs(t) < mindy) { + sdy = t; + mindy = abs(t); + oldy = p[3]; + } + } + } + sdrag = 0; sx = sy = 0; + if (mindx <= GRABAREA) {sdrag = DRAGH; sx = oldx;} + if (mindy <= GRABAREA) {sdrag |= DRAGV; sy = oldy;} + set_cursor(this, cursors[sdrag]); + if (sdrag) return 1; + return Fl_Group::handle(event); + } + + case FL_LEAVE: + set_cursor(this, FL_CURSOR_DEFAULT); + break; + + case FL_DRAG: + // This is necessary if CONSOLIDATE_MOTION in Fl_x.cxx is turned off: + // if (damage()) return 1; // don't fall behind + case FL_RELEASE: { + if (!sdrag) return 0; // should not happen + Fl_Widget* r = resizable(); if (!r) r = this; + int newx; + if (sdrag&DRAGH) { + newx = Fl::event_x()-sdx; + if (newx < r->x()) newx = r->x(); + else if (newx > r->x()+r->w()) newx = r->x()+r->w(); + } else + newx = sx; + int newy; + if (sdrag&DRAGV) { + newy = Fl::event_y()-sdy; + if (newy < r->y()) newy = r->y(); + else if (newy > r->y()+r->h()) newy = r->y()+r->h(); + } else + newy = sy; + position(sx,sy,newx,newy); + if (event == FL_DRAG) set_changed(); + do_callback(); + return 1;} + + } + + return Fl_Group::handle(event); +} + +// +// End of "$Id: Fl_Tile.cxx 5606 2007-01-18 10:01:24Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Tiled_Image.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Tiled_Image.cxx new file mode 100644 index 000000000..222d9e627 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Tiled_Image.cxx @@ -0,0 +1,139 @@ +// +// "$Id: Fl_Tiled_Image.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Tiled image code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include + + +// +// 'Fl_Tiled_Image::Fl_Tiled_Image()' - Constructor. +// +// Use a width and height of 0 to tile the whole window/widget. +// + +Fl_Tiled_Image::Fl_Tiled_Image(Fl_Image *i, // I - Image to tile + int W, // I - Width of tiled area + int H) : // I - Height of tiled area + Fl_Image(W,H,0) { + image_ = i; + alloc_image_ = 0; + + if (W == 0) w(Fl::w()); + if (H == 0) h(Fl::h()); +} + + +// +// 'Fl_Tiled_Image::~Fl_Tiled_Image()' - Destructor. +// + +Fl_Tiled_Image::~Fl_Tiled_Image() { + if (alloc_image_) delete image_; +} + + +// +// 'Fl_Tiled_Image::copy()' - Copy and resize a tiled image... +// + +Fl_Image * // O - New image +Fl_Tiled_Image::copy(int W, // I - New width + int H) { // I - New height + if (W == w() && H == h()) return this; + else return new Fl_Tiled_Image(image_, W, H); +} + + +// +// 'Fl_Tiled_Image::color_average()' - Blend colors... +// + +void +Fl_Tiled_Image::color_average(Fl_Color c, // I - Color to blend with + float i) { // I - Blend fraction + if (!alloc_image_) { + image_ = image_->copy(); + alloc_image_ = 1; + } + + image_->color_average(c, i); +} + + +// +// 'Fl_Tiled_Image::desaturate()' - Convert the image to grayscale... +// + +void +Fl_Tiled_Image::desaturate() { + if (!alloc_image_) { + image_ = image_->copy(); + alloc_image_ = 1; + } + + image_->desaturate(); +} + + +// +// 'Fl_Tiled_Image::draw()' - Draw a shared image... +// + +void +Fl_Tiled_Image::draw(int X, // I - Starting X position + int Y, // I - Starting Y position + int W, // I - Width of area to be filled + int H, // I - Height of area to be filled + int cx, // I - "Source" X position + int cy) { // I - "Source" Y position + if (!image_->w() || !image_->h()) return; + if (W == 0) W = Fl::w(); + if (H == 0) H = Fl::h(); + + fl_clip(X, Y, W, H); + + X += cx; + Y += cy; + + X = X - (X % image_->w()); + Y = Y - (Y % image_->h()); + + W += X; + H += Y; + + for (int yy = Y; yy < H; yy += image_->h()) + for (int xx = X; xx < W; xx += image_->w()) + image_->draw(xx, yy); + + fl_pop_clip(); +} + + +// +// End of "$Id: Fl_Tiled_Image.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Tooltip.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Tooltip.cxx new file mode 100644 index 000000000..37313771f --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Tooltip.cxx @@ -0,0 +1,263 @@ +// +// "$Id: Fl_Tooltip.cxx 5848 2007-05-20 16:18:31Z mike $" +// +// Tooltip source file for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include + +#include + +float Fl_Tooltip::delay_ = 1.0f; +float Fl_Tooltip::hoverdelay_ = 0.2f; +int Fl_Tooltip::enabled_ = 1; +unsigned Fl_Tooltip::color_ = fl_color_cube(FL_NUM_RED - 1, + FL_NUM_GREEN - 1, + FL_NUM_BLUE - 2); +unsigned Fl_Tooltip::textcolor_ = FL_BLACK; +int Fl_Tooltip::font_ = FL_HELVETICA; +int Fl_Tooltip::size_ = FL_NORMAL_SIZE; + +#define MAX_WIDTH 400 + +static const char* tip; + +class Fl_TooltipBox : public Fl_Menu_Window { +public: + Fl_TooltipBox() : Fl_Menu_Window(0, 0) { + set_override(); + end(); + } + void draw(); + void layout(); + void show() { + if (tip) Fl_Menu_Window::show(); + } +}; + +Fl_Widget* Fl_Tooltip::widget_ = 0; +static Fl_TooltipBox *window = 0; +static int Y,H; + +void Fl_TooltipBox::layout() { + fl_font(Fl_Tooltip::font(), Fl_Tooltip::size()); + int ww, hh; + ww = MAX_WIDTH; + fl_measure(tip, ww, hh, FL_ALIGN_LEFT|FL_ALIGN_WRAP|FL_ALIGN_INSIDE); + ww += 6; hh += 6; + + // find position on the screen of the widget: + int ox = Fl::event_x_root(); + int oy = Y + H+2; + for (Fl_Widget* p = Fl_Tooltip::current(); p; p = p->window()) { + oy += p->y(); + } + int scr_x, scr_y, scr_w, scr_h; + Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h); + if (ox+ww > scr_x+scr_w) ox = scr_x+scr_w - ww; + if (ox < scr_x) ox = scr_x; + if (H > 30) { + oy = Fl::event_y_root()+13; + if (oy+hh > scr_y+scr_h) oy -= 23+hh; + } else { + if (oy+hh > scr_y+scr_h) oy -= (4+hh+H); + } + if (oy < scr_y) oy = scr_y; + + resize(ox, oy, ww, hh); +} + +void Fl_TooltipBox::draw() { + draw_box(FL_BORDER_BOX, 0, 0, w(), h(), Fl_Tooltip::color()); + fl_color(Fl_Tooltip::textcolor()); + fl_font(Fl_Tooltip::font(), Fl_Tooltip::size()); + fl_draw(tip, 3, 3, w()-6, h()-6, Fl_Align(FL_ALIGN_LEFT|FL_ALIGN_WRAP)); +} + +static char recent_tooltip; + +static void recent_timeout(void*) { +#ifdef DEBUG + puts("recent_timeout();"); +#endif // DEBUG + + recent_tooltip = 0; +} + +static char recursion; + +static void tooltip_timeout(void*) { +#ifdef DEBUG + puts("tooltip_timeout();"); +#endif // DEBUG + + if (recursion) return; + recursion = 1; + if (!tip || !*tip) { + if (window) window->hide(); + } else { + //if (Fl::grab()) return; + if (!window) window = new Fl_TooltipBox; + // this cast bypasses the normal Fl_Window label() code: + ((Fl_Widget*)window)->label(tip); + window->layout(); + window->redraw(); +// printf("tooltip_timeout: Showing window %p with tooltip \"%s\"...\n", +// window, tip ? tip : "(null)"); + window->show(); + } + + Fl::remove_timeout(recent_timeout); + recent_tooltip = 1; + recursion = 0; +} + +// If this widget or one of it's parents has a tooltip, enter it. This +// will do nothing if this is the current widget (even if the mouse moved +// out so an exit() was done and then moved back in). If no tooltip can +// be found do Fl_Tooltip::exit_(). If you don't want this behavior (for instance +// if you want the tooltip to reappear when the mouse moves back in) +// call the fancier enter_area() below. +void +Fl_Tooltip::enter_(Fl_Widget* w) { +#ifdef DEBUG + printf("Fl_Tooltip::enter_(w=%p)\n", w); + printf(" window=%p\n", window); +#endif // DEBUG + + // find the enclosing group with a tooltip: + Fl_Widget* tw = w; + for (;;) { + if (!tw) {exit_(0); return;} + if (tw == widget_) return; + if (tw->tooltip()) break; + tw = tw->parent(); + } + enter_area(w, 0, 0, w->w(), w->h(), tw->tooltip()); +} + +// Acts as though enter(widget) was done but does not pop up a +// tooltip. This is useful to prevent a tooltip from reappearing when +// a modal overlapping window is deleted. FLTK does this automatically +// when you click the mouse button. +void Fl_Tooltip::current(Fl_Widget* w) { +#ifdef DEBUG + printf("Fl_Tooltip::current(w=%p)\n", w); +#endif // DEBUG + + exit_(0); + // find the enclosing group with a tooltip: + Fl_Widget* tw = w; + for (;;) { + if (!tw) return; + if (tw->tooltip()) break; + tw = tw->parent(); + } + // act just like Fl_Tooltip::enter_() except we can remember a zero: + widget_ = w; +} + +// Hide any visible tooltip. +void +Fl_Tooltip::exit_(Fl_Widget *w) { +#ifdef DEBUG + printf("Fl_Tooltip::exit_(w=%p)\n", w); + printf(" widget=%p, window=%p\n", widget_, window); +#endif // DEBUG + + if (!widget_ || w == window) return; + widget_ = 0; + Fl::remove_timeout(tooltip_timeout); + Fl::remove_timeout(recent_timeout); + if (window && window->visible()) window->hide(); + if (recent_tooltip) { + if (Fl::event_state() & FL_BUTTONS) recent_tooltip = 0; + else Fl::add_timeout(Fl_Tooltip::hoverdelay(), recent_timeout); + } +} + +// Get ready to display a tooltip. The widget and the xywh box inside +// it define an area the tooltip is for, this along with the current +// mouse position places the tooltip (the mouse is assummed to point +// inside or near the box). +void +Fl_Tooltip::enter_area(Fl_Widget* wid, int x,int y,int w,int h, const char* t) +{ + (void)x; + (void)w; + +#ifdef DEBUG + printf("Fl_Tooltip::enter_area(wid=%p, x=%d, y=%d, w=%d, h=%d, t=\"%s\")\n", + wid, x, y, w, h, t ? t : "(null)"); + printf(" recursion=%d, window=%p\n", recursion, window); +#endif // DEBUG + + if (recursion) return; + if (!t || !*t || !enabled()) { + exit_(0); + return; + } + // do nothing if it is the same: + if (wid==widget_ /*&& x==X && y==Y && w==W && h==H*/ && t==tip) return; + Fl::remove_timeout(tooltip_timeout); + Fl::remove_timeout(recent_timeout); + // remember it: + widget_ = wid; Y = y; H = h; tip = t; + // popup the tooltip immediately if it was recently up: + if (recent_tooltip) { + if (window) window->hide(); + Fl::add_timeout(Fl_Tooltip::hoverdelay(), tooltip_timeout); + } else if (Fl_Tooltip::delay() < .1) { +#ifdef WIN32 + // possible fix for the Windows titlebar, it seems to want the + // window to be destroyed, moving it messes up the parenting: + if (window && window->visible()) window->hide(); +#endif // WIN32 + tooltip_timeout(0); + } else { + if (window && window->visible()) window->hide(); + Fl::add_timeout(Fl_Tooltip::delay(), tooltip_timeout); + } + +#ifdef DEBUG + printf(" tip=\"%s\", window->shown()=%d\n", tip ? tip : "(null)", + window ? window->shown() : 0); +#endif // DEBUG +} + +void Fl_Widget::tooltip(const char *tt) { + static char beenhere = 0; + if (!beenhere) { + beenhere = 1; + Fl_Tooltip::enter = Fl_Tooltip::enter_; + Fl_Tooltip::exit = Fl_Tooltip::exit_; + } + tooltip_ = tt; +} + +// +// End of "$Id: Fl_Tooltip.cxx 5848 2007-05-20 16:18:31Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Valuator.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Valuator.cxx new file mode 100644 index 000000000..1d6a32dd2 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Valuator.cxx @@ -0,0 +1,149 @@ +// +// "$Id: Fl_Valuator.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Valuator widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Base class for sliders and all other one-value "knobs" + +#include +#include +#include +#include +#include "flstring.h" + +Fl_Valuator::Fl_Valuator(int X, int Y, int W, int H, const char* L) + : Fl_Widget(X,Y,W,H,L) { + align(FL_ALIGN_BOTTOM); + when(FL_WHEN_CHANGED); + value_ = 0; + previous_value_ = 1; + min = 0; + max = 1; + A = 0.0; + B = 1; +} + +const double epsilon = 4.66e-10; + +void Fl_Valuator::step(double s) { + if (s < 0) s = -s; + A = rint(s); + B = 1; + while (fabs(s-A/B) > epsilon && B<=(0x7fffffff/10)) {B *= 10; A = rint(s*B);} +} + +void Fl_Valuator::precision(int p) { + A = 1.0; + for (B = 1; p--;) B *= 10; +} + +void Fl_Valuator::value_damage() {damage(FL_DAMAGE_EXPOSE);} // by default do partial-redraw + +int Fl_Valuator::value(double v) { + clear_changed(); + if (v == value_) return 0; + value_ = v; + value_damage(); + return 1; +} + +double Fl_Valuator::softclamp(double v) { + int which = (min<=max); + double p = previous_value_; + if ((vmax)==which && p!=max && (p>max)!=which) return max; + else return v; +} + +// inline void Fl_Valuator::handle_push() {previous_value_ = value_;} + +void Fl_Valuator::handle_drag(double v) { + if (v != value_) { + value_ = v; + value_damage(); + set_changed(); + if (when() & FL_WHEN_CHANGED) do_callback(); + } +} + +void Fl_Valuator::handle_release() { + if (when()&FL_WHEN_RELEASE) { + // insure changed() is off even if no callback is done. It may have + // been turned on by the drag, and then the slider returned to it's + // initial position: + clear_changed(); + // now do the callback only if slider in new position or always is on: + if (value_ != previous_value_ || when() & FL_WHEN_NOT_CHANGED) { + do_callback(); + } + } +} + +double Fl_Valuator::round(double v) { + if (A) return rint(v*B/A)*A/B; + else return v; +} + +double Fl_Valuator::clamp(double v) { + if ((vmax)==(min<=max)) return max; + else return v; +} + +double Fl_Valuator::increment(double v, int n) { + if (!A) return v+n*(max-min)/100; + if (min > max) n = -n; + return (rint(v*B/A)+n)*A/B; +} + +int Fl_Valuator::format(char* buffer) { + double v = value(); + // MRS: THIS IS A HACK - RECOMMEND ADDING BUFFER SIZE ARGUMENT + if (!A || !B) return snprintf(buffer, 128, "%g", v); + + // Figure out how many digits are required to correctly format the + // value. + int i, c = 0; + char temp[32]; + // output a number with many digits after the decimal point. This + // seems to be needed to get high precission + snprintf(temp, sizeof(temp), "%.12f", A/B); + // strip all trailing 0's + for (i=strlen(temp)-1; i>0; i--) { + if (temp[i]!='0') break; + } + // count digits until we find the decimal point (or comma or whatever + // letter is set in the current locale) + for (; i>0; i--, c++) { + if (!isdigit(temp[i])) break; + } + + // MRS: THIS IS A HACK - RECOMMEND ADDING BUFFER SIZE ARGUMENT + return snprintf(buffer, 128, "%.*f", c, v); +} + +// +// End of "$Id: Fl_Valuator.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Value_Input.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Value_Input.cxx new file mode 100644 index 000000000..d9d19c416 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Value_Input.cxx @@ -0,0 +1,133 @@ +// +// "$Id: Fl_Value_Input.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Value input widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// FLTK widget for drag-adjusting a floating point value. +// Warning: this works by making a child Fl_Input object, even +// though this object is *not* an Fl_Group. May be a kludge? + +#include +#include +#include +#include +#include + + +void Fl_Value_Input::input_cb(Fl_Widget*, void* v) { + Fl_Value_Input& t = *(Fl_Value_Input*)v; + double nv; + if ((t.step() - floor(t.step()))>0.0 || t.step() == 0.0) nv = strtod(t.input.value(), 0); + else nv = strtol(t.input.value(), 0, 0); + if (nv != t.value() || t.when() & FL_WHEN_NOT_CHANGED) { + t.set_value(nv); + t.set_changed(); + if (t.when()) t.do_callback(); + } +} + +void Fl_Value_Input::draw() { + if (damage()&~FL_DAMAGE_CHILD) input.clear_damage(FL_DAMAGE_ALL); + input.box(box()); + input.color(color(), selection_color()); + input.draw(); + input.clear_damage(); +} + +void Fl_Value_Input::resize(int X, int Y, int W, int H) { + Fl_Valuator::resize(X, Y, W, H); + input.resize(X, Y, W, H); +} + +void Fl_Value_Input::value_damage() { + char buf[128]; + format(buf); + input.value(buf); + input.mark(input.position()); // turn off selection highlight +} + +int Fl_Value_Input::handle(int event) { + double v; + int delta; + int mx = Fl::event_x_root(); + static int ix, drag; + input.when(when()); + switch (event) { + case FL_PUSH: + if (!step()) goto DEFAULT; + ix = mx; + drag = Fl::event_button(); + handle_push(); + return 1; + case FL_DRAG: + if (!step()) goto DEFAULT; + delta = mx-ix; + if (delta > 5) delta -= 5; + else if (delta < -5) delta += 5; + else delta = 0; + switch (drag) { + case 3: v = increment(previous_value(), delta*100); break; + case 2: v = increment(previous_value(), delta*10); break; + default:v = increment(previous_value(), delta); break; + } + v = round(v); + handle_drag(soft()?softclamp(v):clamp(v));; + return 1; + case FL_RELEASE: + if (!step()) goto DEFAULT; + if (value() != previous_value() || !Fl::event_is_click()) + handle_release(); + else { + input.handle(FL_PUSH); + input.handle(FL_RELEASE); + } + return 1; + case FL_FOCUS: + return input.take_focus(); + default: + DEFAULT: + input.type(((step() - floor(step()))>0.0 || step() == 0.0) ? FL_FLOAT_INPUT : FL_INT_INPUT); + return input.handle(event); + } +} + +Fl_Value_Input::Fl_Value_Input(int X, int Y, int W, int H, const char* l) +: Fl_Valuator(X, Y, W, H, l), input(X, Y, W, H, 0) { + soft_ = 0; + if (input.parent()) // defeat automatic-add + ((Fl_Group*)input.parent())->remove(input); + input.parent((Fl_Group *)this); // kludge! + input.callback(input_cb, this); + input.when(FL_WHEN_CHANGED); + box(input.box()); + color(input.color()); + selection_color(input.selection_color()); + align(FL_ALIGN_LEFT); + value_damage(); +} + +// +// End of "$Id: Fl_Value_Input.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Value_Output.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Value_Output.cxx new file mode 100644 index 000000000..8a1f13c8d --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Value_Output.cxx @@ -0,0 +1,103 @@ +// +// "$Id: Fl_Value_Output.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Value output widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Fltk widget for drag-adjusting a floating point value. +// This is much lighter than Fl_Value_Input because it has no text editor +// If step() is zero then it can be used to display a floating-point value + +#include +#include +#include + +void Fl_Value_Output::draw() { + Fl_Boxtype b = box() ? box() : FL_DOWN_BOX; + int X = x()+Fl::box_dx(b); + int Y = y()+Fl::box_dy(b); + int W = w()-Fl::box_dw(b); + int H = h()-Fl::box_dh(b); + if (damage()&~FL_DAMAGE_CHILD) + draw_box(b, color()); + else { + fl_color(color()); + fl_rectf(X, Y, W, H); + } + char buf[128]; + format(buf); + fl_color(active_r() ? textcolor() : fl_inactive(textcolor())); + fl_font(textfont(), textsize()); + fl_draw(buf,X,Y,W,H,FL_ALIGN_LEFT); +} + +int Fl_Value_Output::handle(int event) { + if (!step()) return 0; + double v; + int delta; + int mx = Fl::event_x(); + static int ix, drag; + switch (event) { + case FL_PUSH: + ix = mx; + drag = Fl::event_button(); + handle_push(); + return 1; + case FL_DRAG: + delta = Fl::event_x()-ix; + if (delta > 5) delta -= 5; + else if (delta < -5) delta += 5; + else delta = 0; + switch (drag) { + case 3: v = increment(previous_value(),delta*100); break; + case 2: v = increment(previous_value(),delta*10); break; + default:v = increment(previous_value(),delta); break; + } + v = round(v); + handle_drag(soft()?softclamp(v):clamp(v));; + return 1; + case FL_RELEASE: + handle_release(); + return 1; + case FL_ENTER : + case FL_LEAVE : + return 1; + default: + return 0; + } +} + +Fl_Value_Output::Fl_Value_Output(int X, int Y, int W, int H,const char *l) +: Fl_Valuator(X,Y,W,H,l) { + box(FL_NO_BOX); + align(FL_ALIGN_LEFT); + textfont_ = FL_HELVETICA; + textsize_ = (uchar)FL_NORMAL_SIZE; + textcolor_ = FL_FOREGROUND_COLOR; + soft_ = 0; +} + +// +// End of "$Id: Fl_Value_Output.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Value_Slider.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Value_Slider.cxx new file mode 100644 index 000000000..b8203267a --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Value_Slider.cxx @@ -0,0 +1,82 @@ +// +// "$Id: Fl_Value_Slider.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Value slider widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include + +Fl_Value_Slider::Fl_Value_Slider(int X, int Y, int W, int H, const char*l) +: Fl_Slider(X,Y,W,H,l) { + step(1,100); + textfont_ = FL_HELVETICA; + textsize_ = 10; + textcolor_ = FL_FOREGROUND_COLOR; +} + +void Fl_Value_Slider::draw() { + int sxx = x(), syy = y(), sww = w(), shh = h(); + int bxx = x(), byy = y(), bww = w(), bhh = h(); + if (horizontal()) { + bww = 35; sxx += 35; sww -= 35; + } else { + syy += 25; bhh = 25; shh -= 25; + } + if (damage()&FL_DAMAGE_ALL) draw_box(box(),sxx,syy,sww,shh,color()); + Fl_Slider::draw(sxx+Fl::box_dx(box()), + syy+Fl::box_dy(box()), + sww-Fl::box_dw(box()), + shh-Fl::box_dh(box())); + draw_box(box(),bxx,byy,bww,bhh,color()); + char buf[128]; + format(buf); + fl_font(textfont(), textsize()); + fl_color(active_r() ? textcolor() : fl_inactive(textcolor())); + fl_draw(buf, bxx, byy, bww, bhh, FL_ALIGN_CLIP); +} + +int Fl_Value_Slider::handle(int event) { + if (event == FL_PUSH && Fl::visible_focus()) { + Fl::focus(this); + redraw(); + } + int sxx = x(), syy = y(), sww = w(), shh = h(); + if (horizontal()) { + sxx += 35; sww -= 35; + } else { + syy += 25; shh -= 25; + } + return Fl_Slider::handle(event, + sxx+Fl::box_dx(box()), + syy+Fl::box_dy(box()), + sww-Fl::box_dw(box()), + shh-Fl::box_dh(box())); +} + +// +// End of "$Id: Fl_Value_Slider.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Widget.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Widget.cxx new file mode 100644 index 000000000..b20d8df6b --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Widget.cxx @@ -0,0 +1,284 @@ +// +// "$Id: Fl_Widget.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Base widget class for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include +#include +#include +#include "flstring.h" + + +//////////////////////////////////////////////////////////////// +// for compatability with Forms, all widgets without callbacks are +// inserted into a "queue" when they are activated, and the forms +// compatability interaction functions (fl_do_events, etc) will +// read one widget at a time from this queue and return it: + +const int QUEUE_SIZE = 20; + +static Fl_Widget *obj_queue[QUEUE_SIZE]; +static int obj_head, obj_tail; + +void Fl_Widget::default_callback(Fl_Widget *o, void * /*v*/) { +#if 0 + // This is necessary for strict forms compatability but is confusing. + // Use the parent's callback if this widget does not have one. + for (Fl_Widget *p = o->parent(); p; p = p->parent()) + if (p->callback() != default_callback) { + p->do_callback(o,v); + return; + } +#endif + obj_queue[obj_head++] = o; + if (obj_head >= QUEUE_SIZE) obj_head = 0; + if (obj_head == obj_tail) { + obj_tail++; + if (obj_tail >= QUEUE_SIZE) obj_tail = 0; + } +} + +Fl_Widget *Fl::readqueue() { + if (obj_tail==obj_head) return 0; + Fl_Widget *o = obj_queue[obj_tail++]; + if (obj_tail >= QUEUE_SIZE) obj_tail = 0; + return o; +} + +//////////////////////////////////////////////////////////////// + +int Fl_Widget::handle(int) { + return 0; +} + +int FL_NORMAL_SIZE = 14; + +Fl_Widget::Fl_Widget(int X, int Y, int W, int H, const char* L) { + + x_ = X; y_ = Y; w_ = W; h_ = H; + + label_.value = L; + label_.image = 0; + label_.deimage = 0; + label_.type = FL_NORMAL_LABEL; + label_.font = FL_HELVETICA; + label_.size = (uchar)FL_NORMAL_SIZE; + label_.color = FL_FOREGROUND_COLOR; + tooltip_ = 0; + callback_ = default_callback; + user_data_ = 0; + type_ = 0; + flags_ = VISIBLE_FOCUS; + damage_ = 0; + box_ = FL_NO_BOX; + color_ = FL_GRAY; + color2_ = FL_GRAY; + align_ = FL_ALIGN_CENTER; + when_ = FL_WHEN_RELEASE; + + parent_ = 0; + if (Fl_Group::current()) Fl_Group::current()->add(this); +} + +void Fl_Widget::resize(int X, int Y, int W, int H) { + x_ = X; y_ = Y; w_ = W; h_ = H; +} + +// this is useful for parent widgets to call to resize children: +int Fl_Widget::damage_resize(int X, int Y, int W, int H) { + if (x() == X && y() == Y && w() == W && h() == H) return 0; + resize(X, Y, W, H); + redraw(); + return 1; +} + +int Fl_Widget::take_focus() { + if (!takesevents()) return 0; + if (!visible_focus()) return 0; + if (!handle(FL_FOCUS)) return 0; // see if it wants it + if (contains(Fl::focus())) return 1; // it called Fl::focus for us + Fl::focus(this); + return 1; +} + +extern void fl_throw_focus(Fl_Widget*); // in Fl_x.cxx + +// Destruction does not remove from any parent group! And groups when +// destroyed destroy all their children. This is convienent and fast. +// However, it is only legal to destroy a "root" such as an Fl_Window, +// and automatic destructors may be called. +Fl_Widget::~Fl_Widget() { + Fl::clear_widget_pointer(this); + if (flags() & COPIED_LABEL) free((void *)(label_.value)); + parent_ = 0; // Don't throw focus to a parent widget. + fl_throw_focus(this); +} + +// draw a focus box for the widget... +void +Fl_Widget::draw_focus(Fl_Boxtype B, int X, int Y, int W, int H) const { + if (!Fl::visible_focus()) return; + switch (B) { + case FL_DOWN_BOX: + case FL_DOWN_FRAME: + case FL_THIN_DOWN_BOX: + case FL_THIN_DOWN_FRAME: + X ++; + Y ++; + default: + break; + } + + fl_color(fl_contrast(FL_BLACK, color())); + +#if defined(WIN32) || defined(__APPLE_QD__) + // Windows 95/98/ME do not implement the dotted line style, so draw + // every other pixel around the focus area... + // + // Also, QuickDraw (MacOS) does not support line styles specifically, + // and the hack we use in fl_line_style() will not draw horizontal lines + // on odd-numbered rows... + int i, xx, yy; + + X += Fl::box_dx(B); + Y += Fl::box_dy(B); + W -= Fl::box_dw(B) + 2; + H -= Fl::box_dh(B) + 2; + + for (xx = 0, i = 1; xx < W; xx ++, i ++) if (i & 1) fl_point(X + xx, Y); + for (yy = 0; yy < H; yy ++, i ++) if (i & 1) fl_point(X + W, Y + yy); + for (xx = W; xx > 0; xx --, i ++) if (i & 1) fl_point(X + xx, Y + H); + for (yy = H; yy > 0; yy --, i ++) if (i & 1) fl_point(X, Y + yy); +#else + fl_line_style(FL_DOT); + fl_rect(X + Fl::box_dx(B), Y + Fl::box_dy(B), + W - Fl::box_dw(B) - 1, H - Fl::box_dh(B) - 1); + fl_line_style(FL_SOLID); +#endif // WIN32 +} + + +void Fl_Widget::activate() { + if (!active()) { + clear_flag(INACTIVE); + if (active_r()) { + redraw(); + redraw_label(); + handle(FL_ACTIVATE); + if (inside(Fl::focus())) Fl::focus()->take_focus(); + } + } +} + +void Fl_Widget::deactivate() { + if (active_r()) { + set_flag(INACTIVE); + redraw(); + redraw_label(); + handle(FL_DEACTIVATE); + fl_throw_focus(this); + } else { + set_flag(INACTIVE); + } +} + +int Fl_Widget::active_r() const { + for (const Fl_Widget* o = this; o; o = o->parent()) + if (!o->active()) return 0; + return 1; +} + +void Fl_Widget::show() { + if (!visible()) { + clear_flag(INVISIBLE); + if (visible_r()) { + redraw(); + redraw_label(); + handle(FL_SHOW); + if (inside(Fl::focus())) Fl::focus()->take_focus(); + } + } +} + +void Fl_Widget::hide() { + if (visible_r()) { + set_flag(INVISIBLE); + for (Fl_Widget *p = parent(); p; p = p->parent()) + if (p->box() || !p->parent()) {p->redraw(); break;} + handle(FL_HIDE); + fl_throw_focus(this); + } else { + set_flag(INVISIBLE); + } +} + +int Fl_Widget::visible_r() const { + for (const Fl_Widget* o = this; o; o = o->parent()) + if (!o->visible()) return 0; + return 1; +} + +// return true if widget is inside (or equal to) this: +// Returns false for null widgets. +int Fl_Widget::contains(const Fl_Widget *o) const { + for (; o; o = o->parent_) if (o == this) return 1; + return 0; +} + + +void +Fl_Widget::label(const char *a) { + if (flags() & COPIED_LABEL) { + // reassigning a copied label remains the same copied label + if (label_.value == a) + return; + free((void *)(label_.value)); + clear_flag(COPIED_LABEL); + } + label_.value=a; + redraw_label(); +} + + +void +Fl_Widget::copy_label(const char *a) { + if (flags() & COPIED_LABEL) free((void *)(label_.value)); + if (a) { + set_flag(COPIED_LABEL); + label_.value=strdup(a); + } else { + clear_flag(COPIED_LABEL); + label_.value=(char *)0; + } + redraw_label(); +} + + +// +// End of "$Id: Fl_Widget.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Window.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Window.cxx new file mode 100644 index 000000000..43c9f7fb3 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Window.cxx @@ -0,0 +1,179 @@ +// +// "$Id: Fl_Window.cxx 5251 2006-06-28 10:23:33Z matt $" +// +// Window widget class for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// The Fl_Window is a window in the fltk library. +// This is the system-independent portions. The huge amount of +// crap you need to do to communicate with X is in Fl_x.cxx, the +// equivalent (but totally different) crap for MSWindows is in Fl_win32.cxx + +#include +#include +#include +#include "flstring.h" + +#ifdef __APPLE_QUARTZ__ +#include +#endif + +void Fl_Window::_Fl_Window() { + type(FL_WINDOW); + box(FL_FLAT_BOX); + if (Fl::scheme_bg_) { + labeltype(FL_NORMAL_LABEL); + align(FL_ALIGN_CENTER | FL_ALIGN_INSIDE | FL_ALIGN_CLIP); + image(Fl::scheme_bg_); + } else { + labeltype(FL_NO_LABEL); + } + i = 0; + xclass_ = 0; + icon_ = 0; + iconlabel_ = 0; + resizable(0); + size_range_set = 0; + minw = maxw = minh = maxh = 0; + callback((Fl_Callback*)default_callback); +} + +Fl_Window::Fl_Window(int X,int Y,int W, int H, const char *l) +: Fl_Group(X, Y, W, H, l) { + cursor_default = FL_CURSOR_DEFAULT; + cursor_fg = FL_BLACK; + cursor_bg = FL_WHITE; + + _Fl_Window(); + set_flag(FL_FORCE_POSITION); +} + +Fl_Window::Fl_Window(int W, int H, const char *l) +// fix common user error of a missing end() with current(0): + : Fl_Group((Fl_Group::current(0),0), 0, W, H, l) { + cursor_default = FL_CURSOR_DEFAULT; + cursor_fg = FL_BLACK; + cursor_bg = FL_WHITE; + + _Fl_Window(); + clear_visible(); +} + +Fl_Window *Fl_Widget::window() const { + for (Fl_Widget *o = parent(); o; o = o->parent()) + if (o->type() >= FL_WINDOW) return (Fl_Window*)o; + return 0; +} + +int Fl_Window::x_root() const { + Fl_Window *p = window(); + if (p) return p->x_root() + x(); + return x(); +} + +int Fl_Window::y_root() const { + Fl_Window *p = window(); + if (p) return p->y_root() + y(); + return y(); +} + +void Fl_Window::draw() { + const char *savelabel = label(); + int saveflags = flags(); + int savex = x(); x(0); + int savey = y(); y(0); + // Make sure we don't draw the window title in the window background... + clear_flag(COPIED_LABEL); // do not free copied labels! + Fl_Widget::label(0); + Fl_Group::draw(); +#ifdef __APPLE_QUARTZ__ + if (!parent() && resizable() && (!size_range_set || minh!=maxh || minw!=maxw)) { + int dx = Fl::box_dw(box())-Fl::box_dx(box()); + int dy = Fl::box_dh(box())-Fl::box_dy(box()); + if (dx<=0) dx = 1; + if (dy<=0) dy = 1; + int x1 = w()-dx-1, x2 = x1, y1 = h()-dx-1, y2 = y1; + Fl_Color c[4] = { + color(), + fl_color_average(color(), FL_WHITE, 0.7f), + fl_color_average(color(), FL_BLACK, 0.6f), + fl_color_average(color(), FL_BLACK, 0.8f), + }; + int i; + for (i=dx; i<12; i++) { + fl_color(c[i&3]); + fl_line(x1--, y1, x2, y2--); + } + } +#endif + // Restore the label... + Fl_Widget::label(savelabel); + set_flag(saveflags); + y(savey); + x(savex); +} + +void Fl_Window::label(const char *name) { + label(name, iconlabel()); +} + +void Fl_Window::copy_label(const char *a) { + if (flags() & COPIED_LABEL) { + free((void *)label()); + clear_flag(COPIED_LABEL); + } + if (a) a = strdup(a); + label(a, iconlabel()); + set_flag(COPIED_LABEL); +} + + +void Fl_Window::iconlabel(const char *iname) { + uchar saveflags = flags(); + label(label(), iname); + set_flag(saveflags); +} + +// the Fl::atclose pointer is provided for back compatability. You +// can now just change the callback for the window instead. + +void Fl::default_atclose(Fl_Window* window, void* v) { + window->hide(); + Fl_Widget::default_callback(window, v); // put on Fl::read_queue() +} + +void (*Fl::atclose)(Fl_Window*, void*) = default_atclose; + +void Fl_Window::default_callback(Fl_Window* win, void* v) { + Fl::atclose(win, v); +} + +Fl_Window *Fl_Window::current() { + return current_; +} + + +// +// End of "$Id: Fl_Window.cxx 5251 2006-06-28 10:23:33Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Window_fullscreen.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Window_fullscreen.cxx new file mode 100644 index 000000000..cc30ad1a4 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Window_fullscreen.cxx @@ -0,0 +1,97 @@ +// +// "$Id: Fl_Window_fullscreen.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Fullscreen window support for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Turning the border on/off by changing the motif_wm_hints property +// works on Irix 4DWM. Does not appear to work for any other window +// manager. Fullscreen still works on some window managers (fvwm is one) +// because they allow the border to be placed off-screen. + +// Unfortunatly most X window managers ignore changes to the border +// and refuse to position the border off-screen, so attempting to make +// the window full screen will lose the size of the border off the +// bottom and right. + +#include +#include + +#ifdef __APPLE__ +#include +#endif + +void Fl_Window::border(int b) { + if (b) { + if (border()) return; + clear_flag(FL_NOBORDER); + } else { + if (!border()) return; + set_flag(FL_NOBORDER); + } +#ifdef WIN32 + // not yet implemented, but it's possible + // for full fullscreen we have to make the window topmost as well +#elif defined(__APPLE_QD__) + // warning: not implemented in Quickdraw/Carbon +#elif defined(__APPLE_QUARTZ__) + // warning: not implemented in Quartz/Carbon +#else + if (shown()) Fl_X::i(this)->sendxjunk(); +#endif +} + +void Fl_Window::fullscreen() { +#ifndef WIN32 + //this would clobber the fake wm, since it relies on the border flags to + //determine its thickness + border(0); +#endif +#if defined(__APPLE__) || defined(WIN32) + int sx, sy, sw, sh; + Fl::screen_xywh(sx, sy, sw, sh, x()+w()/2, y()+h()/2); + // if we are on the main screen, we will leave the system menu bar unobstructed + if (Fl::x()>=sx && Fl::y()>=sy && Fl::x()+Fl::w()<=sx+sw && Fl::y()+Fl::h()<=sy+sh) { + sx = Fl::x(); sy = Fl::y(); + sw = Fl::w(); sh = Fl::h(); + } + if (x()==sx) x(sx+1); // make sure that we actually execute the resize + resize(sx, sy, sw, sh); +#else + if (!x()) x(1); // force it to call XResizeWindow() + resize(0,0,Fl::w(),Fl::h()); +#endif +} + +void Fl_Window::fullscreen_off(int X,int Y,int W,int H) { + // this order produces less blinking on IRIX: + resize(X,Y,W,H); +#ifndef WIN32 + border(1); +#endif +} + +// +// End of "$Id: Fl_Window_fullscreen.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Window_hotspot.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Window_hotspot.cxx new file mode 100644 index 000000000..a551ce8ee --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Window_hotspot.cxx @@ -0,0 +1,100 @@ +// +// "$Id: Fl_Window_hotspot.cxx 5697 2007-02-13 14:38:43Z matt $" +// +// Common hotspot routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include + +void Fl_Window::hotspot(int X, int Y, int offscreen) { + int mx,my; + + // Update the screen position based on the mouse position. + Fl::get_mouse(mx,my); + X = mx-X; Y = my-Y; + + // If offscreen is 0 (the default), make sure that the window + // stays on the screen, if possible. + if (!offscreen) { + int scr_x, scr_y, scr_w, scr_h; + Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h); + + int top = 0; + int left = 0; + int right = 0; + int bottom = 0; + + if (border()) { +#ifdef WIN32 + if (size_range_set && (maxw != minw || maxh != minh)) { + left = right = GetSystemMetrics(SM_CXSIZEFRAME); + top = bottom = GetSystemMetrics(SM_CYSIZEFRAME); + } else { + left = right = GetSystemMetrics(SM_CXFIXEDFRAME); + top = bottom = GetSystemMetrics(SM_CYFIXEDFRAME); + } + top += GetSystemMetrics(SM_CYCAPTION); +#elif defined(__APPLE__) + top = 24; + left = 2; + right = 2; + bottom = 2; +#else + // Ensure border is on screen; these values are generic enough + // to work with many window managers, and are based on KDE defaults. + top = 20; + left = 4; + right = 4; + bottom = 8; +#endif + } + // now insure contents are on-screen (more important than border): + if (X+w()+right > scr_w-scr_x) X = scr_w-scr_x-right-w(); + if (X-left < scr_x) X = left; + if (Y+h()+bottom > scr_h-scr_y) Y = scr_h-scr_y-bottom-h(); + if (Y-top < scr_y) Y = top; + // make sure that we will force this position + if (X==x()) x(X-1); + } + + position(X,Y); +} + +void Fl_Window::hotspot(const Fl_Widget *o, int offscreen) { + int X = o->w()/2; + int Y = o->h()/2; + while (o != this && o) { + X += o->x(); Y += o->y(); + o = o->window(); + } + hotspot(X,Y,offscreen); +} + + +// +// End of "$Id: Fl_Window_hotspot.cxx 5697 2007-02-13 14:38:43Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Window_iconize.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Window_iconize.cxx new file mode 100644 index 000000000..5ad32f174 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Window_iconize.cxx @@ -0,0 +1,49 @@ +// +// "$Id: Fl_Window_iconize.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Window minification code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include + +extern char fl_show_iconic; // in Fl_x.cxx + +void Fl_Window::iconize() { + if (!shown()) { + fl_show_iconic = 1; + show(); + } else { +#ifdef WIN32 + ShowWindow(i->xid, SW_SHOWMINNOACTIVE); +#elif defined(__APPLE__) + CollapseWindow( i->xid, true ); +#else + XIconifyWindow(fl_display, i->xid, fl_screen); +#endif + } +} + +// +// End of "$Id: Fl_Window_iconize.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_Wizard.cxx b/plugins/zynaddsubfx/fltk/src/Fl_Wizard.cxx new file mode 100644 index 000000000..1a22d3175 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_Wizard.cxx @@ -0,0 +1,210 @@ +// +// "$Id: Fl_Wizard.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Fl_Wizard widget routines. +// +// Copyright 1997-2005 by Easy Software Products. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +// Contents: +// +// Fl_Wizard::Fl_Wizard() - Create an Fl_Wizard widget. +// Fl_Wizard::draw() - Draw the wizard border and visible child. +// Fl_Wizard::next() - Show the next child. +// Fl_Wizard::prev() - Show the previous child. +// Fl_Wizard::value() - Return the current visible child. +// Fl_Wizard::value() - Set the visible child. +// + +// +// Include necessary header files... +// + +#include +#include +#include + + +// +// 'Fl_Wizard::Fl_Wizard()' - Create an Fl_Wizard widget. +// + +Fl_Wizard::Fl_Wizard(int xx, // I - Lefthand position + int yy, // I - Upper position + int ww, // I - Width + int hh, // I - Height + const char *l) : // I - Label + Fl_Group(xx, yy, ww, hh, l) +{ + box(FL_THIN_UP_BOX); + + value_ = (Fl_Widget *)0; +} + + +// +// 'Fl_Wizard::draw()' - Draw the wizard border and visible child. +// + +void +Fl_Wizard::draw() +{ + Fl_Widget *kid; // Visible child + + + kid = value(); + + if (damage() & FL_DAMAGE_ALL) + { + // Redraw everything... + if (kid) + { + draw_box(box(), x(), y(), w(), h(), kid->color()); + draw_child(*kid); + } + else + draw_box(box(), x(), y(), w(), h(), color()); + + } + else if (kid) + update_child(*kid); +} + + +// +// 'Fl_Wizard::next()' - Show the next child. +// + +void +Fl_Wizard::next() +{ + int num_kids; + Fl_Widget * const *kids; + + + if ((num_kids = children()) == 0) + return; + + for (kids = array(); num_kids > 0; kids ++, num_kids --) + if ((*kids)->visible()) + break; + + if (num_kids > 1) + value(kids[1]); +} + + +// +// 'Fl_Wizard::prev()' - Show the previous child. +// + + +void +Fl_Wizard::prev() +{ + int num_kids; + Fl_Widget * const *kids; + + + if ((num_kids = children()) == 0) + return; + + for (kids = array(); num_kids > 0; kids ++, num_kids --) + if ((*kids)->visible()) + break; + + if (num_kids > 0 && num_kids < children()) + value(kids[-1]); +} + + +// +// 'Fl_Wizard::value()' - Return the current visible child. +// + +Fl_Widget * +Fl_Wizard::value() +{ + int num_kids; + Fl_Widget * const *kids; + Fl_Widget *kid; + + + if ((num_kids = children()) == 0) + return ((Fl_Widget *)0); + + for (kids = array(), kid = (Fl_Widget *)0; num_kids > 0; kids ++, num_kids --) + { + if ((*kids)->visible()) + { + if (kid) + (*kids)->hide(); + else + kid = *kids; + } + } + + if (!kid) + { + kids --; + kid = *kids; + kid->show(); + } + + return (kid); +} + + +// +// 'Fl_Wizard::value()' - Set the visible child. +// + +void +Fl_Wizard::value(Fl_Widget *kid) +{ + int num_kids; + Fl_Widget * const *kids; + + + if ((num_kids = children()) == 0) + return; + + for (kids = array(); num_kids > 0; kids ++, num_kids --) + { + if (*kids == kid) + { + if (!kid->visible()) + kid->show(); + } + else + (*kids)->hide(); + } + + // This will restore the mouse pointer to the window's default cursor + // whenever the wizard pane is changed. Otherwise text widgets that + // show the next pane may leave the cursor set to the I beam, etc... + if (window()) window()->cursor(FL_CURSOR_DEFAULT); +} + + +// +// End of "$Id: Fl_Wizard.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_XBM_Image.cxx b/plugins/zynaddsubfx/fltk/src/Fl_XBM_Image.cxx new file mode 100644 index 000000000..ce66683a6 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_XBM_Image.cxx @@ -0,0 +1,106 @@ +// +// "$Id: Fl_XBM_Image.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Fl_XBM_Image routines. +// +// Copyright 1997-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +// Contents: +// +// Fl_XBM_Image::Fl_XBM_Image() - Load an XBM file. +// + +// +// Include necessary header files... +// + +#include +#include +#include +#include +#include "flstring.h" + +// +// 'Fl_XBM_Image::Fl_XBM_Image()' - Load an XBM file. +// + +Fl_XBM_Image::Fl_XBM_Image(const char *name) : Fl_Bitmap((const char *)0,0,0) { + FILE *f; + uchar *ptr; + + if ((f = fopen(name, "rb")) == NULL) return; + + char buffer[1024]; + char junk[1024]; + int wh[2]; // width and height + int i; + for (i = 0; i<2; i++) { + for (;;) { + if (!fgets(buffer,1024,f)) { + fclose(f); + return; + } + int r = sscanf(buffer,"#define %s %d",junk,&wh[i]); + if (r >= 2) break; + } + } + + // skip to data array: + for (;;) { + if (!fgets(buffer,1024,f)) { + fclose(f); + return; + } + if (!strncmp(buffer,"static ",7)) break; + } + + // Allocate memory... + w(wh[0]); + h(wh[1]); + + int n = ((wh[0]+7)/8)*wh[1]; + array = new uchar[n]; + + // read the data: + for (i = 0, ptr = (uchar *)array; i < n;) { + if (!fgets(buffer,1024,f)) { + fclose(f); + return; + } + const char *a = buffer; + while (*a && i0) { + *ptr++ = (uchar)t; + i ++; + } + while (*a && *a++ != ','); + } + } + + fclose(f); +} + + +// +// End of "$Id: Fl_XBM_Image.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_XColor.H b/plugins/zynaddsubfx/fltk/src/Fl_XColor.H new file mode 100644 index 000000000..c0f893cd9 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_XColor.H @@ -0,0 +1,46 @@ +// +// "$Id: Fl_XColor.H 4288 2005-04-16 00:13:17Z mike $" +// +// X-specific color definitions for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2001 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include + +// one of these for each color in fltk's "colormap": +// if overlays are enabled, another one for the overlay +struct Fl_XColor { + unsigned char r,g,b; // actual color used by X + unsigned char mapped; // true when XAllocColor done + unsigned long pixel; // the X pixel to use +}; +extern Fl_XColor fl_xmap[/*overlay*/][256]; + +// mask & shifts to produce xcolor for truecolor visuals: +extern unsigned char fl_redmask, fl_greenmask, fl_bluemask; +extern int fl_redshift, fl_greenshift, fl_blueshift, fl_extrashift; + +// +// End of "$Id: Fl_XColor.H 4288 2005-04-16 00:13:17Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_XPM_Image.cxx b/plugins/zynaddsubfx/fltk/src/Fl_XPM_Image.cxx new file mode 100644 index 000000000..b50535f57 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_XPM_Image.cxx @@ -0,0 +1,131 @@ +// +// "$Id: Fl_XPM_Image.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Fl_XPM_Image routines. +// +// Copyright 1997-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// +// Contents: +// +// + +// +// Include necessary header files... +// + +#include +#include +#include +#include +#include "flstring.h" + + +// +// 'hexdigit()' - Convert a hex digit to an integer. +// + +static int hexdigit(int x) { // I - Hex digit... + if (isdigit(x)) return x-'0'; + if (isupper(x)) return x-'A'+10; + if (islower(x)) return x-'a'+10; + return 20; +} + +#define MAXSIZE 2048 +#define INITIALLINES 256 + +Fl_XPM_Image::Fl_XPM_Image(const char *name) : Fl_Pixmap((char *const*)0) { + FILE *f; + + if ((f = fopen(name, "rb")) == NULL) return; + + // read all the c-strings out of the file: + char** new_data = new char *[INITIALLINES]; + char** temp_data; + int malloc_size = INITIALLINES; + char buffer[MAXSIZE+20]; + int i = 0; + while (fgets(buffer,MAXSIZE+20,f)) { + if (buffer[0] != '\"') continue; + char *myp = buffer; + char *q = buffer+1; + while (*q != '\"' && myp < buffer+MAXSIZE) { + if (*q == '\\') switch (*++q) { + case '\r': + case '\n': + fgets(q,(buffer+MAXSIZE+20)-q,f); break; + case 0: + break; + case 'x': { + q++; + int n = 0; + for (int x = 0; x < 3; x++) { + int xd = hexdigit(*q); + if (xd > 15) break; + n = (n<<4)+xd; + q++; + } + *myp++ = n; + } break; + default: { + int c = *q++; + if (c>='0' && c<='7') { + c -= '0'; + for (int x=0; x<2; x++) { + int xd = hexdigit(*q); + if (xd>7) break; + c = (c<<3)+xd; + q++; + } + } + *myp++ = c; + } break; + } else { + *myp++ = *q++; + } + } + *myp++ = 0; + if (i >= malloc_size) { + temp_data = new char *[malloc_size + INITIALLINES]; + memcpy(temp_data, new_data, sizeof(char *) * malloc_size); + delete[] new_data; + new_data = temp_data; + malloc_size += INITIALLINES; + } + new_data[i] = new char[myp-buffer+1]; + memcpy(new_data[i], buffer,myp-buffer); + new_data[i][myp-buffer] = 0; + i++; + } + + fclose(f); + + data((const char **)new_data, i); + alloc_data = 1; + + measure(); +} + + +// +// End of "$Id: Fl_XPM_Image.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_abort.cxx b/plugins/zynaddsubfx/fltk/src/Fl_abort.cxx new file mode 100644 index 000000000..cc6571d2a --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_abort.cxx @@ -0,0 +1,102 @@ +// +// "$Id: Fl_abort.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Warning/error message code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// This method is in it's own source file so that stdlib and stdio +// do not need to be included in Fl.cxx: +// You can also override this by redefining all of these. + +#include +#include +#include +#include +#include "flstring.h" + +#ifdef WIN32 +# include + +static void warning(const char *, ...) { + // Show nothing for warnings under WIN32... +} + +static void error(const char *format, ...) { + va_list args; + char buf[1024]; + va_start(args, format); + vsnprintf(buf, 1024, format, args); + va_end(args); + MessageBox(0,buf,"Error",MB_ICONEXCLAMATION|MB_SYSTEMMODAL); +} + +static void fatal(const char *format, ...) { + va_list args; + char buf[1024]; + va_start(args, format); + vsnprintf(buf, 1024, format, args); + va_end(args); + MessageBox(0,buf,"Error",MB_ICONSTOP|MB_SYSTEMMODAL); + ::exit(1); +} + +#else + +static void warning(const char *format, ...) { + va_list args; + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + fputc('\n', stderr); + fflush(stderr); +} + +static void error(const char *format, ...) { + va_list args; + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + fputc('\n', stderr); + fflush(stderr); +} + +static void fatal(const char *format, ...) { + va_list args; + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + fputc('\n', stderr); + fflush(stderr); + ::exit(1); +} + +#endif + +void (*Fl::warning)(const char* format, ...) = ::warning; +void (*Fl::error)(const char* format, ...) = ::error; +void (*Fl::fatal)(const char* format, ...) = ::fatal; + +// +// End of "$Id: Fl_abort.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_add_idle.cxx b/plugins/zynaddsubfx/fltk/src/Fl_add_idle.cxx new file mode 100644 index 000000000..9321dd572 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_add_idle.cxx @@ -0,0 +1,100 @@ +// +// "$Id: Fl_add_idle.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Idle routine support for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Allows you to manage an arbitrary set of idle() callbacks. +// Replaces the older set_idle() call (which is used to implement this) + +#include + +struct idle_cb { + void (*cb)(void*); + void* data; + idle_cb *next; +}; + +// the callbacks are stored linked in a ring. last points at the one +// just called, first at the next to call. last->next == first. + +static idle_cb* first; +static idle_cb* last; +static idle_cb* freelist; + +static void call_idle() { + idle_cb* p = first; + last = p; first = p->next; + p->cb(p->data); // this may call add_idle() or remove_idle()! +} + +void Fl::add_idle(void (*cb)(void*), void* data) { + idle_cb* p = freelist; + if (p) freelist = p->next; + else p = new idle_cb; + p->cb = cb; + p->data = data; + if (first) { + last->next = p; + last = p; + p->next = first; + } else { + first = last = p; + p->next = p; + set_idle(call_idle); + } +} + +int Fl::has_idle(void (*cb)(void*), void* data) { + idle_cb* p = first; + if (!p) return 0; + for (;; p = p->next) { + if (p->cb == cb && p->data == data) return 1; + if (p==last) return 0; + } +} + +void Fl::remove_idle(void (*cb)(void*), void* data) { + idle_cb* p = first; + if (!p) return; + idle_cb* l = last; + for (;; p = p->next) { + if (p->cb == cb && p->data == data) break; + if (p==last) return; // not found + l = p; + } + if (l == p) { // only one + first = last = 0; + set_idle(0); + } else { + last = l; + first = l->next = p->next; + } + p->next = freelist; + freelist = p; +} + +// +// End of "$Id: Fl_add_idle.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_arg.cxx b/plugins/zynaddsubfx/fltk/src/Fl_arg.cxx new file mode 100644 index 000000000..b94ccc45e --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_arg.cxx @@ -0,0 +1,424 @@ +// +// "$Id: Fl_arg.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Optional argument initialization code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// OPTIONAL initialization code for a program using fltk. +// You do not need to call this! Feel free to make up your own switches. + +#include +#include +#include +#include +#include +#include +#include +#include "flstring.h" + +#if defined(WIN32) || defined(__APPLE__) +int XParseGeometry(const char*, int*, int*, unsigned int*, unsigned int*); +# define NoValue 0x0000 +# define XValue 0x0001 +# define YValue 0x0002 +# define WidthValue 0x0004 +# define HeightValue 0x0008 +# define AllValues 0x000F +# define XNegative 0x0010 +# define YNegative 0x0020 +#endif + +static int fl_match(const char *a, const char *s, int atleast = 1) { + const char *b = s; + while (*a && (*a == *b || tolower(*a) == *b)) {a++; b++;} + return !*a && b >= s+atleast; +} + +// flags set by previously parsed arguments: +extern char fl_show_iconic; // in Fl_x.cxx +static char arg_called; +static char return_i; +static const char *name; +static const char *geometry; +static const char *title; +// these are in Fl_get_system_colors and are set by the switches: +extern const char *fl_fg; +extern const char *fl_bg; +extern const char *fl_bg2; + +// consume a switch from argv. Returns number of words eaten, 0 on error: +int Fl::arg(int argc, char **argv, int &i) { + arg_called = 1; + const char *s = argv[i]; + + if (!s) {i++; return 1;} // something removed by calling program? + + // a word that does not start with '-', or a word after a '--', or + // the word '-' by itself all start the "non-switch arguments" to + // a program. Return 0 to indicate that we don't understand the + // word, but set a flag (return_i) so that args() will return at + // that point: + if (s[0] != '-' || s[1] == '-' || !s[1]) {return_i = 1; return 0;} + s++; // point after the dash + + if (fl_match(s, "iconic")) { + fl_show_iconic = 1; + i++; + return 1; + } else if (fl_match(s, "kbd")) { + Fl::visible_focus(1); + i++; + return 1; + } else if (fl_match(s, "nokbd", 3)) { + Fl::visible_focus(0); + i++; + return 1; + } else if (fl_match(s, "dnd", 2)) { + Fl::dnd_text_ops(1); + i++; + return 1; + } else if (fl_match(s, "nodnd", 3)) { + Fl::dnd_text_ops(0); + i++; + return 1; + } else if (fl_match(s, "tooltips", 2)) { + Fl_Tooltip::enable(); + i++; + return 1; + } else if (fl_match(s, "notooltips", 3)) { + Fl_Tooltip::disable(); + i++; + return 1; + } +#ifdef __APPLE__ + // The Finder application in MacOS X passes the "-psn_N_NNNNN" option + // to all apps... + else if (strncmp(s, "psn_", 4) == 0) { + i++; + return 1; + } +#endif // __APPLE__ + + const char *v = argv[i+1]; + if (i >= argc-1 || !v) + return 0; // all the rest need an argument, so if missing it is an error + + if (fl_match(s, "geometry")) { + + int flags, gx, gy; unsigned int gw, gh; + flags = XParseGeometry(v, &gx, &gy, &gw, &gh); + if (!flags) return 0; + geometry = v; + +#if !defined(WIN32) && !defined(__APPLE__) + } else if (fl_match(s, "display", 2)) { + Fl::display(v); +#endif + + } else if (fl_match(s, "title", 2)) { + title = v; + + } else if (fl_match(s, "name", 2)) { + name = v; + + } else if (fl_match(s, "bg2", 3) || fl_match(s, "background2", 11)) { + fl_bg2 = v; + + } else if (fl_match(s, "bg", 2) || fl_match(s, "background", 10)) { + fl_bg = v; + + } else if (fl_match(s, "fg", 2) || fl_match(s, "foreground", 10)) { + fl_fg = v; + + } else if (fl_match(s, "scheme", 1)) { + Fl::scheme(v); + + } else return 0; // unrecognized + + i += 2; + return 2; +} + +// consume all switches from argv. Returns number of words eaten. +// Returns zero on error. 'i' will either point at first word that +// does not start with '-', at the error word, or after a '--', or at +// argc. If your program does not take any word arguments you can +// report an error if i < argc. + +int Fl::args(int argc, char** argv, int& i, int (*cb)(int,char**,int&)) { + arg_called = 1; + i = 1; // skip argv[0] + while (i < argc) { + if (cb && cb(argc,argv,i)) continue; + if (!arg(argc,argv,i)) return return_i ? i : 0; + } + return i; +} + +// show a main window, use any parsed arguments +void Fl_Window::show(int argc, char **argv) { + if (argc && !arg_called) Fl::args(argc,argv); + + Fl::get_system_colors(); + +#if !defined(WIN32) && !defined(__APPLE__) + // Get defaults for drag-n-drop and focus... + const char *key = 0, *val; + + if (Fl::first_window()) key = Fl::first_window()->xclass(); + if (!key) key = "fltk"; + + val = XGetDefault(fl_display, key, "dndTextOps"); + if (val) Fl::dnd_text_ops(strcasecmp(val, "true") == 0 || + strcasecmp(val, "on") == 0 || + strcasecmp(val, "yes") == 0); + + val = XGetDefault(fl_display, key, "tooltips"); + if (val) Fl_Tooltip::enable(strcasecmp(val, "true") == 0 || + strcasecmp(val, "on") == 0 || + strcasecmp(val, "yes") == 0); + + val = XGetDefault(fl_display, key, "visibleFocus"); + if (val) Fl::visible_focus(strcasecmp(val, "true") == 0 || + strcasecmp(val, "on") == 0 || + strcasecmp(val, "yes") == 0); +#endif // !WIN32 && !__APPLE__ + + // set colors first, so background_pixel is correct: + static char beenhere; + if (!beenhere) { + if (geometry) { + int fl = 0, gx = x(), gy = y(); unsigned int gw = w(), gh = h(); + fl = XParseGeometry(geometry, &gx, &gy, &gw, &gh); + if (fl & XNegative) gx = Fl::w()-w()+gx; + if (fl & YNegative) gy = Fl::h()-h()+gy; + // int mw,mh; minsize(mw,mh); + // if (mw > gw) gw = mw; + // if (mh > gh) gh = mh; + Fl_Widget *r = resizable(); + if (!r) resizable(this); + // for WIN32 we assumme window is not mapped yet: + if (fl & (XValue | YValue)) + x(-1), resize(gx,gy,gw,gh); + else + size(gw,gh); + resizable(r); + } + } + + // set the class, which is used by X version of get_system_colors: + if (name) {xclass(name); name = 0;} + else if (!xclass()) xclass(fl_filename_name(argv[0])); + + if (title) {label(title); title = 0;} + else if (!label()) label(xclass()); + + if (!beenhere) { + beenhere = 1; + Fl::scheme(Fl::scheme()); // opens display! May call Fl::fatal() + } + + // Show the window AFTER we have set the colors and scheme. + show(); + +#if !defined(WIN32) && !defined(__APPLE__) + // set the command string, used by state-saving window managers: + int j; + int n=0; for (j=0; jx{+-}{+-}", where + * width, height, xoffset, and yoffset are unsigned integers. + * Example: "=80x24+300-49" + * The equal sign is optional. + * It returns a bitmask that indicates which of the four values + * were actually found in the string. For each value found, + * the corresponding argument is updated; for each value + * not found, the corresponding argument is left unchanged. + */ + +static int ReadInteger(char* string, char** NextString) +{ + register int Result = 0; + int Sign = 1; + + if (*string == '+') + string++; + else if (*string == '-') { + string++; + Sign = -1; + } + for (; (*string >= '0') && (*string <= '9'); string++) { + Result = (Result * 10) + (*string - '0'); + } + *NextString = string; + if (Sign >= 0) + return (Result); + else + return (-Result); +} + +int XParseGeometry(const char* string, int* x, int* y, + unsigned int* width, unsigned int* height) +{ + int mask = NoValue; + register char *strind; + unsigned int tempWidth = 0, tempHeight = 0; + int tempX = 0, tempY = 0; + char *nextCharacter; + + if ( (string == NULL) || (*string == '\0')) return(mask); + if (*string == '=') + string++; /* ignore possible '=' at beg of geometry spec */ + + strind = (char *)string; + if (*strind != '+' && *strind != '-' && *strind != 'x') { + tempWidth = ReadInteger(strind, &nextCharacter); + if (strind == nextCharacter) + return (0); + strind = nextCharacter; + mask |= WidthValue; + } + + if (*strind == 'x' || *strind == 'X') { + strind++; + tempHeight = ReadInteger(strind, &nextCharacter); + if (strind == nextCharacter) + return (0); + strind = nextCharacter; + mask |= HeightValue; + } + + if ((*strind == '+') || (*strind == '-')) { + if (*strind == '-') { + strind++; + tempX = -ReadInteger(strind, &nextCharacter); + if (strind == nextCharacter) + return (0); + strind = nextCharacter; + mask |= XNegative; + + } else { + strind++; + tempX = ReadInteger(strind, &nextCharacter); + if (strind == nextCharacter) + return(0); + strind = nextCharacter; + } + mask |= XValue; + if ((*strind == '+') || (*strind == '-')) { + if (*strind == '-') { + strind++; + tempY = -ReadInteger(strind, &nextCharacter); + if (strind == nextCharacter) + return(0); + strind = nextCharacter; + mask |= YNegative; + + } else { + strind++; + tempY = ReadInteger(strind, &nextCharacter); + if (strind == nextCharacter) + return(0); + strind = nextCharacter; + } + mask |= YValue; + } + } + + /* If strind isn't at the end of the string the it's an invalid + geometry specification. */ + + if (*strind != '\0') return (0); + + if (mask & XValue) + *x = tempX; + if (mask & YValue) + *y = tempY; + if (mask & WidthValue) + *width = tempWidth; + if (mask & HeightValue) + *height = tempHeight; + return (mask); +} + +#endif // ifdef WIN32 + +// +// End of "$Id: Fl_arg.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_compose.cxx b/plugins/zynaddsubfx/fltk/src/Fl_compose.cxx new file mode 100644 index 000000000..422f4e37d --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_compose.cxx @@ -0,0 +1,223 @@ +// +// "$Id: Fl_compose.cxx 5211 2006-06-19 07:43:39Z matt $" +// +// Character compose processing for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include + +// +// MRS: Uncomment the following define to get the original (pre-1.1.2) +// dead key support code. The original code apparently did not +// work on Belgian keyboards. +// + +//#define OLD_DEAD_KEY_CODE + + +#ifdef __APPLE__ + +static const char* const compose_pairs = +":A*A,C'E~N:O:U'a`a^a:a~a*a,c'e`e" +"^e:e'i`i^i:i~n'o`o^o:o~o'u`u^u:u" +"+ o /c# SS* P|ssrOcOTM' : !=AE/O" +"oo+-<=>=Y=mudtSgPipiS a dgOmaeo/" +"? ! !!v-f ~~Dt<<>>.. `A~A~OOEoe" +"- --''``\"'\"`:-^V:y:Y//E=< > fifl" +"++..,,_\"%%^A^E'A:E`E'I^I:I`I'O^O" +"mc`O'U^U`U||^ ~^_ u . * , ~-; v "; + +#else + +static const char* const compose_pairs = +"=E _'f _\"..+ ++^ %%^S< OE ^Z ^''^^\"\"^-*- --~ TM^s> oe ^z:Y" +" ! % # $ y=| & : c a <<~ - r _ * +-2 3 ' u p . , 1 o >>141234? " +"`A'A^A~A:A*AAE,C`E'E^E:E`I'I^I:I-D~N`O'O^O~O:Ox O/`U'U^U:U'YTHss" +"`a'a^a~a:a*aae,c`e'e^e:e`i'i^i:i-d~n`o'o^o~o:o-:o/`u'u^u:u'yth:y"; + +#endif + +#if !defined(WIN32) && defined(OLD_DEAD_KEY_CODE) // X only +// X dead-key lookup table. This turns a dead-key keysym into the +// first of two characters for one of the compose sequences. These +// keysyms start at 0xFE50. +// Win32 handles the dead keys before FLTK can see them. This is +// unfortunate, because you don't get the preview effect. +static char dead_keys[] = { + '`', // XK_dead_grave + '\'', // XK_dead_acute + '^', // XK_dead_circumflex + '~', // XK_dead_tilde + '_', // XK_dead_macron + 0, // XK_dead_breve + '.', // XK_dead_abovedot + ':', // XK_dead_diaeresis + '*', // XK_dead_abovering + 0, // XK_dead_doubleacute + 'v', // XK_dead_caron + ',' // XK_dead_cedilla +// 0, // XK_dead_ogonek +// 0, // XK_dead_iota +// 0, // XK_dead_voiced_sound +// 0, // XK_dead_semivoiced_sound +// 0 // XK_dead_belowdot +}; +#endif // !WIN32 && OLD_DEAD_KEY_CODE + +int Fl::compose_state = 0; + +int Fl::compose(int& del) { + + del = 0; + unsigned char ascii = (unsigned)e_text[0]; + + // Alt+letters are reserved for shortcuts. But alt+foreign letters + // has to be allowed, because some key layouts require alt to be held + // down in order to type them... + // + // OSX users sometimes need to hold down ALT for keys, so we only check + // for META on OSX... +#ifdef __APPLE__ + if ((e_state & FL_META) && !(ascii & 128)) return 0; +#else + if ((e_state & (FL_ALT|FL_META)) && !(ascii & 128)) return 0; +#endif // __APPLE__ + + if (compose_state == 1) { // after the compose key + if ( // do not get distracted by any modifier keys + e_keysym==FL_Shift_L|| + e_keysym==FL_Shift_R || + e_keysym==FL_Alt_L || + e_keysym==FL_Alt_R || + e_keysym==FL_Meta_L || + e_keysym==FL_Meta_R || + e_keysym==FL_Control_R || + e_keysym==FL_Control_L || + e_keysym==FL_Menu + ) return 0; + + if (ascii == ' ') { // space turns into nbsp +#ifdef __APPLE__ + e_text[0] = char(0xCA); +#else + e_text[0] = char(0xA0); +#endif + compose_state = 0; + return 1; + } else if (ascii < ' ' || ascii == 127) { + compose_state = 0; + return 0; + } + + // see if it is either character of any pair: + for (const char *p = compose_pairs; *p; p += 2) + if (p[0] == ascii || p[1] == ascii) { + if (p[1] == ' ') e_text[0] = (p-compose_pairs)/2+0x80; + compose_state = ascii; + return 1; + } + + if (e_length) { // compose key also "quotes" control characters + compose_state = 0; + return 1; + } + + } else if (compose_state) { // second character of compose + + char c1 = char(compose_state); // retrieve first character +#ifdef __APPLE__ + if ( (c1==0x60 && ascii==0xab) || (c1==0x27 && ascii==0x60)) { + del = 1; + compose_state = '^'; + e_text[0] = 0xf6; + return 1; + } + if (ascii==' ') { + del = 0; + compose_state = 0; + return 0; + } +#endif + // now search for the pair in either order: + for (const char *p = compose_pairs; *p; p += 2) { + if (p[0] == ascii && p[1] == c1 || p[1] == ascii && p[0] == c1) { + e_text[0] = (p-compose_pairs)/2+0x80; + del = 1; // delete the old character and insert new one + compose_state = 0; + return 1; + } + } + + } + + int i = e_keysym; + + // See if they type the compose prefix key: + if (i == FL_Control_R || i == 0xff20/* Multi-Key */) { + compose_state = 1; + return 1; + } + +#ifdef WIN32 +#elif (defined __APPLE__) + if (e_state & 0x40000000) { + if (ascii<0x80) + compose_state = ascii; + else + compose_state = compose_pairs[(ascii-0x80)*2]; + return 1; + } +#else + // See if they typed a dead key. This gets it into the same state as + // typing prefix+accent: + if (i >= 0xfe50 && i <= 0xfe5b) { +# ifdef OLD_DEAD_KEY_CODE + ascii = dead_keys[i-0xfe50]; + for (const char *p = compose_pairs; *p; p += 2) + if (p[0] == ascii) { + compose_state = ascii; + return 1; + } +# else + ascii = e_text[0]; + for (const char *p = compose_pairs; *p; p += 2) + if (p[0] == ascii || + (p[1] == ' ' && (p - compose_pairs) / 2 + 0x80 == ascii)) { + compose_state = p[0]; + return 1; + } +# endif // OLD_DEAD_KEY_CODE + compose_state = 0; + return 1; + } +#endif + + // Only insert non-control characters: + if (e_length && (ascii & ~31 && ascii!=127)) {compose_state = 0; return 1;} + + return 0; +} + + + diff --git a/plugins/zynaddsubfx/fltk/src/Fl_display.cxx b/plugins/zynaddsubfx/fltk/src/Fl_display.cxx new file mode 100644 index 000000000..7ba19f7ac --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_display.cxx @@ -0,0 +1,54 @@ +// +// "$Id: Fl_display.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Display function for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Startup method to set what display to use. +// Using setenv makes programs that are exec'd use the same display. + +#include +#include +#include "flstring.h" + +void Fl::display(const char *d) { +#if defined(__APPLE__) || defined(WIN32) + (void)d; +#else + static char e[1024]; + strcpy(e,"DISPLAY="); + strlcat(e,d,sizeof(e)); + for (char *c = e+8; *c!=':'; c++) { + if (!*c) { + strlcat(e,":0.0",sizeof(e)); + break; + } + } + putenv(e); +#endif // __APPLE__ +} + +// +// End of "$Id: Fl_display.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_get_key.cxx b/plugins/zynaddsubfx/fltk/src/Fl_get_key.cxx new file mode 100644 index 000000000..4b8d505bf --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_get_key.cxx @@ -0,0 +1,69 @@ +// +// "$Id: Fl_get_key.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Keyboard state routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifdef WIN32 +# include "Fl_get_key_win32.cxx" +#elif defined(__APPLE__) +# include "Fl_get_key_mac.cxx" +#else + +// Return the current state of a key. This is the X version. I identify +// keys (mostly) by the X keysym. So this turns the keysym into a keycode +// and looks it up in the X key bit vector, which Fl_x.cxx keeps track of. + +# include +# include + +extern char fl_key_vector[32]; // in Fl_x.cxx + +int Fl::event_key(int k) { + if (k > FL_Button && k <= FL_Button+8) + return Fl::event_state(8<<(k-FL_Button)); + int i; +# ifdef __sgi + // get some missing PC keyboard keys: + if (k == FL_Meta_L) i = 147; + else if (k == FL_Meta_R) i = 148; + else if (k == FL_Menu) i = 149; + else +# endif + i = XKeysymToKeycode(fl_display, k); + if (i==0) return 0; + return fl_key_vector[i/8] & (1 << (i%8)); +} + +int Fl::get_key(int k) { + fl_open_display(); + XQueryKeymap(fl_display, fl_key_vector); + return event_key(k); +} + +#endif + +// +// End of "$Id: Fl_get_key.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_get_key_mac.cxx b/plugins/zynaddsubfx/fltk/src/Fl_get_key_mac.cxx new file mode 100644 index 000000000..d0c740204 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_get_key_mac.cxx @@ -0,0 +1,110 @@ +// +// "$Id: Fl_get_key_mac.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// MacOS keyboard state routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Return the current state of a key. Keys are named by fltk symbols, +// which are actually X keysyms. So this has to translate to macOS +// symbols. + +#include +#include +#include + +// convert an FLTK (X) keysym to a MacOS symbol: +// See also the inverse converter in Fl_mac.cxx +// This table is in numeric order by FLTK symbol order for binary search: + +static const struct {unsigned short vk, fltk;} vktab[] = { + { 49, ' ' }, { 39, '\'' }, { 43, ',' }, { 27, '-' }, { 47, '.' }, { 44, '/' }, + { 29, '0' }, { 18, '1' }, { 19, '2' }, { 20, '3' }, + { 21, '4' }, { 23, '5' }, { 22, '6' }, { 26, '7' }, + { 28, '8' }, { 25, '9' }, { 41, ';' }, { 24, '=' }, + { 0, 'A' }, { 11, 'B' }, { 8, 'C' }, { 2, 'D' }, + { 14, 'E' }, { 3, 'F' }, { 5, 'G' }, { 4, 'H' }, + { 34, 'I' }, { 38, 'J' }, { 40, 'K' }, { 37, 'L' }, + { 46, 'M' }, { 45, 'N' }, { 31, 'O' }, { 35, 'P' }, + { 12, 'Q' }, { 15, 'R' }, { 1, 'S' }, { 17, 'T' }, + { 32, 'U' }, { 9, 'V' }, { 13, 'W' }, { 7, 'X' }, + { 16, 'Y' }, { 6, 'Z' }, + { 33, '[' }, { 30, ']' }, { 50, '`' }, { 42, '|' }, + { 51, FL_BackSpace }, { 48, FL_Tab }, { 36, FL_Enter }, { 127, FL_Pause }, + { 107, FL_Scroll_Lock }, { 53, FL_Escape }, { 0x73, FL_Home }, { 123, FL_Left }, + { 126, FL_Up }, { 124, FL_Right }, { 125, FL_Down }, { 0x74, FL_Page_Up }, + { 0x79, FL_Page_Down }, { 119, FL_End }, { 0x71, FL_Print }, { 127, FL_Insert }, + { 0x6e, FL_Menu }, { 114, FL_Help }, { 0x47, FL_Num_Lock }, + { 76, FL_KP_Enter }, { 67, FL_KP+'*' }, { 69, FL_KP+'+'}, { 78, FL_KP+'-' }, { 65, FL_KP+'.' }, { 75, FL_KP+'/' }, + { 82, FL_KP+'0' }, { 83, FL_KP+'1' }, { 84, FL_KP+'2' }, { 85, FL_KP+'3' }, + { 86, FL_KP+'4' }, { 87, FL_KP+'5' }, { 88, FL_KP+'6' }, { 89, FL_KP+'7' }, + { 91, FL_KP+'8' }, { 92, FL_KP+'9' }, { 81, FL_KP+'=' }, + { 0x7a, FL_F+1 }, { 0x78, FL_F+2 }, { 0x63, FL_F+3 }, { 0x76, FL_F+4 }, + { 0x60, FL_F+5 }, { 0x61, FL_F+6 }, { 0x62, FL_F+7 }, { 0x64, FL_F+8 }, + { 0x65, FL_F+9 }, { 0x6D, FL_F+10 }, { 0x67, FL_F+11 }, { 0x6f, FL_F+12 }, + { 56, FL_Shift_L }, { 56, FL_Shift_R }, { 59, FL_Control_L }, { 59, FL_Control_R }, + { 57, FL_Caps_Lock }, { 55, FL_Meta_L }, { 55, FL_Meta_R }, + { 58, FL_Alt_L }, { 58, FL_Alt_R }, { 0x75, FL_Delete }, +}; + +static int fltk2mac(int fltk) { + int a = 0; + int b = sizeof(vktab)/sizeof(*vktab); + while (a < b) { + int c = (a+b)/2; + if (vktab[c].fltk == fltk) return vktab[c].vk; + if (vktab[c].fltk < fltk) a = c+1; else b = c; + } + return 127; +} + +//: returns true, if that key was pressed during the last event +int Fl::event_key(int k) { + return get_key(k); +} + +#include + +//: returns true, if that key is pressed right now +int Fl::get_key(int k) { + KeyMap foo; + GetKeys(foo); +#ifdef MAC_TEST_FOR_KEYCODES + static int cnt = 0; + if (cnt++>1024) { + cnt = 0; + printf("%08x %08x %08x %08x\n", (ulong*)(foo)[3], (ulong*)(foo)[2], (ulong*)(foo)[1], (ulong*)(foo)[0]); + } +#endif + unsigned char *b = (unsigned char*)foo; + // KP_Enter can be at different locations for Powerbooks vs. desktop Macs + if (k==FL_KP_Enter) { + return (((b[0x34>>3]>>(0x34&7))&1)||((b[0x4c>>3]>>(0x4c&7))&1)); + } + int i = fltk2mac(k); + return (b[i>>3]>>(i&7))&1; +} + +// +// End of "$Id: Fl_get_key_mac.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_get_key_win32.cxx b/plugins/zynaddsubfx/fltk/src/Fl_get_key_win32.cxx new file mode 100644 index 000000000..3153fdbfc --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_get_key_win32.cxx @@ -0,0 +1,138 @@ +// +// "$Id: Fl_get_key_win32.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// WIN32 keyboard state routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Return the current state of a key. Keys are named by fltk symbols, +// which are actually X keysyms. So this has to translate to MSWindows +// VK_x symbols. + +#include +#include + +// convert an Fltk (X) keysym to a MSWindows VK symbol: +// See also the inverse converter in Fl_win32.cxx +// This table is in numeric order by Fltk symbol order for binary search: + +static const struct {unsigned short vk, fltk;} vktab[] = { + {VK_SPACE, ' '}, + {'1', '!'}, + {0xde, '\"'}, + {'3', '#'}, + {'4', '$'}, + {'5', '%'}, + {'7', '&'}, + {0xde, '\''}, + {'9', '('}, + {'0', ')'}, + {'8', '*'}, + {0xbb, '+'}, + {0xbc, ','}, + {0xbd, '-'}, + {0xbe, '.'}, + {0xbf, '/'}, + {0xba, ':'}, + {0xba, ';'}, + {0xbc, '<'}, + {0xbb, '='}, + {0xbe, '>'}, + {0xbf, '?'}, + {'2', '@'}, + {0xdb, '['}, + {0xdc, '\\'}, + {0xdd, ']'}, + {'6', '^'}, + {0xbd, '_'}, + {0xc0, '`'}, + {0xdb, '{'}, + {0xdc, '|'}, + {0xdd, '}'}, + {0xc0, '~'}, + {VK_BACK, FL_BackSpace}, + {VK_TAB, FL_Tab}, + {VK_CLEAR, 0xff0b/*XK_Clear*/}, + {VK_RETURN, FL_Enter}, + {VK_PAUSE, FL_Pause}, + {VK_SCROLL, FL_Scroll_Lock}, + {VK_ESCAPE, FL_Escape}, + {VK_HOME, FL_Home}, + {VK_LEFT, FL_Left}, + {VK_UP, FL_Up}, + {VK_RIGHT, FL_Right}, + {VK_DOWN, FL_Down}, + {VK_PRIOR, FL_Page_Up}, + {VK_NEXT, FL_Page_Down}, + {VK_END, FL_End}, + {VK_SNAPSHOT, FL_Print}, + {VK_INSERT, FL_Insert}, + {VK_APPS, FL_Menu}, + {VK_NUMLOCK, FL_Num_Lock}, +//{VK_???, FL_KP_Enter}, + {VK_MULTIPLY, FL_KP+'*'}, + {VK_ADD, FL_KP+'+'}, + {VK_SUBTRACT, FL_KP+'-'}, + {VK_DECIMAL, FL_KP+'.'}, + {VK_DIVIDE, FL_KP+'/'}, + {VK_LSHIFT, FL_Shift_L}, + {VK_RSHIFT, FL_Shift_R}, + {VK_LCONTROL, FL_Control_L}, + {VK_RCONTROL, FL_Control_R}, + {VK_CAPITAL, FL_Caps_Lock}, + {VK_LWIN, FL_Meta_L}, + {VK_RWIN, FL_Meta_R}, + {VK_LMENU, FL_Alt_L}, + {VK_RMENU, FL_Alt_R}, + {VK_DELETE, FL_Delete} +}; + +static int fltk2ms(int fltk) { + if (fltk >= '0' && fltk <= '9') return fltk; + if (fltk >= 'A' && fltk <= 'Z') return fltk; + if (fltk >= 'a' && fltk <= 'z') return fltk-('a'-'A'); + if (fltk > FL_F && fltk <= FL_F+16) return fltk-(FL_F-(VK_F1-1)); + if (fltk >= FL_KP+'0' && fltk<=FL_KP+'9') return fltk-(FL_KP+'0'-VK_NUMPAD0); + int a = 0; + int b = sizeof(vktab)/sizeof(*vktab); + while (a < b) { + int c = (a+b)/2; + if (vktab[c].fltk == fltk) return vktab[c].vk; + if (vktab[c].fltk < fltk) a = c+1; else b = c; + } + return 0; +} + +int Fl::event_key(int k) { + return GetKeyState(fltk2ms(k))&~1; +} + +int Fl::get_key(int k) { + uchar foo[256]; + GetKeyboardState(foo); + return foo[fltk2ms(k)]&~1; +} + +// +// End of "$Id: Fl_get_key_win32.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_get_system_colors.cxx b/plugins/zynaddsubfx/fltk/src/Fl_get_system_colors.cxx new file mode 100644 index 000000000..094f9c89c --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_get_system_colors.cxx @@ -0,0 +1,386 @@ +// +// "$Id: Fl_get_system_colors.cxx 5699 2007-02-20 17:02:41Z matt $" +// +// System color support for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2006 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include +#include "flstring.h" +#include +#include +#include +#include +#include "tile.xpm" + +#if defined(__APPLE__) && defined(__MWERKS__) +extern "C" int putenv(const char*); +#endif // __APPLE__ && __MWERKS__ + +#if defined(WIN32) && !defined(__CYGWIN__) && !defined(__WATCOMC__) +// Visual C++ 2005 incorrectly displays a warning about the use of POSIX APIs +// on Windows, which is supposed to be POSIX compliant... +# define putenv _putenv +#endif // WIN32 && !__CYGWIN__ + +static char fl_bg_set = 0; +static char fl_bg2_set = 0; +static char fl_fg_set = 0; + + +void Fl::background(uchar r, uchar g, uchar b) { + fl_bg_set = 1; + + // replace the gray ramp so that FL_GRAY is this color + if (!r) r = 1; else if (r==255) r = 254; + double powr = log(r/255.0)/log((FL_GRAY-FL_GRAY_RAMP)/(FL_NUM_GRAY-1.0)); + if (!g) g = 1; else if (g==255) g = 254; + double powg = log(g/255.0)/log((FL_GRAY-FL_GRAY_RAMP)/(FL_NUM_GRAY-1.0)); + if (!b) b = 1; else if (b==255) b = 254; + double powb = log(b/255.0)/log((FL_GRAY-FL_GRAY_RAMP)/(FL_NUM_GRAY-1.0)); + for (int i = 0; i < FL_NUM_GRAY; i++) { + double gray = i/(FL_NUM_GRAY-1.0); + Fl::set_color(fl_gray_ramp(i), + uchar(pow(gray,powr)*255+.5), + uchar(pow(gray,powg)*255+.5), + uchar(pow(gray,powb)*255+.5)); + } +} + +void Fl::foreground(uchar r, uchar g, uchar b) { + fl_fg_set = 1; + + Fl::set_color(FL_FOREGROUND_COLOR,r,g,b); +} + +void Fl::background2(uchar r, uchar g, uchar b) { + fl_bg2_set = 1; + + Fl::set_color(FL_BACKGROUND2_COLOR,r,g,b); + Fl::set_color(FL_FOREGROUND_COLOR, + get_color(fl_contrast(FL_FOREGROUND_COLOR,FL_BACKGROUND2_COLOR))); +} + +// these are set by Fl::args() and override any system colors: +const char *fl_fg = NULL; +const char *fl_bg = NULL; +const char *fl_bg2 = NULL; + +static void set_selection_color(uchar r, uchar g, uchar b) { + Fl::set_color(FL_SELECTION_COLOR,r,g,b); +} + +#if defined(WIN32) || defined(__APPLE__) + +# include +// simulation of XParseColor: +int fl_parse_color(const char* p, uchar& r, uchar& g, uchar& b) { + if (*p == '#') p++; + int n = strlen(p); + int m = n/3; + const char *pattern = 0; + switch(m) { + case 1: pattern = "%1x%1x%1x"; break; + case 2: pattern = "%2x%2x%2x"; break; + case 3: pattern = "%3x%3x%3x"; break; + case 4: pattern = "%4x%4x%4x"; break; + default: return 0; + } + int R,G,B; if (sscanf(p,pattern,&R,&G,&B) != 3) return 0; + switch(m) { + case 1: R *= 0x11; G *= 0x11; B *= 0x11; break; + case 3: R >>= 4; G >>= 4; B >>= 4; break; + case 4: R >>= 8; G >>= 8; B >>= 8; break; + } + r = (uchar)R; g = (uchar)G; b = (uchar)B; + return 1; +} +#else +// Wrapper around XParseColor... +int fl_parse_color(const char* p, uchar& r, uchar& g, uchar& b) { + XColor x; + if (!fl_display) fl_open_display(); + if (XParseColor(fl_display, fl_colormap, p, &x)) { + r = (uchar)(x.red>>8); + g = (uchar)(x.green>>8); + b = (uchar)(x.blue>>8); + return 1; + } else return 0; +} +#endif // WIN32 || __APPLE__ + +#if defined(WIN32) +static void +getsyscolor(int what, const char* arg, void (*func)(uchar,uchar,uchar)) +{ + if (arg) { + uchar r,g,b; + if (!fl_parse_color(arg, r,g,b)) + Fl::error("Unknown color: %s", arg); + else + func(r,g,b); + } else { + DWORD x = GetSysColor(what); + func(uchar(x&255), uchar(x>>8), uchar(x>>16)); + } +} + +void Fl::get_system_colors() { + if (!fl_bg2_set) getsyscolor(COLOR_WINDOW, fl_bg2,Fl::background2); + if (!fl_fg_set) getsyscolor(COLOR_WINDOWTEXT, fl_fg, Fl::foreground); + if (!fl_bg_set) getsyscolor(COLOR_BTNFACE, fl_bg, Fl::background); + getsyscolor(COLOR_HIGHLIGHT, 0, set_selection_color); +} + +#elif defined(__APPLE__) +// MacOS X currently supports two color schemes - Blue and Graphite. +// Since we aren't emulating the Aqua interface (even if Apple would +// let us), we use some defaults that are similar to both. The +// Fl::scheme("plastic") color/box scheme provides a usable Aqua-like +// look-n-feel... +void Fl::get_system_colors() +{ + fl_open_display(); + + if (!fl_bg2_set) background2(0xff, 0xff, 0xff); + if (!fl_fg_set) foreground(0, 0, 0); + if (!fl_bg_set) background(0xd8, 0xd8, 0xd8); + +#if 0 + // this would be the correct code, but it does not run on all versions + // of OS X. Also, setting a bright selection color would require + // some updates in Fl_Adjuster and Fl_Help_Browser + OSStatus err; + RGBColor c; + err = GetThemeBrushAsColor(kThemeBrushPrimaryHighlightColor, 24, true, &c); + if (err) + set_selection_color(0x00, 0x00, 0x80); + else + set_selection_color(c.red, c.green, c.blue); +#else + set_selection_color(0x00, 0x00, 0x80); +#endif +} +#else + +// Read colors that KDE writes to the xrdb database. + +// XGetDefault does not do the expected thing: it does not like +// periods in either word. Therefore it cannot match class.Text.background. +// However *.Text.background is matched by pretending the program is "Text". +// But this will also match *.background if there is no *.Text.background +// entry, requiring users to put in both (unless they want the text fields +// the same color as the windows). + +static void +getsyscolor(const char *key1, const char* key2, const char *arg, const char *defarg, void (*func)(uchar,uchar,uchar)) +{ + if (!arg) { + arg = XGetDefault(fl_display, key1, key2); + if (!arg) arg = defarg; + } + XColor x; + if (!XParseColor(fl_display, fl_colormap, arg, &x)) + Fl::error("Unknown color: %s", arg); + else + func(x.red>>8, x.green>>8, x.blue>>8); +} + +void Fl::get_system_colors() +{ + fl_open_display(); + const char* key1 = 0; + if (Fl::first_window()) key1 = Fl::first_window()->xclass(); + if (!key1) key1 = "fltk"; + if (!fl_bg2_set) getsyscolor("Text","background", fl_bg2, "#ffffff", Fl::background2); + if (!fl_fg_set) getsyscolor(key1, "foreground", fl_fg, "#000000", Fl::foreground); + if (!fl_bg_set) getsyscolor(key1, "background", fl_bg, "#c0c0c0", Fl::background); + getsyscolor("Text", "selectBackground", 0, "#000080", set_selection_color); +} + +#endif + + +//// Simple implementation of 2.0 Fl::scheme() interface... +#define D1 BORDER_WIDTH +#define D2 (BORDER_WIDTH+BORDER_WIDTH) + +extern void fl_up_box(int, int, int, int, Fl_Color); +extern void fl_down_box(int, int, int, int, Fl_Color); +extern void fl_thin_up_box(int, int, int, int, Fl_Color); +extern void fl_thin_down_box(int, int, int, int, Fl_Color); +extern void fl_round_up_box(int, int, int, int, Fl_Color); +extern void fl_round_down_box(int, int, int, int, Fl_Color); + +extern void fl_up_frame(int, int, int, int, Fl_Color); +extern void fl_down_frame(int, int, int, int, Fl_Color); +extern void fl_thin_up_frame(int, int, int, int, Fl_Color); +extern void fl_thin_down_frame(int, int, int, int, Fl_Color); + +const char *Fl::scheme_ = (const char *)0; +Fl_Image *Fl::scheme_bg_ = (Fl_Image *)0; + +static Fl_Pixmap tile(tile_xpm); + +int Fl::scheme(const char *s) { + if (!s) { + if ((s = getenv("FLTK_SCHEME")) == NULL) { +#if !defined(WIN32) && !defined(__APPLE__) + const char* key = 0; + if (Fl::first_window()) key = Fl::first_window()->xclass(); + if (!key) key = "fltk"; + fl_open_display(); + s = XGetDefault(fl_display, key, "scheme"); +#endif // !WIN32 && !__APPLE__ + } + } + + if (s) { + if (!strcasecmp(s, "none") || !strcasecmp(s, "base") || !*s) s = 0; + else s = strdup(s); + } + if (scheme_) free((void*)scheme_); + scheme_ = s; + + // Save the new scheme in the FLTK_SCHEME env var so that child processes + // inherit it... + static char e[1024]; + strcpy(e,"FLTK_SCHEME="); + if (s) strlcat(e,s,sizeof(e)); + putenv(e); + + // Load the scheme... + return reload_scheme(); +} + +int Fl::reload_scheme() { + Fl_Window *win; + + if (scheme_ && !strcasecmp(scheme_, "plastic")) { + // Update the tile image to match the background color... + uchar r, g, b; + int nr, ng, nb; + int i; +// static uchar levels[3] = { 0xff, 0xef, 0xe8 }; + // OSX 10.3 and higher use a background with less contrast... + static uchar levels[3] = { 0xff, 0xf8, 0xf4 }; + + get_color(FL_GRAY, r, g, b); + +// printf("FL_GRAY = 0x%02x 0x%02x 0x%02x\n", r, g, b); + + for (i = 0; i < 3; i ++) { + nr = levels[i] * r / 0xe8; + if (nr > 255) nr = 255; + + ng = levels[i] * g / 0xe8; + if (ng > 255) ng = 255; + + nb = levels[i] * b / 0xe8; + if (nb > 255) nb = 255; + + sprintf(tile_cmap[i], "%c c #%02x%02x%02x", "Oo."[i], nr, ng, nb); +// puts(tile_cmap[i]); + } + + tile.uncache(); + + if (!scheme_bg_) scheme_bg_ = new Fl_Tiled_Image(&tile, w(), h()); + + // Load plastic buttons, etc... + set_boxtype(FL_UP_FRAME, FL_PLASTIC_UP_FRAME); + set_boxtype(FL_DOWN_FRAME, FL_PLASTIC_DOWN_FRAME); + set_boxtype(FL_THIN_UP_FRAME, FL_PLASTIC_UP_FRAME); + set_boxtype(FL_THIN_DOWN_FRAME, FL_PLASTIC_DOWN_FRAME); + + set_boxtype(FL_UP_BOX, FL_PLASTIC_UP_BOX); + set_boxtype(FL_DOWN_BOX, FL_PLASTIC_DOWN_BOX); + set_boxtype(FL_THIN_UP_BOX, FL_PLASTIC_THIN_UP_BOX); + set_boxtype(FL_THIN_DOWN_BOX, FL_PLASTIC_THIN_DOWN_BOX); + set_boxtype(_FL_ROUND_UP_BOX, FL_PLASTIC_ROUND_UP_BOX); + set_boxtype(_FL_ROUND_DOWN_BOX, FL_PLASTIC_ROUND_DOWN_BOX); + + // Use standard size scrollbars... + Fl::scrollbar_size(16); + } else if (scheme_ && !strcasecmp(scheme_, "gtk+")) { + // Use a GTK+ inspired look-n-feel... + if (scheme_bg_) { + delete scheme_bg_; + scheme_bg_ = (Fl_Image *)0; + } + + set_boxtype(FL_UP_FRAME, FL_GTK_UP_FRAME); + set_boxtype(FL_DOWN_FRAME, FL_GTK_DOWN_FRAME); + set_boxtype(FL_THIN_UP_FRAME, FL_GTK_THIN_UP_FRAME); + set_boxtype(FL_THIN_DOWN_FRAME, FL_GTK_THIN_DOWN_FRAME); + + set_boxtype(FL_UP_BOX, FL_GTK_UP_BOX); + set_boxtype(FL_DOWN_BOX, FL_GTK_DOWN_BOX); + set_boxtype(FL_THIN_UP_BOX, FL_GTK_THIN_UP_BOX); + set_boxtype(FL_THIN_DOWN_BOX, FL_GTK_THIN_DOWN_BOX); + set_boxtype(_FL_ROUND_UP_BOX, FL_GTK_ROUND_UP_BOX); + set_boxtype(_FL_ROUND_DOWN_BOX, FL_GTK_ROUND_DOWN_BOX); + + // Use slightly thinner scrollbars... + Fl::scrollbar_size(15); + } else { + // Use the standard FLTK look-n-feel... + if (scheme_bg_) { + delete scheme_bg_; + scheme_bg_ = (Fl_Image *)0; + } + + set_boxtype(FL_UP_FRAME, fl_up_frame, D1, D1, D2, D2); + set_boxtype(FL_DOWN_FRAME, fl_down_frame, D1, D1, D2, D2); + set_boxtype(FL_THIN_UP_FRAME, fl_thin_up_frame, 1, 1, 2, 2); + set_boxtype(FL_THIN_DOWN_FRAME, fl_thin_down_frame, 1, 1, 2, 2); + + set_boxtype(FL_UP_BOX, fl_up_box, D1, D1, D2, D2); + set_boxtype(FL_DOWN_BOX, fl_down_box, D1, D1, D2, D2); + set_boxtype(FL_THIN_UP_BOX, fl_thin_up_box, 1, 1, 2, 2); + set_boxtype(FL_THIN_DOWN_BOX, fl_thin_down_box, 1, 1, 2, 2); + set_boxtype(_FL_ROUND_UP_BOX, fl_round_up_box, 3, 3, 6, 6); + set_boxtype(_FL_ROUND_DOWN_BOX, fl_round_down_box, 3, 3, 6, 6); + + // Use standard size scrollbars... + Fl::scrollbar_size(16); + } + + // Set (or clear) the background tile for all windows... + for (win = first_window(); win; win = next_window(win)) { + win->labeltype(scheme_bg_ ? FL_NORMAL_LABEL : FL_NO_LABEL); + win->align(FL_ALIGN_CENTER | FL_ALIGN_INSIDE | FL_ALIGN_CLIP); + win->image(scheme_bg_); + win->redraw(); + } + + return 1; +} + + +// +// End of "$Id: Fl_get_system_colors.cxx 5699 2007-02-20 17:02:41Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_grab.cxx b/plugins/zynaddsubfx/fltk/src/Fl_grab.cxx new file mode 100644 index 000000000..7a735e2ab --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_grab.cxx @@ -0,0 +1,106 @@ +// +// "$Id: Fl_grab.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Grab/release code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include + +//////////////////////////////////////////////////////////////// +// "Grab" is done while menu systems are up. This has several effects: +// Events are all sent to the "grab window", which does not even +// have to be displayed (and in the case of Fl_Menu.cxx it isn't). +// The system is also told to "grab" events and send them to this app. +// This also modifies how Fl_Window::show() works, on X it turns on +// override_redirect, it does similar things on WIN32. + +extern void fl_fix_focus(); // in Fl.cxx + +#ifdef WIN32 +// We have to keep track of whether we have captured the mouse, since +// MSWindows shows little respect for this... Grep for fl_capture to +// see where and how this is used. +extern HWND fl_capture; +#endif + +#ifdef __APPLE__ +// MacOS Carbon does not seem to have a mechanism to grab the mouse pointer +extern WindowRef fl_capture; +#endif + +void Fl::grab(Fl_Window* win) { + if (win) { + if (!grab_) { +#ifdef WIN32 + SetActiveWindow(fl_capture = fl_xid(first_window())); + SetCapture(fl_capture); +#elif defined(__APPLE__) + fl_capture = fl_xid( first_window() ); + SetUserFocusWindow( fl_capture ); +#else + XGrabPointer(fl_display, + fl_xid(first_window()), + 1, + ButtonPressMask|ButtonReleaseMask| + ButtonMotionMask|PointerMotionMask, + GrabModeAsync, + GrabModeAsync, + None, + 0, + fl_event_time); + XGrabKeyboard(fl_display, + fl_xid(first_window()), + 1, + GrabModeAsync, + GrabModeAsync, + fl_event_time); +#endif + } + grab_ = win; + } else { + if (grab_) { +#ifdef WIN32 + fl_capture = 0; + ReleaseCapture(); +#elif defined(__APPLE__) + fl_capture = 0; + SetUserFocusWindow( (WindowRef)kUserFocusAuto ); +#else + XUngrabKeyboard(fl_display, fl_event_time); + XUngrabPointer(fl_display, fl_event_time); + // this flush is done in case the picked menu item goes into + // an infinite loop, so we don't leave the X server locked up: + XFlush(fl_display); +#endif + grab_ = 0; + fl_fix_focus(); + } + } +} + +// +// End of "$Id: Fl_grab.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_lock.cxx b/plugins/zynaddsubfx/fltk/src/Fl_lock.cxx new file mode 100644 index 000000000..688dc3db5 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_lock.cxx @@ -0,0 +1,358 @@ +// +// "$Id: Fl_lock.cxx 5950 2007-10-07 10:44:28Z matt $" +// +// Multi-threading support code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2007 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + + +#include +#include + +#include + +/* + From Bill: + + I would prefer that FLTK contain the minimal amount of extra + stuff for doing threads. There are other portable thread + wrapper libraries out there and FLTK should not be providing + another. This file is an attempt to make minimal additions + and make them self-contained in this source file. + + From Mike: + + Starting with 1.1.8, we now have a callback so that you can + process awake() messages as they come in. + + + The API: + + Fl::lock() - recursive lock. You must call this before the + first call to Fl::wait()/run() to initialize the thread + system. The lock is locked all the time except when + Fl::wait() is waiting for events. + + Fl::unlock() - release the recursive lock. + + Fl::awake(void*) - Causes Fl::wait() to return (with the lock + locked) even if there are no events ready. + + Fl::awake(void (*cb)(void *), void*) - Call a function + in the main thread from within another thread of execution. + + Fl::thread_message() - returns an argument sent to an + Fl::awake() call, or returns NULL if none. WARNING: the + current implementation only has a one-entry queue and only + returns the most recent value! +*/ + +Fl_Awake_Handler *Fl::awake_ring_; +void **Fl::awake_data_; +int Fl::awake_ring_size_; +int Fl::awake_ring_head_; +int Fl::awake_ring_tail_; +static const int AWAKE_RING_SIZE = 1024; + +static void lock_ring(); +static void unlock_ring(); + + +int Fl::add_awake_handler_(Fl_Awake_Handler func, void *data) +{ + int ret = 0; + lock_ring(); + if (!awake_ring_) { + awake_ring_size_ = AWAKE_RING_SIZE; + awake_ring_ = (Fl_Awake_Handler*)malloc(awake_ring_size_*sizeof(Fl_Awake_Handler)); + awake_data_ = (void**)malloc(awake_ring_size_*sizeof(void*)); + } + if (awake_ring_head_==awake_ring_tail_-1 || awake_ring_head_+1==awake_ring_tail_) { + // ring is full. Return -1 as an error indicator. + ret = -1; + } else { + awake_ring_[awake_ring_head_] = func; + awake_data_[awake_ring_head_] = data; + ++awake_ring_head_; + if (awake_ring_head_ == awake_ring_size_) + awake_ring_head_ = 0; + } + unlock_ring(); + return ret; +} + +int Fl::get_awake_handler_(Fl_Awake_Handler &func, void *&data) +{ + int ret = 0; + lock_ring(); + if (!awake_ring_ || awake_ring_head_ == awake_ring_tail_) { + ret = -1; + } else { + func = awake_ring_[awake_ring_tail_]; + data = awake_data_[awake_ring_tail_]; + ++awake_ring_tail_; + if (awake_ring_tail_ == awake_ring_size_) + awake_ring_tail_ = 0; + } + unlock_ring(); + return ret; +} + +// +// 'Fl::awake()' - Let the main thread know an update is pending +// and have it cal a specific function +// +int Fl::awake(Fl_Awake_Handler func, void *data) { + int ret = add_awake_handler_(func, data); + Fl::awake(); + return ret; +} + +//////////////////////////////////////////////////////////////// +// Windows threading... +#ifdef WIN32 +# include +# include +# include + +// These pointers are in Fl_win32.cxx: +extern void (*fl_lock_function)(); +extern void (*fl_unlock_function)(); + +// The main thread's ID +static DWORD main_thread; + +// Microsoft's version of a MUTEX... +CRITICAL_SECTION cs; +CRITICAL_SECTION *cs_ring; + +void unlock_ring() { + LeaveCriticalSection(cs_ring); +} + +void lock_ring() { + if (!cs_ring) { + cs_ring = (CRITICAL_SECTION*)malloc(sizeof(CRITICAL_SECTION)); + InitializeCriticalSection(cs_ring); + } + EnterCriticalSection(cs_ring); +} + +// +// 'unlock_function()' - Release the lock. +// + +static void unlock_function() { + LeaveCriticalSection(&cs); +} + +// +// 'lock_function()' - Get the lock. +// + +static void lock_function() { + EnterCriticalSection(&cs); +} + +// +// 'Fl::lock()' - Lock access to FLTK data structures... +// + +void Fl::lock() { + if (!main_thread) InitializeCriticalSection(&cs); + + lock_function(); + + if (!main_thread) { + fl_lock_function = lock_function; + fl_unlock_function = unlock_function; + main_thread = GetCurrentThreadId(); + } +} + +// +// 'Fl::unlock()' - Unlock access to FLTK data structures... +// + +void Fl::unlock() { + unlock_function(); +} + + +// +// 'Fl::awake()' - Let the main thread know an update is pending. +// +// When called from a thread, it causes FLTK to awake from Fl::wait()... +// + +void Fl::awake(void* msg) { + PostThreadMessage( main_thread, fl_wake_msg, (WPARAM)msg, 0); +} + +//////////////////////////////////////////////////////////////// +// POSIX threading... +#elif HAVE_PTHREAD +# include +# include +# include + +// Pipe for thread messaging via Fl::awake()... +static int thread_filedes[2]; + +// Mutex and state information for Fl::lock() and Fl::unlock()... +static pthread_mutex_t fltk_mutex; +static pthread_t owner; +static int counter; + +static void lock_function_init_std() { + pthread_mutex_init(&fltk_mutex, NULL); +} + +static void lock_function_std() { + if (!counter || owner != pthread_self()) { + pthread_mutex_lock(&fltk_mutex); + owner = pthread_self(); + } + counter++; +} + +static void unlock_function_std() { + if (!--counter) pthread_mutex_unlock(&fltk_mutex); +} + +# ifdef PTHREAD_MUTEX_RECURSIVE +static bool lock_function_init_rec() { + pthread_mutexattr_t attrib; + pthread_mutexattr_init(&attrib); + if (pthread_mutexattr_settype(&attrib, PTHREAD_MUTEX_RECURSIVE)) { + pthread_mutexattr_destroy(&attrib); + return true; + } + + pthread_mutex_init(&fltk_mutex, &attrib); + return false; +} + +static void lock_function_rec() { + pthread_mutex_lock(&fltk_mutex); +} + +static void unlock_function_rec() { + pthread_mutex_unlock(&fltk_mutex); +} +# endif // PTHREAD_MUTEX_RECURSIVE + +void Fl::awake(void* msg) { + write(thread_filedes[1], &msg, sizeof(void*)); +} + +static void* thread_message_; +void* Fl::thread_message() { + void* r = thread_message_; + thread_message_ = 0; + return r; +} + +static void thread_awake_cb(int fd, void*) { + read(fd, &thread_message_, sizeof(void*)); + Fl_Awake_Handler func; + void *data; + while (Fl::get_awake_handler_(func, data)==0) { + (*func)(data); + } +} + +// These pointers are in Fl_x.cxx: +extern void (*fl_lock_function)(); +extern void (*fl_unlock_function)(); + +void Fl::lock() { + if (!thread_filedes[1]) { + // Initialize thread communication pipe to let threads awake FLTK + // from Fl::wait() + pipe(thread_filedes); + + // Make the write side of the pipe non-blocking to avoid deadlock + // conditions (STR #1537) + fcntl(thread_filedes[1], F_SETFL, + fcntl(thread_filedes[1], F_GETFL) | O_NONBLOCK); + + // Monitor the read side of the pipe so that messages sent via + // Fl::awake() from a thread will "wake up" the main thread in + // Fl::wait(). + Fl::add_fd(thread_filedes[0], FL_READ, thread_awake_cb); + + // Set lock/unlock functions for this system, using a system-supplied + // recursive mutex if supported... +# ifdef PTHREAD_MUTEX_RECURSIVE + if (!lock_function_init_rec()) { + fl_lock_function = lock_function_rec; + fl_unlock_function = unlock_function_rec; + } else { +# endif // PTHREAD_MUTEX_RECURSIVE + lock_function_init_std(); + fl_lock_function = lock_function_std; + fl_unlock_function = unlock_function_std; +# ifdef PTHREAD_MUTEX_RECURSIVE + } +# endif // PTHREAD_MUTEX_RECURSIVE + } + + fl_lock_function(); +} + +void Fl::unlock() { + fl_unlock_function(); +} + +// Mutex code for the awake ring buffer +static pthread_mutex_t *ring_mutex; + +void unlock_ring() { + pthread_mutex_unlock(ring_mutex); +} + +void lock_ring() { + if (!ring_mutex) { + ring_mutex = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t)); + pthread_mutex_init(ring_mutex, NULL); + } + pthread_mutex_lock(ring_mutex); +} + +#else + +void unlock_ring() { +} + +void lock_ring() { +} + +void Fl::awake(void*) { +} + +#endif // WIN32 + +// +// End of "$Id: Fl_lock.cxx 5950 2007-10-07 10:44:28Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_mac.cxx b/plugins/zynaddsubfx/fltk/src/Fl_mac.cxx new file mode 100644 index 000000000..47b2daee1 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_mac.cxx @@ -0,0 +1,2471 @@ +// +// "$Id: Fl_mac.cxx 6033 2008-02-20 18:17:34Z matt $" +// +// MacOS specific code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2007 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +//// From the inner edge of a MetroWerks CodeWarrior CD: +// (without permission) +// +// "Three Compiles for 68Ks under the sky, +// Seven Compiles for PPCs in their fragments of code, +// Nine Compiles for Mortal Carbon doomed to die, +// One Compile for Mach-O Cocoa on its Mach-O throne, +// in the Land of MacOS X where the Drop-Shadows lie. +// +// One Compile to link them all, One Compile to merge them, +// One Compile to copy them all and in the bundle bind them, +// in the Land of MacOS X where the Drop-Shadows lie." + +// warning: the Apple Quartz version still uses some Quickdraw calls, +// mostly to get around the single active context in QD and +// to implement clipping. This should be changed into pure +// Quartz calls in the near future. + +// we don't need the following definition because we deliver only +// true mouse moves. On very slow systems however, this flag may +// still be useful. +#define CONSOLIDATE_MOTION 0 +extern "C" { +#include +} + +#include +#include +#include +#include +#include +#include +#include +#include +#include "flstring.h" +#include + +// #define DEBUG_SELECT // UNCOMMENT FOR SELECT()/THREAD DEBUGGING +#ifdef DEBUG_SELECT +#include // testing +#define DEBUGMSG(msg) if ( msg ) fprintf(stderr, msg); +#define DEBUGPERRORMSG(msg) if ( msg ) perror(msg) +#define DEBUGTEXT(txt) txt +#else +#define DEBUGMSG(msg) +#define DEBUGPERRORMSG(msg) +#define DEBUGTEXT(txt) NULL +#endif /*DEBUG_SELECT*/ + +// external functions +extern Fl_Window* fl_find(Window); +extern void fl_fix_focus(); + +// forward definition of functions in this file +static void handleUpdateEvent( WindowPtr xid ); +//+ int fl_handle(const EventRecord &event); +static int FSSpec2UnixPath( FSSpec *fs, char *dst ); + +// public variables +int fl_screen; +CGContextRef fl_gc = 0; +Handle fl_system_menu; +Fl_Sys_Menu_Bar *fl_sys_menu_bar = 0; +CursHandle fl_default_cursor; +WindowRef fl_capture = 0; // we need this to compensate for a missing(?) mouse capture +ulong fl_event_time; // the last timestamp from an x event +char fl_key_vector[32]; // used by Fl::get_key() +bool fl_show_iconic; // true if called from iconize() - shows the next created window in collapsed state +int fl_disable_transient_for; // secret method of removing TRANSIENT_FOR +const Fl_Window* fl_modal_for; // parent of modal() window +Fl_Region fl_window_region = 0; +Window fl_window; +Fl_Window *Fl_Window::current_; +EventRef fl_os_event; // last (mouse) event + +// forward declarations of variables in this file +static int got_events = 0; +static Fl_Window* resize_from_system; +static CursPtr default_cursor_ptr; +static Cursor default_cursor; +static WindowRef fl_os_capture = 0; // the dispatch handler will redirect mose move and drag events to these windows + +#if CONSOLIDATE_MOTION +static Fl_Window* send_motion; +extern Fl_Window* fl_xmousewin; +#endif + +enum { kEventClassFLTK = 'fltk' }; +enum { kEventFLTKBreakLoop = 1, kEventFLTKDataReady }; + +/** +* Mac keyboard lookup table + */ +static unsigned short macKeyLookUp[128] = +{ + 'a', 's', 'd', 'f', 'h', 'g', 'z', 'x', + 'c', 'v', '^', 'b', 'q', 'w', 'e', 'r', + + 'y', 't', '1', '2', '3', '4', '6', '5', + '=', '9', '7', '-', '8', '0', ']', 'o', + + 'u', '[', 'i', 'p', FL_Enter, 'l', 'j', '\'', + 'k', ';', '\\', ',', '/', 'n', 'm', '.', + + FL_Tab, ' ', '`', FL_BackSpace, + FL_KP_Enter, FL_Escape, 0, 0/*FL_Meta_L*/, + 0/*FL_Shift_L*/, 0/*FL_Caps_Lock*/, 0/*FL_Alt_L*/, 0/*FL_Control_L*/, + 0/*FL_Shift_R*/, 0/*FL_Alt_R*/, 0/*FL_Control_R*/, 0, + + 0, FL_KP+'.', FL_Right, FL_KP+'*', 0, FL_KP+'+', FL_Left, FL_Num_Lock, + FL_Down, 0, 0, FL_KP+'/', FL_KP_Enter, FL_Up, FL_KP+'-', 0, + + 0, FL_KP+'=', FL_KP+'0', FL_KP+'1', FL_KP+'2', FL_KP+'3', FL_KP+'4', FL_KP+'5', + FL_KP+'6', FL_KP+'7', 0, FL_KP+'8', FL_KP+'9', 0, 0, 0, + + FL_F+5, FL_F+6, FL_F+7, FL_F+3, FL_F+8, FL_F+9, 0, FL_F+11, + 0, 0/*FL_F+13*/, FL_Print, FL_Scroll_Lock, 0, FL_F+10, FL_Menu, FL_F+12, + + 0, FL_Pause, FL_Help, FL_Home, FL_Page_Up, FL_Delete, FL_F+4, FL_End, + FL_F+2, FL_Page_Down, FL_F+1, FL_Left, FL_Right, FL_Down, FL_Up, 0/*FL_Power*/, +}; + +/** + * convert the current mouse chord into the FLTK modifier state + */ +static void mods_to_e_state( UInt32 mods ) +{ + long state = 0; + if ( mods & kEventKeyModifierNumLockMask ) state |= FL_NUM_LOCK; + if ( mods & cmdKey ) state |= FL_META; + if ( mods & (optionKey|rightOptionKey) ) state |= FL_ALT; + if ( mods & (controlKey|rightControlKey) ) state |= FL_CTRL; + if ( mods & (shiftKey|rightShiftKey) ) state |= FL_SHIFT; + if ( mods & alphaLock ) state |= FL_CAPS_LOCK; + Fl::e_state = ( Fl::e_state & 0xff000000 ) | state; + //printf( "State 0x%08x (%04x)\n", Fl::e_state, mods ); +} + + +/** + * convert the current mouse chord into the FLTK keysym + */ +static void mods_to_e_keysym( UInt32 mods ) +{ + if ( mods & cmdKey ) Fl::e_keysym = FL_Meta_L; + else if ( mods & kEventKeyModifierNumLockMask ) Fl::e_keysym = FL_Num_Lock; + else if ( mods & optionKey ) Fl::e_keysym = FL_Alt_L; + else if ( mods & rightOptionKey ) Fl::e_keysym = FL_Alt_R; + else if ( mods & controlKey ) Fl::e_keysym = FL_Control_L; + else if ( mods & rightControlKey ) Fl::e_keysym = FL_Control_R; + else if ( mods & shiftKey ) Fl::e_keysym = FL_Shift_L; + else if ( mods & rightShiftKey ) Fl::e_keysym = FL_Shift_R; + else if ( mods & alphaLock ) Fl::e_keysym = FL_Caps_Lock; + else Fl::e_keysym = 0; + //printf( "to sym 0x%08x (%04x)\n", Fl::e_keysym, mods ); +} +// these pointers are set by the Fl::lock() function: +static void nothing() {} +void (*fl_lock_function)() = nothing; +void (*fl_unlock_function)() = nothing; + +// +// Select interface -- how it's implemented: +// When the user app configures one or more file descriptors to monitor +// with Fl::add_fd(), we start a separate thread to select() the data, +// sending a custom OSX 'FLTK data ready event' to the parent thread's +// RunApplicationLoop(), so that it triggers the data ready callbacks +// in the parent thread. -erco 04/04/04 +// +#define POLLIN 1 +#define POLLOUT 4 +#define POLLERR 8 + +// Class to handle select() 'data ready' +class DataReady +{ + struct FD + { + int fd; + short events; + void (*cb)(int, void*); + void* arg; + }; + int nfds, fd_array_size; + FD *fds; + pthread_t tid; // select()'s thread id + + // Data that needs to be locked (all start with '_') + pthread_mutex_t _datalock; // data lock + fd_set _fdsets[3]; // r/w/x sets user wants to monitor + int _maxfd; // max fd count to monitor + int _cancelpipe[2]; // pipe used to help cancel thread + void *_userdata; // thread's userdata + +public: + DataReady() + { + nfds = 0; + fd_array_size = 0; + fds = 0; + tid = 0; + + pthread_mutex_init(&_datalock, NULL); + FD_ZERO(&_fdsets[0]); FD_ZERO(&_fdsets[1]); FD_ZERO(&_fdsets[2]); + _cancelpipe[0] = _cancelpipe[1] = 0; + _userdata = 0; + _maxfd = 0; + } + + ~DataReady() + { + CancelThread(DEBUGTEXT("DESTRUCTOR\n")); + if (fds) { free(fds); fds = 0; } + nfds = 0; + } + + // Locks + // The convention for locks: volatile vars start with '_', + // and must be locked before use. Locked code is prefixed + // with /*LOCK*/ to make painfully obvious esp. in debuggers. -erco + // + void DataLock() { pthread_mutex_lock(&_datalock); } + void DataUnlock() { pthread_mutex_unlock(&_datalock); } + + // Accessors + int IsThreadRunning() { return(tid ? 1 : 0); } + int GetNfds() { return(nfds); } + int GetCancelPipe(int ix) { return(_cancelpipe[ix]); } + fd_set GetFdset(int ix) { return(_fdsets[ix]); } + + // Methods + void AddFD(int n, int events, void (*cb)(int, void*), void *v); + void RemoveFD(int n, int events); + int CheckData(fd_set& r, fd_set& w, fd_set& x); + void HandleData(fd_set& r, fd_set& w, fd_set& x); + static void* DataReadyThread(void *self); + void StartThread(void *userdata); + void CancelThread(const char *reason); +}; + +static DataReady dataready; + +void DataReady::AddFD(int n, int events, void (*cb)(int, void*), void *v) +{ + RemoveFD(n, events); + int i = nfds++; + if (i >= fd_array_size) + { + FD *temp; + fd_array_size = 2*fd_array_size+1; + if (!fds) { temp = (FD*)malloc(fd_array_size*sizeof(FD)); } + else { temp = (FD*)realloc(fds, fd_array_size*sizeof(FD)); } + if (!temp) return; + fds = temp; + } + fds[i].cb = cb; + fds[i].arg = v; + fds[i].fd = n; + fds[i].events = events; + DataLock(); + /*LOCK*/ if (events & POLLIN) FD_SET(n, &_fdsets[0]); + /*LOCK*/ if (events & POLLOUT) FD_SET(n, &_fdsets[1]); + /*LOCK*/ if (events & POLLERR) FD_SET(n, &_fdsets[2]); + /*LOCK*/ if (n > _maxfd) _maxfd = n; + DataUnlock(); +} + +// Remove an FD from the array +void DataReady::RemoveFD(int n, int events) +{ + int i,j; + for (i=j=0; iDataLock(); + /*LOCK*/ int maxfd = self->_maxfd; + /*LOCK*/ fd_set r = self->GetFdset(0); + /*LOCK*/ fd_set w = self->GetFdset(1); + /*LOCK*/ fd_set x = self->GetFdset(2); + /*LOCK*/ void *userdata = self->_userdata; + /*LOCK*/ int cancelpipe = self->GetCancelPipe(0); + /*LOCK*/ if ( cancelpipe > maxfd ) maxfd = cancelpipe; + /*LOCK*/ FD_SET(cancelpipe, &r); // add cancelpipe to fd's to watch + /*LOCK*/ FD_SET(cancelpipe, &x); + self->DataUnlock(); + // timeval t = { 1000, 0 }; // 1000 seconds; + timeval t = { 2, 0 }; // HACK: 2 secs prevents 'hanging' problem + int ret = ::select(maxfd+1, &r, &w, &x, &t); + pthread_testcancel(); // OSX 10.0.4 and older: needed for parent to cancel + switch ( ret ) + { + case 0: // NO DATA + continue; + case -1: // ERROR + { + DEBUGPERRORMSG("CHILD THREAD: select() failed"); + return(NULL); // error? exit thread + } + default: // DATA READY + { + if (FD_ISSET(cancelpipe, &r) || FD_ISSET(cancelpipe, &x)) // cancel? + { return(NULL); } // just exit + DEBUGMSG("CHILD THREAD: DATA IS READY\n"); + EventRef drEvent; + CreateEvent( 0, kEventClassFLTK, kEventFLTKDataReady, + 0, kEventAttributeUserEvent, &drEvent); + EventQueueRef eventqueue = (EventQueueRef)userdata; + PostEventToQueue(eventqueue, drEvent, kEventPriorityStandard ); + ReleaseEvent( drEvent ); + return(NULL); // done with thread + } + } + } +} + +// START 'DATA READY' THREAD RUNNING, CREATE INTER-THREAD PIPE +void DataReady::StartThread(void *new_userdata) +{ + CancelThread(DEBUGTEXT("STARTING NEW THREAD\n")); + DataLock(); + /*LOCK*/ pipe(_cancelpipe); // pipe for sending cancel msg to thread + /*LOCK*/ _userdata = new_userdata; + DataUnlock(); + DEBUGMSG("*** START THREAD\n"); + pthread_create(&tid, NULL, DataReadyThread, (void*)this); +} + +// CANCEL 'DATA READY' THREAD, CLOSE PIPE +void DataReady::CancelThread(const char *reason) +{ + if ( tid ) + { + DEBUGMSG("*** CANCEL THREAD: "); + DEBUGMSG(reason); + if ( pthread_cancel(tid) == 0 ) // cancel first + { + DataLock(); + /*LOCK*/ write(_cancelpipe[1], "x", 1); // wake thread from select + DataUnlock(); + pthread_join(tid, NULL); // wait for thread to finish + } + tid = 0; + DEBUGMSG("(JOINED) OK\n"); + } + // Close pipe if open + DataLock(); + /*LOCK*/ if ( _cancelpipe[0] ) { close(_cancelpipe[0]); _cancelpipe[0] = 0; } + /*LOCK*/ if ( _cancelpipe[1] ) { close(_cancelpipe[1]); _cancelpipe[1] = 0; } + DataUnlock(); +} + +void Fl::add_fd( int n, int events, void (*cb)(int, void*), void *v ) + { dataready.AddFD(n, events, cb, v); } + +void Fl::add_fd(int fd, void (*cb)(int, void*), void* v) + { dataready.AddFD(fd, POLLIN, cb, v); } + +void Fl::remove_fd(int n, int events) + { dataready.RemoveFD(n, events); } + +void Fl::remove_fd(int n) + { dataready.RemoveFD(n, -1); } + +/** + * Check if there is actually a message pending! + */ +int fl_ready() +{ + EventRef event; + return !ReceiveNextEvent(0, NULL, 0.0, false, &event); +} + +/** + * handle Apple Menu items (can be created using the Fl_Sys_Menu_Bar + * returns eventNotHandledErr if the menu item could not be handled + */ +OSStatus HandleMenu( HICommand *cmd ) +{ + OSStatus ret = eventNotHandledErr; + // attributes, commandIDm menu.menuRef, menu.menuItemIndex + UInt32 ref; + OSErr rrc = GetMenuItemRefCon( cmd->menu.menuRef, cmd->menu.menuItemIndex, &ref ); + //printf( "%d, %08x, %08x, %d, %d, %8x\n", rrc, cmd->attributes, cmd->commandID, cmd->menu.menuRef, cmd->menu.menuItemIndex, rrc ); + if ( rrc==noErr && ref ) + { + Fl_Menu_Item *m = (Fl_Menu_Item*)ref; + //printf( "Menu: %s\n", m->label() ); + fl_sys_menu_bar->picked( m ); + if ( m->flags & FL_MENU_TOGGLE ) // update the menu toggle symbol + SetItemMark( cmd->menu.menuRef, cmd->menu.menuItemIndex, (m->flags & FL_MENU_VALUE ) ? 0x12 : 0 ); + if ( m->flags & FL_MENU_RADIO ) // update all radio buttons in this menu + { + Fl_Menu_Item *j = m; + int i = cmd->menu.menuItemIndex; + for (;;) + { + if ( j->flags & FL_MENU_DIVIDER ) + break; + j++; i++; + if ( !j->text || !j->radio() ) + break; + SetItemMark( cmd->menu.menuRef, i, ( j->flags & FL_MENU_VALUE ) ? 0x13 : 0 ); + } + j = m-1; i = cmd->menu.menuItemIndex-1; + for ( ; i>0; j--, i-- ) + { + if ( !j->text || j->flags&FL_MENU_DIVIDER || !j->radio() ) + break; + SetItemMark( cmd->menu.menuRef, i, ( j->flags & FL_MENU_VALUE ) ? 0x13 : 0 ); + } + SetItemMark( cmd->menu.menuRef, cmd->menu.menuItemIndex, ( m->flags & FL_MENU_VALUE ) ? 0x13 : 0 ); + } + ret = noErr; // done handling this event + } + HiliteMenu(0); + return ret; +} + + +/** + * We can make every event pass through this function + * - mouse events need to be manipulated to use a mouse focus window + * - keyboard, mouse and some window events need to quit the Apple Event Loop + * so FLTK can continue its own management + */ +static pascal OSStatus carbonDispatchHandler( EventHandlerCallRef nextHandler, EventRef event, void *userData ) +{ + OSStatus ret = eventNotHandledErr; + HICommand cmd; + + fl_lock_function(); + + got_events = 1; + + switch ( GetEventClass( event ) ) + { + case kEventClassMouse: + switch ( GetEventKind( event ) ) + { + case kEventMouseUp: + case kEventMouseMoved: + case kEventMouseDragged: + if ( fl_capture ) + ret = SendEventToEventTarget( event, GetWindowEventTarget( fl_capture ) ); + else if ( fl_os_capture ){ + ret = SendEventToEventTarget( event, GetWindowEventTarget( fl_os_capture ) ); + fl_os_capture = 0; + } + break; + } + break; + case kEventClassCommand: + switch (GetEventKind( event ) ) + { + case kEventCommandProcess: + GetEventParameter( event, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &cmd ); + ret = HandleMenu( &cmd ); + break; + } + break; + case kEventClassFLTK: + switch ( GetEventKind( event ) ) + { + case kEventFLTKBreakLoop: + ret = noErr; + break; + case kEventFLTKDataReady: + { + dataready.CancelThread(DEBUGTEXT("DATA READY EVENT\n")); + + // CHILD THREAD TELLS US DATA READY + // Check to see what's ready, and invoke user's cb's + // + fd_set r,w,x; + switch(dataready.CheckData(r,w,x)) + { + case 0: // NO DATA + break; + case -1: // ERROR + break; + default: // DATA READY + dataready.HandleData(r,w,x); + break; + } + } + ret = noErr; + break; + } + } + if ( ret == eventNotHandledErr ) + ret = CallNextEventHandler( nextHandler, event ); // let the OS handle the activation, but continue to get a click-through effect + + fl_unlock_function(); + + return ret; +} + + +/** + * break the current event loop + */ +static void breakMacEventLoop() +{ + EventRef breakEvent; + + fl_lock_function(); + + CreateEvent( 0, kEventClassFLTK, kEventFLTKBreakLoop, 0, kEventAttributeUserEvent, &breakEvent ); + PostEventToQueue( GetCurrentEventQueue(), breakEvent, kEventPriorityStandard ); + ReleaseEvent( breakEvent ); + + fl_unlock_function(); +} + +// +// MacOS X timers +// + +struct MacTimeout { + Fl_Timeout_Handler callback; + void* data; + EventLoopTimerRef timer; + EventLoopTimerUPP upp; + char pending; +}; +static MacTimeout* mac_timers; +static int mac_timer_alloc; +static int mac_timer_used; + + +static void realloc_timers() +{ + if (mac_timer_alloc == 0) { + mac_timer_alloc = 8; + } + mac_timer_alloc *= 2; + MacTimeout* new_timers = new MacTimeout[mac_timer_alloc]; + memset(new_timers, 0, sizeof(MacTimeout)*mac_timer_alloc); + memcpy(new_timers, mac_timers, sizeof(MacTimeout) * mac_timer_used); + MacTimeout* delete_me = mac_timers; + mac_timers = new_timers; + delete [] delete_me; +} + +static void delete_timer(MacTimeout& t) +{ + if (t.timer) { + RemoveEventLoopTimer(t.timer); + DisposeEventLoopTimerUPP(t.upp); + memset(&t, 0, sizeof(MacTimeout)); + } +} + + +static pascal void do_timer(EventLoopTimerRef timer, void* data) +{ + for (int i = 0; i < mac_timer_used; ++i) { + MacTimeout& t = mac_timers[i]; + if (t.timer == timer && t.data == data) { + t.pending = 0; + (*t.callback)(data); + if (t.pending==0) + delete_timer(t); + break; + } + } + breakMacEventLoop(); +} + +/** + * This function is the central event handler. + * It reads events from the event queue using the given maximum time + * Funny enough, it returns the same time that it got as the argument. + */ +static double do_queued_events( double time = 0.0 ) +{ + static bool been_here = 0; + static RgnHandle rgn; + + // initialize events and a region that enables mouse move events + if (!been_here) { + rgn = NewRgn(); + Point mp; + GetMouse(&mp); + SetRectRgn(rgn, mp.h, mp.v, mp.h, mp.v); + SetEventMask(everyEvent); + been_here = 1; + } + OSStatus ret; + static EventTargetRef target = 0; + if ( !target ) + { + target = GetEventDispatcherTarget(); + + EventHandlerUPP dispatchHandler = NewEventHandlerUPP( carbonDispatchHandler ); // will not be disposed by Carbon... + static EventTypeSpec dispatchEvents[] = { + { kEventClassWindow, kEventWindowShown }, + { kEventClassWindow, kEventWindowHidden }, + { kEventClassWindow, kEventWindowActivated }, + { kEventClassWindow, kEventWindowDeactivated }, + { kEventClassWindow, kEventWindowClose }, + { kEventClassKeyboard, kEventRawKeyDown }, + { kEventClassKeyboard, kEventRawKeyRepeat }, + { kEventClassKeyboard, kEventRawKeyUp }, + { kEventClassKeyboard, kEventRawKeyModifiersChanged }, + { kEventClassMouse, kEventMouseDown }, + { kEventClassMouse, kEventMouseUp }, + { kEventClassMouse, kEventMouseMoved }, + { kEventClassMouse, 11 }, // MightyMouse wheels + { kEventClassMouse, kEventMouseWheelMoved }, + { kEventClassMouse, kEventMouseDragged }, + { kEventClassFLTK, kEventFLTKBreakLoop }, + { kEventClassFLTK, kEventFLTKDataReady } }; + ret = InstallEventHandler( target, dispatchHandler, GetEventTypeCount(dispatchEvents), dispatchEvents, 0, 0L ); + static EventTypeSpec appEvents[] = { + { kEventClassCommand, kEventCommandProcess } }; + ret = InstallApplicationEventHandler( dispatchHandler, GetEventTypeCount(appEvents), appEvents, 0, 0L ); + } + + got_events = 0; + + // Check for re-entrant condition + if ( dataready.IsThreadRunning() ) + { dataready.CancelThread(DEBUGTEXT("AVOID REENTRY\n")); } + + // Start thread to watch for data ready + if ( dataready.GetNfds() ) + { dataready.StartThread((void*)GetCurrentEventQueue()); } + + fl_unlock_function(); + + EventRef event; + EventTimeout timeout = time; + if (!ReceiveNextEvent(0, NULL, timeout, true, &event)) { + got_events = 1; + OSErr ret = SendEventToEventTarget( event, target ); + if (ret!=noErr) { + EventRecord clevent; + ConvertEventRefToEventRecord(event, &clevent); + if (clevent.what==kHighLevelEvent) { + ret = AEProcessAppleEvent(&clevent); + } + } + if ( ret==eventNotHandledErr + && GetEventClass(event)==kEventClassMouse + && GetEventKind(event)==kEventMouseDown ) { + WindowRef win; Point pos; + GetEventParameter(event, kEventParamMouseLocation, typeQDPoint, + NULL, sizeof(pos), NULL, &pos); + if (MacFindWindow(pos, &win)==inMenuBar) { + MenuSelect(pos); + } + } + ReleaseEvent( event ); + } + + fl_lock_function(); + +#if CONSOLIDATE_MOTION + if (send_motion && send_motion == fl_xmousewin) { + send_motion = 0; + Fl::handle(FL_MOVE, fl_xmousewin); + } +#endif + + return time; +} + + +/** + * This public function handles all events. It wait a maximum of + * 'time' secods for an event. This version returns 1 if events + * other than the timeout timer were processed. + * + * \todo there is no socket handling in this code whatsoever + */ +int fl_wait( double time ) +{ + do_queued_events( time ); + return (got_events); +} + + +/** + * event handler for Apple-Q key combination + * this is also called from the Carbon Window handler after all windows were closed + */ +static OSErr QuitAppleEventHandler( const AppleEvent *appleEvt, AppleEvent* reply, UInt32 refcon ) +{ + fl_lock_function(); + + while ( Fl_X::first ) { + Fl_X *x = Fl_X::first; + Fl::handle( FL_CLOSE, x->w ); + if ( Fl_X::first == x ) { + fl_unlock_function(); + return noErr; // FLTK has not close all windows, so we return to the main program now + } + } + + fl_unlock_function(); + + return noErr; +} + + +/** + * Carbon Window handler + * This needs to be linked into all new window event handlers + */ +static pascal OSStatus carbonWindowHandler( EventHandlerCallRef nextHandler, EventRef event, void *userData ) +{ + UInt32 kind = GetEventKind( event ); + OSStatus ret = eventNotHandledErr; + Fl_Window *window = (Fl_Window*)userData; + Fl::first_window(window); + + Rect currentBounds, originalBounds; + WindowClass winClass; + static Fl_Window *activeWindow = 0; + + fl_lock_function(); + + switch ( kind ) + { + case kEventWindowBoundsChanging: + GetEventParameter( event, kEventParamCurrentBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, ¤tBounds ); + GetEventParameter( event, kEventParamOriginalBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, &originalBounds ); + break; + case kEventWindowDrawContent: + handleUpdateEvent( fl_xid( window ) ); + ret = noErr; + break; + case kEventWindowBoundsChanged: { + GetEventParameter( event, kEventParamCurrentBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, ¤tBounds ); + GetEventParameter( event, kEventParamOriginalBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, &originalBounds ); + int X = currentBounds.left, W = currentBounds.right-X; + int Y = currentBounds.top, H = currentBounds.bottom-Y; + resize_from_system = window; + window->resize( X, Y, W, H ); + if ( ( originalBounds.right - originalBounds.left != W ) + || ( originalBounds.bottom - originalBounds.top != H ) ) + { + if ( window->shown() ) + handleUpdateEvent( fl_xid( window ) ); + } + break; } + case kEventWindowShown: + if ( !window->parent() ) + { + GetWindowClass( fl_xid( window ), &winClass ); + if ( winClass != kHelpWindowClass ) { // help windows can't get the focus! + Fl::handle( FL_FOCUS, window); + activeWindow = window; + } + Fl::handle( FL_SHOW, window); + mods_to_e_state(GetCurrentKeyModifiers()); + } + break; + case kEventWindowHidden: + if ( !window->parent() ) Fl::handle( FL_HIDE, window); + break; + case kEventWindowActivated: + if ( window->shown() && window!=activeWindow ) + { + GetWindowClass( fl_xid( window ), &winClass ); + if ( winClass != kHelpWindowClass ) { // help windows can't get the focus! + Fl::handle( FL_FOCUS, window); + activeWindow = window; + } + } + break; + case kEventWindowDeactivated: + if ( window==activeWindow ) + { + Fl::handle( FL_UNFOCUS, window); + activeWindow = 0; + } + break; + case kEventWindowClose: + Fl::handle( FL_CLOSE, window ); // this might or might not close the window + // if there are no more windows, send a high-level quit event + if (!Fl_X::first) QuitAppleEventHandler( 0, 0, 0 ); + ret = noErr; // returning noErr tells Carbon to stop following up on this event + break; + case kEventWindowCollapsed: + window->clear_visible(); + break; + case kEventWindowExpanded: + window->set_visible(); + break; + } + + fl_unlock_function(); + + return ret; +} + + +/** + * Carbon Mousewheel handler + * This needs to be linked into all new window event handlers + */ +static pascal OSStatus carbonMousewheelHandler( EventHandlerCallRef nextHandler, EventRef event, void *userData ) +{ + // Handle the new "MightyMouse" mouse wheel events. Please, someone explain + // to me why Apple changed the API on this even though the current API + // supports two wheels just fine. Matthias, + fl_lock_function(); + + fl_os_event = event; + Fl_Window *window = (Fl_Window*)userData; + if ( !window->shown() ) + { + fl_unlock_function(); + return noErr; + } + Fl::first_window(window); + + EventMouseWheelAxis axis; + GetEventParameter( event, kEventParamMouseWheelAxis, typeMouseWheelAxis, NULL, sizeof(EventMouseWheelAxis), NULL, &axis ); + long delta; + GetEventParameter( event, kEventParamMouseWheelDelta, typeLongInteger, NULL, sizeof(long), NULL, &delta ); +// fprintf(stderr, "axis=%d, delta=%d\n", axis, delta); + if ( axis == kEventMouseWheelAxisX ) { + Fl::e_dx = -delta; + Fl::e_dy = 0; + if ( Fl::e_dx) Fl::handle( FL_MOUSEWHEEL, window ); + } else if ( axis == kEventMouseWheelAxisY ) { + Fl::e_dx = 0; + Fl::e_dy = -delta; + if ( Fl::e_dy) Fl::handle( FL_MOUSEWHEEL, window ); + } else { + fl_unlock_function(); + + return eventNotHandledErr; + } + + fl_unlock_function(); + + return noErr; +} + + +/** + * convert the current mouse chord into the FLTK modifier state + */ +static void chord_to_e_state( UInt32 chord ) +{ + static ulong state[] = + { + 0, FL_BUTTON1, FL_BUTTON3, FL_BUTTON1|FL_BUTTON3, FL_BUTTON2, + FL_BUTTON2|FL_BUTTON1, FL_BUTTON2|FL_BUTTON3, + FL_BUTTON2|FL_BUTTON1|FL_BUTTON3 + }; + Fl::e_state = ( Fl::e_state & 0xff0000 ) | state[ chord & 0x07 ]; +} + + +/** + * Carbon Mouse Button Handler + */ +static pascal OSStatus carbonMouseHandler( EventHandlerCallRef nextHandler, EventRef event, void *userData ) +{ + static int keysym[] = { 0, FL_Button+1, FL_Button+3, FL_Button+2 }; + static int px, py; + static char suppressed = 0; + + fl_lock_function(); + + fl_os_event = event; + Fl_Window *window = (Fl_Window*)userData; + if ( !window->shown() ) + { + fl_unlock_function(); + return noErr; + } + Fl::first_window(window); + Point pos; + GetEventParameter( event, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &pos ); + EventMouseButton btn; + GetEventParameter( event, kEventParamMouseButton, typeMouseButton, NULL, sizeof(EventMouseButton), NULL, &btn ); + UInt32 clickCount; + GetEventParameter( event, kEventParamClickCount, typeUInt32, NULL, sizeof(UInt32), NULL, &clickCount ); + UInt32 chord; + GetEventParameter( event, kEventParamMouseChord, typeUInt32, NULL, sizeof(UInt32), NULL, &chord ); + WindowRef xid = fl_xid(window), tempXid; + int sendEvent = 0, part = 0; + switch ( GetEventKind( event ) ) + { + case kEventMouseDown: + part = FindWindow( pos, &tempXid ); + if (!(Fl::grab() && window!=Fl::grab())) { + if ( part == inGrow ) { + fl_unlock_function(); + suppressed = 1; + Fl_Tooltip::current(0L); + return CallNextEventHandler( nextHandler, event ); // let the OS handle this for us + } + if ( part != inContent ) { + fl_unlock_function(); + suppressed = 1; + Fl_Tooltip::current(0L); + // anything else to here? + return CallNextEventHandler( nextHandler, event ); // let the OS handle this for us + } + } + suppressed = 0; + if (part==inContent && !IsWindowActive( xid ) ) { + CallNextEventHandler( nextHandler, event ); // let the OS handle the activation, but continue to get a click-through effect + } + // normal handling of mouse-down follows + fl_os_capture = xid; + sendEvent = FL_PUSH; + Fl::e_is_click = 1; px = pos.h; py = pos.v; + if (clickCount>1) + Fl::e_clicks++; + else + Fl::e_clicks = 0; + // fall through + case kEventMouseUp: + if (suppressed) { + suppressed = 0; + break; + } + if ( !window ) break; + if ( !sendEvent ) { + sendEvent = FL_RELEASE; + } + Fl::e_keysym = keysym[ btn ]; + // fall through + case kEventMouseMoved: + suppressed = 0; + if ( !sendEvent ) { + sendEvent = FL_MOVE; chord = 0; + } + // fall through + case kEventMouseDragged: + if (suppressed) break; + if ( !sendEvent ) { + sendEvent = FL_MOVE; // Fl::handle will convert into FL_DRAG + if (abs(pos.h-px)>5 || abs(pos.v-py)>5) + Fl::e_is_click = 0; + } + chord_to_e_state( chord ); + GrafPtr oldPort; + GetPort( &oldPort ); + SetPort( GetWindowPort(xid) ); // \todo replace this! There must be some GlobalToLocal call that has a port as an argument + SetOrigin(0, 0); + Fl::e_x_root = pos.h; + Fl::e_y_root = pos.v; + GlobalToLocal( &pos ); + Fl::e_x = pos.h; + Fl::e_y = pos.v; + SetPort( oldPort ); + if (GetEventKind(event)==kEventMouseDown && part!=inContent) { + int used = Fl::handle( sendEvent, window ); + CallNextEventHandler( nextHandler, event ); // let the OS handle this for us + if (!used) + suppressed = 1; + } else { + Fl::handle( sendEvent, window ); + } + break; + } + + fl_unlock_function(); + + return noErr; +} + + +/** + * convert the keyboard return code into the symbol on the keycaps + */ +static unsigned short keycode_to_sym( UInt32 keyCode, UInt32 mods, unsigned short deflt ) +{ + static Ptr map = 0; + UInt32 state = 0; + if (!map) { + map = (Ptr)GetScriptManagerVariable(smKCHRCache); + if (!map) { + long kbID = GetScriptManagerVariable(smKeyScript); + map = *GetResource('KCHR', kbID); + } + } + if (map) + return KeyTranslate(map, keyCode|mods, &state ); + return deflt; +} + +/** + * handle carbon keyboard events + */ +pascal OSStatus carbonKeyboardHandler( + EventHandlerCallRef nextHandler, EventRef event, void *userData ) +{ + static char buffer[5]; + int sendEvent = 0; + Fl_Window *window = (Fl_Window*)userData; + Fl::first_window(window); + UInt32 mods; + static UInt32 prevMods = 0xffffffff; + + fl_lock_function(); + + int kind = GetEventKind(event); + + // get the modifiers for any of the events + GetEventParameter( event, kEventParamKeyModifiers, typeUInt32, + NULL, sizeof(UInt32), NULL, &mods ); + if ( prevMods == 0xffffffff ) prevMods = mods; + + // get the key code only for key events + UInt32 keyCode = 0; + unsigned char key = 0; + unsigned short sym = 0; + if (kind!=kEventRawKeyModifiersChanged) { + GetEventParameter( event, kEventParamKeyCode, typeUInt32, + NULL, sizeof(UInt32), NULL, &keyCode ); + GetEventParameter( event, kEventParamKeyMacCharCodes, typeChar, + NULL, sizeof(char), NULL, &key ); + } + /* output a human readbale event identifier for debugging + const char *ev = ""; + switch (kind) { + case kEventRawKeyDown: ev = "kEventRawKeyDown"; break; + case kEventRawKeyRepeat: ev = "kEventRawKeyRepeat"; break; + case kEventRawKeyUp: ev = "kEventRawKeyUp"; break; + case kEventRawKeyModifiersChanged: ev = "kEventRawKeyModifiersChanged"; break; + default: ev = "unknown"; + } + printf("%08x %08x %08x '%c' %s \n", mods, keyCode, key, key, ev); + */ + switch (kind) + { + case kEventRawKeyDown: + case kEventRawKeyRepeat: + // When the user presses a "dead key", no information is send about + // which dead key symbol was created. So we need to trick Carbon into + // giving us the code by sending a "space" after the "dead key". + if (key==0) { + UInt32 ktState = 0; + KeyboardLayoutRef klr; + KLGetCurrentKeyboardLayout(&klr); + const void *kchar = 0; KLGetKeyboardLayoutProperty(klr, kKLKCHRData, &kchar); + KeyTranslate(kchar, (mods&0xff00) | keyCode, &ktState); // send the dead key + key = KeyTranslate(kchar, 0x31, &ktState); // fake a space key press + Fl::e_state |= 0x40000000; // mark this as a dead key + } else { + Fl::e_state &= 0xbfffffff; // clear the deadkey flag + } + sendEvent = FL_KEYBOARD; + // fall through + case kEventRawKeyUp: + if ( !sendEvent ) { + sendEvent = FL_KEYUP; + Fl::e_state &= 0xbfffffff; // clear the deadkey flag + } + // if the user pressed alt/option, event_key should have the keycap, + // but event_text should generate the international symbol + if ( isalpha(key) ) + sym = tolower(key); + else if ( Fl::e_state&FL_CTRL && key<32 ) + sym = key+96; + else if ( Fl::e_state&FL_ALT ) // find the keycap of this key + sym = keycode_to_sym( keyCode & 0x7f, 0, macKeyLookUp[ keyCode & 0x7f ] ); + else + sym = macKeyLookUp[ keyCode & 0x7f ]; + Fl::e_keysym = Fl::e_original_keysym = sym; + // Handle FL_KP_Enter on regular keyboards and on Powerbooks + if ( keyCode==0x4c || keyCode==0x34) key=0x0d; + // Matt: the Mac has no concept of a NumLock key, or at least not visible + // Matt: to Carbon. The kEventKeyModifierNumLockMask is only set when + // Matt: a numeric keypad key is pressed and does not correspond with + // Matt: the NumLock light in PowerBook keyboards. + if ( (sym >= FL_KP && sym <= FL_KP_Last) || !(sym & 0xff00) || + sym == FL_Tab || sym == FL_Enter) { + buffer[0] = key; + Fl::e_length = 1; + } else { + buffer[0] = 0; + Fl::e_length = 0; + } + Fl::e_text = buffer; + // insert UnicodeHandling here! + break; + case kEventRawKeyModifiersChanged: { + UInt32 tMods = prevMods ^ mods; + if ( tMods ) + { + mods_to_e_keysym( tMods ); + if ( Fl::e_keysym ) + sendEvent = ( prevModsparent()) window = window->window(); + if (sendEvent && Fl::handle(sendEvent,window)) { + fl_unlock_function(); + return noErr; // return noErr if FLTK handled the event + } else { + fl_unlock_function(); + //return CallNextEventHandler( nextHandler, event );; + // Matt: I had better results (no duplicate events) always returning + // Matt: 'noErr'. System keyboard events still seem to work just fine. + return noErr; + } +} + + + +/** + * Open callback function to call... + */ + +static void (*open_cb)(const char *) = 0; + + +/** + * Event handler for Apple-O key combination and also for file opens + * via the finder... + */ + +static OSErr OpenAppleEventHandler(const AppleEvent *appleEvt, + AppleEvent *reply, + UInt32 refcon) { + OSErr err; + AEDescList documents; + long i, n; + FSSpec fileSpec; + AEKeyword keyWd; + DescType typeCd; + Size actSz; + char filename[1024]; + + if (!open_cb) return noErr; + + // Initialize the document list... + AECreateDesc(typeNull, NULL, 0, &documents); + + // Get the open parameter(s)... + err = AEGetParamDesc(appleEvt, keyDirectObject, typeAEList, &documents); + if (err != noErr) { + AEDisposeDesc(&documents); + return err; + } + + // Lock access to FLTK in this thread... + fl_lock_function(); + + // Open the documents via the callback... + if (AECountItems(&documents, &n) == noErr) { + for (i = 1; i <= n; i ++) { + // Get the next FSSpec record... + AEGetNthPtr(&documents, i, typeFSS, &keyWd, &typeCd, + (Ptr)&fileSpec, sizeof(fileSpec), + (actSz = sizeof(fileSpec), &actSz)); + + // Convert to a UNIX path... + FSSpec2UnixPath(&fileSpec, filename); + + // Call the callback with the filename... + (*open_cb)(filename); + } + } + + // Unlock access to FLTK for all threads... + fl_unlock_function(); + + // Get rid of the document list... + AEDisposeDesc(&documents); + + return noErr; +} + + +/** + * Install an open documents event handler... + */ + +void fl_open_callback(void (*cb)(const char *)) { + open_cb = cb; + if (cb) { + AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, + NewAEEventHandlerUPP((AEEventHandlerProcPtr) + OpenAppleEventHandler), 0, false); + } else { + AERemoveEventHandler(kCoreEventClass, kAEOpenDocuments, + NewAEEventHandlerUPP((AEEventHandlerProcPtr) + OpenAppleEventHandler), false); + } +} + + +/** + * initialize the Mac toolboxes, dock status, and set the default menubar + */ + +extern "C" { + extern OSErr CPSEnableForegroundOperation(ProcessSerialNumber *psn, UInt32 _arg2, + UInt32 _arg3, UInt32 _arg4, UInt32 _arg5); +} + +void fl_open_display() { + static char beenHereDoneThat = 0; + if ( !beenHereDoneThat ) { + beenHereDoneThat = 1; + + FlushEvents(everyEvent,0); + + MoreMasters(); // \todo Carbon suggests MoreMasterPointers() + AEInstallEventHandler( kCoreEventClass, kAEQuitApplication, NewAEEventHandlerUPP((AEEventHandlerProcPtr)QuitAppleEventHandler), 0, false ); + + // create the Mac Handle for the default cursor (a pointer to a pointer) + GetQDGlobalsArrow(&default_cursor); + default_cursor_ptr = &default_cursor; + fl_default_cursor = &default_cursor_ptr; + + ClearMenuBar(); + AppendResMenu( GetMenuHandle( 1 ), 'DRVR' ); + DrawMenuBar(); + + // bring the application into foreground without a 'CARB' resource + Boolean same_psn; + ProcessSerialNumber cur_psn, front_psn; + if( !GetCurrentProcess( &cur_psn ) && !GetFrontProcess( &front_psn ) && + !SameProcess( &front_psn, &cur_psn, &same_psn ) && !same_psn ) + { + // only transform the application type for unbundled apps + CFBundleRef bundle = CFBundleGetMainBundle(); + if( bundle ) + { + FSRef execFs; + CFURLRef execUrl = CFBundleCopyExecutableURL( bundle ); + CFURLGetFSRef( execUrl, &execFs ); + + FSRef bundleFs; + GetProcessBundleLocation( &cur_psn, &bundleFs ); + + if( !FSCompareFSRefs( &execFs, &bundleFs ) ) + bundle = NULL; + + CFRelease(execUrl); + } + + if( !bundle ) + { + // Earlier versions of this code tried to use weak linking, however it + // appears that this does not work on 10.2. Since 10.3 and higher provide + // both TransformProcessType and CPSEnableForegroundOperation, the following + // conditional code compiled on 10.2 will still work on newer releases... + OSErr err; + +#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2 + if (TransformProcessType != NULL) { + err = TransformProcessType(&cur_psn, kProcessTransformToForegroundApplication); + } else +#endif // MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2 + err = CPSEnableForegroundOperation(&cur_psn, 0x03, 0x3C, 0x2C, 0x1103); + + if (err == noErr) { + SetFrontProcess( &cur_psn ); + } + } + } + } +} + + +/** + * get rid of allocated resources + */ +void fl_close_display() { +} + + +/** + * smallest x ccordinate in screen space + */ +int Fl::x() { + BitMap r; + GetQDGlobalsScreenBits(&r); + return r.bounds.left; +} + + +/** + * smallest y ccordinate in screen space + */ +int Fl::y() { + BitMap r; + GetQDGlobalsScreenBits(&r); + return r.bounds.top + 20; // \todo 20 pixel menu bar? +} + + +/** + * screen width (single monitor!?) + */ +int Fl::w() { + BitMap r; + GetQDGlobalsScreenBits(&r); + return r.bounds.right - r.bounds.left; +} + + +/** + * screen height (single monitor!?) + */ +int Fl::h() { + BitMap r; + GetQDGlobalsScreenBits(&r); + return r.bounds.bottom - r.bounds.top - 20; +} + + +/** + * get the current mouse pointer world coordinates + */ +void Fl::get_mouse(int &x, int &y) +{ + fl_open_display(); + Point loc; + GetMouse( &loc ); + LocalToGlobal( &loc ); + x = loc.h; + y = loc.v; +} + + +/** + * convert Mac keystrokes to FLTK + */ +unsigned short mac2fltk(ulong macKey) +{ + unsigned short cc = macKeyLookUp[(macKey>>8)&0x7f]; + if (cc) return cc; + return macKey&0xff; +} + + +/** + * Initialize the given port for redraw and call the windw's flush() to actually draw the content + */ +void Fl_X::flush() +{ + w->flush(); +#ifdef __APPLE_QD__ + GrafPtr port; + GetPort( &port ); + if ( port ) + QDFlushPortBuffer( port, 0 ); +#elif defined (__APPLE_QUARTZ__) + if (fl_gc) + CGContextFlush(fl_gc); +#endif + SetOrigin( 0, 0 ); +} + + +/** + * Handle all clipping and redraw for the given port + * There are two different callers for this event: + * 1: the OS can request a redraw and provides all clipping itself + * 2: Fl::flush() wants all redraws now + */ +void handleUpdateEvent( WindowPtr xid ) +{ + Fl_Window *window = fl_find( xid ); + if ( !window ) return; + GrafPtr oldPort; + GetPort( &oldPort ); + SetPort( GetWindowPort(xid) ); + Fl_X *i = Fl_X::i( window ); + i->wait_for_expose = 0; + if ( window->damage() ) { + if ( i->region ) { + InvalWindowRgn( xid, i->region ); + } + } + if ( i->region ) { // no region, so the sytem will take the update region from the OS + DisposeRgn( i->region ); + i->region = 0; + } + for ( Fl_X *cx = i->xidChildren; cx; cx = cx->xidNext ) + { + cx->w->clear_damage(window->damage()|FL_DAMAGE_EXPOSE); + cx->flush(); + cx->w->clear_damage(); + } + window->clear_damage(window->damage()|FL_DAMAGE_EXPOSE); + i->flush(); + window->clear_damage(); + SetPort( oldPort ); +} + + +/** + * \todo this is a leftover from OS9 times. Please check how much applies to Carbon! + */ +int Fl_X::fake_X_wm(const Fl_Window* w,int &X,int &Y, int &bt,int &bx, int &by) { + int W, H, xoff, yoff, dx, dy; + int ret = bx = by = bt = 0; + if (w->border() && !w->parent()) { + if (w->maxw != w->minw || w->maxh != w->minh) { + ret = 2; + bx = 6; // \todo Mac : GetSystemMetrics(SM_CXSIZEFRAME); + by = 6; // \todo Mac : get Mac window frame size GetSystemMetrics(SM_CYSIZEFRAME); + } else { + ret = 1; + bx = 6; // \todo Mac : GetSystemMetrics(SM_CXFIXEDFRAME); + by = 6; // \todo Mac : GetSystemMetrics(SM_CYFIXEDFRAME); + } + bt = 22; // \todo Mac : GetSystemMetrics(SM_CYCAPTION); + } + //The coordinates of the whole window, including non-client area + xoff = bx; + yoff = by + bt; + dx = 2*bx; + dy = 2*by + bt; + X = w->x()-xoff; + Y = w->y()-yoff; + W = w->w()+dx; + H = w->h()+dy; + + //Proceed to positioning the window fully inside the screen, if possible + + // let's get a little elaborate here. Mac OS X puts a lot of stuff on the desk + // that we want to avoid when positioning our window, namely the Dock and the + // top menu bar (and even more stuff in 10.4 Tiger). So we will go through the + // list of all available screens and find the one that this window is most + // likely to go to, and then reposition it to fit withing the 'good' area. + Rect r; + // find the screen, that the center of this window will fall into + int R = X+W, B = Y+H; // right and bottom + int cx = (X+R)/2, cy = (Y+B)/2; // center of window; + GDHandle gd = 0L; + for (gd = GetDeviceList(); gd; gd = GetNextDevice(gd)) { + GDPtr gp = *gd; + if ( cx >= gp->gdRect.left && cx <= gp->gdRect.right + && cy >= gp->gdRect.top && cy <= gp->gdRect.bottom) + break; + } + // if the center doesn't fall on a screen, try the top left + if (!gd) { + for (gd = GetDeviceList(); gd; gd = GetNextDevice(gd)) { + GDPtr gp = *gd; + if ( X >= gp->gdRect.left && X <= gp->gdRect.right + && Y >= gp->gdRect.top && Y <= gp->gdRect.bottom) + break; + } + } + // if that doesn't fall on a screen, try the top right + if (!gd) { + for (gd = GetDeviceList(); gd; gd = GetNextDevice(gd)) { + GDPtr gp = *gd; + if ( R >= gp->gdRect.left && R <= gp->gdRect.right + && Y >= gp->gdRect.top && Y <= gp->gdRect.bottom) + break; + } + } + // if that doesn't fall on a screen, try the bottom left + if (!gd) { + for (gd = GetDeviceList(); gd; gd = GetNextDevice(gd)) { + GDPtr gp = *gd; + if ( X >= gp->gdRect.left && X <= gp->gdRect.right + && B >= gp->gdRect.top && B <= gp->gdRect.bottom) + break; + } + } + // last resort, try the bottom right + if (!gd) { + for (gd = GetDeviceList(); gd; gd = GetNextDevice(gd)) { + GDPtr gp = *gd; + if ( R >= gp->gdRect.left && R <= gp->gdRect.right + && B >= gp->gdRect.top && B <= gp->gdRect.bottom) + break; + } + } + // if we still have not found a screen, we will use the main + // screen, the one that has the application menu bar. + if (!gd) gd = GetMainDevice(); + if (gd) { + GetAvailableWindowPositioningBounds(gd, &r); + if ( R > r.right ) X -= R - r.right; + if ( B > r.bottom ) Y -= B - r.bottom; + if ( X < r.left ) X = r.left; + if ( Y < r.top ) Y = r.top; + } + + //Return the client area's top left corner in (X,Y) + X+=xoff; + Y+=yoff; + + return ret; +} + +/** + * convert a Mac FSSpec structure into a Unix filename + */ +static int FSSpec2UnixPath( FSSpec *fs, char *dst ) +{ + FSRef fsRef; + FSpMakeFSRef( fs, &fsRef ); + FSRefMakePath( &fsRef, (UInt8*)dst, 1024 ); + return strlen(dst); +} + +static DragReference currDragRef = 0; +static char *currDragData = 0L; +static int currDragSize = 0; +static OSErr currDragErr = noErr; +Fl_Window *fl_dnd_target_window = 0; +#include + +/** + * Fill the currDrag* variables with the current DnD ASCII text. + */ +static OSErr fillCurrentDragData(DragReference dragRef) +{ + OSErr ret = noErr; + char *dst = 0L; + + // shortcut through this whole procedure if this is still the same drag event + if (dragRef==currDragRef) + return currDragErr; + + // clear currDrag* for a new drag event + currDragRef = dragRef; + if (currDragData) free(currDragData); + currDragData = 0; + currDragSize = 0; + + // fill currDRag* with ASCII data, if available + UInt16 i, nItem; + ItemReference itemRef; + FlavorFlags flags; + Size itemSize, size = 0; + CountDragItems( dragRef, &nItem ); + for ( i = 1; i <= nItem; i++ ) + { + GetDragItemReferenceNumber( dragRef, i, &itemRef ); + ret = GetFlavorFlags( dragRef, itemRef, 'TEXT', &flags ); + if ( ret == noErr ) + { + GetFlavorDataSize( dragRef, itemRef, 'TEXT', &itemSize ); + size += itemSize; + } + ret = GetFlavorFlags( dragRef, itemRef, 'hfs ', &flags ); + if ( ret == noErr ) + { + size += 1024; //++ ouch! We should create the full pathname and figure out its length + } + } + + if ( !size ) + { + currDragErr = userCanceledErr; + return currDragErr; + } + + currDragSize = size + nItem - 1; + currDragData = dst = (char*)malloc( size+nItem );; + + for ( i = 1; i <= nItem; i++ ) + { + GetDragItemReferenceNumber( dragRef, i, &itemRef ); + ret = GetFlavorFlags( dragRef, itemRef, 'TEXT', &flags ); + if ( ret == noErr ) + { + GetFlavorDataSize( dragRef, itemRef, 'TEXT', &itemSize ); + GetFlavorData( dragRef, itemRef, 'TEXT', dst, &itemSize, 0L ); + dst += itemSize; + *dst++ = '\n'; // add our element seperator + } + ret = GetFlavorFlags( dragRef, itemRef, 'hfs ', &flags ); + if ( ret == noErr ) + { + HFSFlavor hfs; itemSize = sizeof( hfs ); + GetFlavorData( dragRef, itemRef, 'hfs ', &hfs, &itemSize, 0L ); + itemSize = FSSpec2UnixPath( &hfs.fileSpec, dst ); + dst += itemSize; + if ( itemSize>1 && ( hfs.fileType=='fold' || hfs.fileType=='disk' ) ) + *dst++ = '/'; + *dst++ = '\n'; // add our element seperator + } + } + + dst[-1] = 0; + currDragSize = dst - currDragData - 1; + currDragErr = ret; + return ret; +} + +/** + * Drag'n'drop tracking handler + */ +static pascal OSErr dndTrackingHandler( DragTrackingMessage msg, WindowPtr w, void *userData, DragReference dragRef ) +{ + Fl_Window *target = (Fl_Window*)userData; + Fl::first_window(target); + Point mp; + static int px, py; + + fillCurrentDragData(dragRef); + Fl::e_length = currDragSize; + Fl::e_text = currDragData; + + switch ( msg ) + { + case kDragTrackingEnterWindow: + // check if 'TEXT' is available + GetDragMouse( dragRef, &mp, 0 ); + Fl::e_x_root = px = mp.h; + Fl::e_y_root = py = mp.v; + Fl::e_x = px - target->x(); + Fl::e_y = py - target->y(); + fl_dnd_target_window = target; + if ( Fl::handle( FL_DND_ENTER, target ) ) + fl_cursor( FL_CURSOR_HAND ); //ShowDragHilite( ); // modify the mouse cursor?! + else + fl_cursor( FL_CURSOR_DEFAULT ); //HideDragHilite( dragRef ); + breakMacEventLoop(); + return noErr; + case kDragTrackingInWindow: + GetDragMouse( dragRef, &mp, 0 ); + if ( mp.h==px && mp.v==py ) + break; //+ return previous condition for dnd hiliting + Fl::e_x_root = px = mp.h; + Fl::e_y_root = py = mp.v; + Fl::e_x = px - target->x(); + Fl::e_y = py - target->y(); + fl_dnd_target_window = target; + if ( Fl::handle( FL_DND_DRAG, target ) ) + fl_cursor( FL_CURSOR_HAND ); //ShowDragHilite( ); // modify the mouse cursor?! + else + fl_cursor( FL_CURSOR_DEFAULT ); //HideDragHilite( dragRef ); + breakMacEventLoop(); + return noErr; + break; + case kDragTrackingLeaveWindow: + // HideDragHilite() + fl_cursor( FL_CURSOR_DEFAULT ); //HideDragHilite( dragRef ); + if ( fl_dnd_target_window ) + { + Fl::handle( FL_DND_LEAVE, fl_dnd_target_window ); + fl_dnd_target_window = 0; + } + breakMacEventLoop(); + return noErr; + } + return noErr; +} + + +/** + * Drag'n'drop receive handler + */ +static pascal OSErr dndReceiveHandler( WindowPtr w, void *userData, DragReference dragRef ) +{ + Point mp; + OSErr ret; + + Fl_Window *target = fl_dnd_target_window = (Fl_Window*)userData; + Fl::first_window(target); + GetDragMouse( dragRef, &mp, 0 ); + Fl::e_x_root = mp.h; + Fl::e_y_root = mp.v; + Fl::e_x = Fl::e_x_root - target->x(); + Fl::e_y = Fl::e_y_root - target->y(); + if ( !Fl::handle( FL_DND_RELEASE, target ) ) + return userCanceledErr; + + ret = fillCurrentDragData(dragRef); + if (ret==userCanceledErr) + return userCanceledErr; + + Fl::e_length = currDragSize; + Fl::e_text = currDragData; +// printf("Sending following text to widget %p:\n%s\n", Fl::belowmouse(), Fl::e_text); + int old_event = Fl::e_number; + Fl::belowmouse()->handle(Fl::e_number = FL_PASTE); + Fl::e_number = old_event; + + if (currDragData) { + free(currDragData); + } + currDragData = 0L; + currDragRef = 0; + Fl::e_text = 0L; + Fl::e_length = 0; + fl_dnd_target_window = 0L; + + breakMacEventLoop(); + return noErr; +} + + +/** + * go ahead, create that (sub)window + * \todo we should make menu windows slightly transparent for the new Mac look + */ +void Fl_X::make(Fl_Window* w) +{ + static int xyPos = 100; + if ( w->parent() ) // create a subwindow + { + Fl_Group::current(0); + Rect wRect; + wRect.top = w->y(); + wRect.left = w->x(); + wRect.bottom = w->y() + w->h(); if (wRect.bottom<=wRect.top) wRect.bottom = wRect.top+1; + wRect.right = w->x() + w->w(); if (wRect.right<=wRect.left) wRect.right = wRect.left+1; + // our subwindow needs this structure to know about its clipping. + Fl_X* x = new Fl_X; + x->other_xid = 0; + x->region = 0; + x->subRegion = 0; + x->cursor = fl_default_cursor; + x->gc = 0; // stay 0 for Quickdraw; fill with CGContext for Quartz + Fl_Window *win = w->window(); + Fl_X *xo = Fl_X::i(win); + if (xo) { + x->xidNext = xo->xidChildren; + x->xidChildren = 0L; + xo->xidChildren = x; + x->xid = fl_xid(win); + x->w = w; w->i = x; + x->wait_for_expose = 0; + x->next = Fl_X::first; // must be in the list for ::flush() + Fl_X::first = x; + int old_event = Fl::e_number; + w->handle(Fl::e_number = FL_SHOW); + Fl::e_number = old_event; + w->redraw(); // force draw to happen + } + fl_show_iconic = 0; + } + else // create a desktop window + { + Fl_Group::current(0); + fl_open_display(); + int winclass = kDocumentWindowClass; + int winattr = kWindowStandardHandlerAttribute | kWindowCloseBoxAttribute | kWindowCollapseBoxAttribute; + int xp = w->x(); + int yp = w->y(); + int wp = w->w(); + int hp = w->h(); + if (w->size_range_set) { + if ( w->minh != w->maxh || w->minw != w->maxw) + winattr |= kWindowFullZoomAttribute | kWindowResizableAttribute | kWindowLiveResizeAttribute; + } else { + if (w->resizable()) { + Fl_Widget *o = w->resizable(); + int minw = o->w(); if (minw > 100) minw = 100; + int minh = o->h(); if (minh > 100) minh = 100; + w->size_range(w->w() - o->w() + minw, w->h() - o->h() + minh, 0, 0); + winattr |= kWindowFullZoomAttribute | kWindowResizableAttribute | kWindowLiveResizeAttribute; + } else { + w->size_range(w->w(), w->h(), w->w(), w->h()); + } + } + int xwm = xp, ywm = yp, bt, bx, by; + + if (!fake_X_wm(w, xwm, ywm, bt, bx, by)) { + // menu windows and tooltips + if (w->modal()||w->override()) { + winclass = kHelpWindowClass; + winattr = 0; + } else { + winattr = 512; // kWindowNoTitleBarAttribute; + } + } else if (w->modal()) { + winclass = kMovableModalWindowClass; + } + + if (by+bt) { + wp += 2*bx; + hp += 2*by+bt; + } + if (!(w->flags() & Fl_Window::FL_FORCE_POSITION)) { + // use the Carbon functions below for default window positioning + w->x(xyPos+Fl::x()); + w->y(xyPos+Fl::y()); + xyPos += 25; + if (xyPos>200) xyPos = 100; + } else { + if (!Fl::grab()) { + xp = xwm; yp = ywm; + w->x(xp);w->y(yp); + } + xp -= bx; + yp -= by+bt; + } + + if (w->non_modal() && Fl_X::first && !fl_disable_transient_for) { + // find some other window to be "transient for": + Fl_Window* w = Fl_X::first->w; + while (w->parent()) w = w->window(); // todo: this code does not make any sense! (w!=w??) + } + + Rect wRect; + wRect.top = w->y(); + wRect.left = w->x(); + wRect.bottom = w->y() + w->h(); if (wRect.bottom<=wRect.top) wRect.bottom = wRect.top+1; + wRect.right = w->x() + w->w(); if (wRect.right<=wRect.left) wRect.right = wRect.left+1; + + const char *name = w->label(); + Str255 pTitle; + if (name) { + if (strlen(name) > 255) pTitle[0] = 255; + else pTitle[0] = strlen(name); + + memcpy(pTitle+1, name, pTitle[0]); + } else pTitle[0] = 0; + + Fl_X* x = new Fl_X; + x->other_xid = 0; // room for doublebuffering image map. On OS X this is only used by overlay windows + x->region = 0; + x->subRegion = 0; + x->cursor = fl_default_cursor; + x->xidChildren = 0; + x->xidNext = 0; + x->gc = 0; + + winattr &= GetAvailableWindowAttributes( winclass ); // make sure that the window will open + CreateNewWindow( winclass, winattr, &wRect, &(x->xid) ); + SetWTitle(x->xid, pTitle); + MoveWindow(x->xid, wRect.left, wRect.top, 1); // avoid Carbon Bug on old OS + if (w->non_modal() && !w->modal()) { + // Major kludge: this is to have the regular look, but stay above the document windows + SetWindowClass(x->xid, kFloatingWindowClass); + SetWindowActivationScope(x->xid, kWindowActivationScopeAll); + } + if (!(w->flags() & Fl_Window::FL_FORCE_POSITION)) + { + WindowRef pw = Fl_X::first ? Fl_X::first->xid : 0 ; + if (w->modal()) { + RepositionWindow(x->xid, pw, kWindowAlertPositionOnParentWindowScreen); + } else if (w->non_modal()) { + RepositionWindow(x->xid, pw, kWindowCenterOnParentWindowScreen); + } else { + RepositionWindow(x->xid, pw, kWindowCascadeOnParentWindowScreen); + } + } + x->w = w; w->i = x; + x->wait_for_expose = 1; + x->next = Fl_X::first; + Fl_X::first = x; + { // Install Carbon Event handlers + OSStatus ret; + EventHandlerUPP mousewheelHandler = NewEventHandlerUPP( carbonMousewheelHandler ); // will not be disposed by Carbon... + static EventTypeSpec mousewheelEvents[] = { + { kEventClassMouse, kEventMouseWheelMoved } }; + ret = InstallWindowEventHandler( x->xid, mousewheelHandler, + (int)(sizeof(mousewheelEvents)/sizeof(mousewheelEvents[0])), + mousewheelEvents, w, 0L ); + EventHandlerUPP mouseHandler = NewEventHandlerUPP( carbonMouseHandler ); // will not be disposed by Carbon... + static EventTypeSpec mouseEvents[] = { + { kEventClassMouse, kEventMouseDown }, + { kEventClassMouse, kEventMouseUp }, + { kEventClassMouse, kEventMouseMoved }, + { kEventClassMouse, kEventMouseDragged } }; + ret = InstallWindowEventHandler( x->xid, mouseHandler, 4, mouseEvents, w, 0L ); + EventHandlerUPP keyboardHandler = NewEventHandlerUPP( carbonKeyboardHandler ); // will not be disposed by Carbon... + static EventTypeSpec keyboardEvents[] = { + { kEventClassKeyboard, kEventRawKeyDown }, + { kEventClassKeyboard, kEventRawKeyRepeat }, + { kEventClassKeyboard, kEventRawKeyUp }, + { kEventClassKeyboard, kEventRawKeyModifiersChanged } }; + ret = InstallWindowEventHandler( x->xid, keyboardHandler, 4, keyboardEvents, w, 0L ); + EventHandlerUPP windowHandler = NewEventHandlerUPP( carbonWindowHandler ); // will not be disposed by Carbon... + static EventTypeSpec windowEvents[] = { + { kEventClassWindow, kEventWindowDrawContent }, + { kEventClassWindow, kEventWindowShown }, + { kEventClassWindow, kEventWindowHidden }, + { kEventClassWindow, kEventWindowActivated }, + { kEventClassWindow, kEventWindowDeactivated }, + { kEventClassWindow, kEventWindowClose }, + { kEventClassWindow, kEventWindowCollapsed }, + { kEventClassWindow, kEventWindowExpanded }, + { kEventClassWindow, kEventWindowBoundsChanging }, + { kEventClassWindow, kEventWindowBoundsChanged } }; + ret = InstallWindowEventHandler( x->xid, windowHandler, 10, windowEvents, w, 0L ); + ret = InstallTrackingHandler( dndTrackingHandler, x->xid, w ); + ret = InstallReceiveHandler( dndReceiveHandler, x->xid, w ); + } + + if ( ! Fl_X::first->next ) // if this is the first window, we need to bring the application to the front + { + ProcessSerialNumber psn; + OSErr err = GetCurrentProcess( &psn ); + if ( err==noErr ) SetFrontProcess( &psn ); + } + + if (w->size_range_set) w->size_range_(); + + if (winclass != kHelpWindowClass) { + Fl_Tooltip::enter(0); + } + if (w->size_range_set) w->size_range_(); + ShowWindow(x->xid); + if (fl_show_iconic) { + fl_show_iconic = 0; + CollapseWindow( x->xid, true ); // \todo Mac ; untested + } else { + w->set_visible(); + } + + Rect rect; + GetWindowBounds(x->xid, kWindowContentRgn, &rect); + w->x(rect.left); w->y(rect.top); + w->w(rect.right-rect.left); w->h(rect.bottom-rect.top); + + int old_event = Fl::e_number; + w->handle(Fl::e_number = FL_SHOW); + Fl::e_number = old_event; + w->redraw(); // force draw to happen + + if (w->modal()) { Fl::modal_ = w; fl_fix_focus(); } + } +} + + +/** + * Tell the OS what window sizes we want to allow + */ +void Fl_Window::size_range_() { + size_range_set = 1; + HISize minSize = { minw, minh }; + HISize maxSize = { maxw?maxw:32000, maxh?maxh:32000 }; + if (i && i->xid) + SetWindowResizeLimits(i->xid, &minSize, &maxSize); +} + + +/** + * returns pointer to the filename, or null if name ends with ':' + */ +const char *fl_filename_name( const char *name ) +{ + const char *p, *q; + if (!name) return (0); + for ( p = q = name ; *p ; ) + { + if ( ( p[0] == ':' ) && ( p[1] == ':' ) ) + { + q = p+2; + p++; + } + else if (p[0] == '/') + q = p + 1; + p++; + } + return q; +} + + +/** + * set the window title bar + * \todo make the titlebar icon work! + */ +void Fl_Window::label(const char *name,const char */*iname*/) { + Fl_Widget::label(name); + Str255 pTitle; + + if (name) { pTitle[0] = strlen(name); memcpy(pTitle+1, name, pTitle[0]); } + else pTitle[0] = 0; + + if (shown() || i) SetWTitle(fl_xid(this), pTitle); +} + + +/** + * make a window visible + */ +void Fl_Window::show() { + image(Fl::scheme_bg_); + if (Fl::scheme_bg_) { + labeltype(FL_NORMAL_LABEL); + align(FL_ALIGN_CENTER | FL_ALIGN_INSIDE | FL_ALIGN_CLIP); + } else { + labeltype(FL_NO_LABEL); + } + Fl_Tooltip::exit(this); + if (!shown() || !i) { + Fl_X::make(this); + } else { + if ( !parent() ) + { + if ( IsWindowCollapsed( i->xid ) ) CollapseWindow( i->xid, false ); + if (!fl_capture) { + BringToFront(i->xid); + SelectWindow(i->xid); + } + } + } +} + + +/** + * resize a window + */ +void Fl_Window::resize(int X,int Y,int W,int H) { + if (W<=0) W = 1; // OS X does not like zero width windows + if (H<=0) H = 1; + int is_a_resize = (W != w() || H != h()); +// printf("Fl_Winodw::resize(X=%d, Y=%d, W=%d, H=%d), is_a_resize=%d, resize_from_system=%p, this=%p\n", +// X, Y, W, H, is_a_resize, resize_from_system, this); + if (X != x() || Y != y()) set_flag(FL_FORCE_POSITION); + else if (!is_a_resize) return; + if ( (resize_from_system!=this) && (!parent()) && shown()) { + if (is_a_resize) { + if (resizable()) { + if (Wmaxw) maxw = W; // over a previously set size_range + if (Hmaxh) maxh = H; + size_range(minw, minh, maxw, maxh); + } else { + size_range(W, H, W, H); + } + Rect dim; dim.left=X; dim.top=Y; dim.right=X+W; dim.bottom=Y+H; + SetWindowBounds(i->xid, kWindowContentRgn, &dim); + Rect all; all.top=-32000; all.bottom=32000; all.left=-32000; all.right=32000; + InvalWindowRect( i->xid, &all ); + } else { + MoveWindow(i->xid, X, Y, 0); + } + } + resize_from_system = 0; + if (is_a_resize) { + Fl_Group::resize(X,Y,W,H); + if (shown()) { + redraw(); + } + } else { + x(X); y(Y); + } +} + + +/** + * make all drawing go into this window (called by subclass flush() impl.) + */ +void Fl_Window::make_current() +{ +#ifdef __APPLE_QUARTZ__ + OSStatus err; + Fl_X::q_release_context(); +#endif + if ( !fl_window_region ) + fl_window_region = NewRgn(); + fl_window = i->xid; + current_ = this; + + SetPort( GetWindowPort(i->xid) ); // \todo check for the handling of doublebuffered windows + + int xp = 0, yp = 0; + Fl_Window *win = this; + while ( win ) + { + if ( !win->window() ) + break; + xp += win->x(); + yp += win->y(); + win = (Fl_Window*)win->window(); + } + SetOrigin( -xp, -yp ); + + SetRectRgn( fl_window_region, 0, 0, w(), h() ); + + // \todo for performance reasons: we don't have to create this unless the child windows moved + for ( Fl_X *cx = i->xidChildren; cx; cx = cx->xidNext ) + { + Fl_Window *cw = cx->w; + if (!cw->visible_r()) continue; + Fl_Region r = NewRgn(); + SetRectRgn( r, cw->x() - xp, cw->y() - yp, + cw->x() + cw->w() - xp, cw->y() + cw->h() - yp ); + DiffRgn( fl_window_region, r, fl_window_region ); + DisposeRgn( r ); + } + +#ifdef __APPLE_QUARTZ__ + err = QDBeginCGContext(GetWindowPort(i->xid), &i->gc); + if (err!=noErr) + fprintf(stderr, "Error %d in QDBeginCGContext\n", (int)err); + fl_gc = i->gc; + CGContextSaveGState(fl_gc); + Fl_X::q_fill_context(); +#endif + fl_clip_region( 0 ); + SetPortClipRegion( GetWindowPort(i->xid), fl_window_region ); + return; +} + +// helper function to manage the current CGContext fl_gc +#ifdef __APPLE_QUARTZ__ +extern Fl_Color fl_color_; +extern class Fl_FontSize *fl_fontsize; +extern void fl_font(class Fl_FontSize*); +extern void fl_quartz_restore_line_style_(); + +// FLTK has only one global graphics state. This function copies the FLTK state into the +// current Quartz context +void Fl_X::q_fill_context() { + if (!fl_gc) return; + int hgt = 0; + if (fl_window) { + Rect portRect; + GetPortBounds(GetWindowPort( fl_window ), &portRect); + hgt = portRect.bottom-portRect.top; + } else { + hgt = CGBitmapContextGetHeight(fl_gc); + } + CGContextTranslateCTM(fl_gc, 0.5, hgt-0.5f); + CGContextScaleCTM(fl_gc, 1.0f, -1.0f); + fl_font(fl_fontsize); + fl_color(fl_color_); + fl_quartz_restore_line_style_(); +} + +// The only way to reset clipping to its original state is to pop the current graphics +// state and restore the global state. +void Fl_X::q_clear_clipping() { + if (!fl_gc) return; + CGContextRestoreGState(fl_gc); + CGContextSaveGState(fl_gc); +} + +// Give the Quartz context back to the system +void Fl_X::q_release_context(Fl_X *x) { + if (x && x->gc!=fl_gc) return; + if (!fl_gc) return; + CGContextRestoreGState(fl_gc); + if (fl_window) { + OSStatus err = QDEndCGContext(GetWindowPort(fl_window), &fl_gc); + if (err!=noErr) + fprintf(stderr, "Error %d in QDEndCGContext\n", (int)err); + } + fl_gc = 0; +} + +void Fl_X::q_begin_image(CGRect &rect, int cx, int cy, int w, int h) { + CGContextSaveGState(fl_gc); + CGAffineTransform mx = CGContextGetCTM(fl_gc); + CGRect r2 = rect; + r2.origin.x -= 0.5f; + r2.origin.y -= 0.5f; + CGContextClipToRect(fl_gc, r2); + mx.d = -1.0; mx.tx = -mx.tx; + CGContextConcatCTM(fl_gc, mx); + rect.origin.x = -(mx.tx+0.5f) + rect.origin.x - cx; + rect.origin.y = (mx.ty+0.5f) - rect.origin.y - h + cy; + rect.size.width = w; + rect.size.height = h; +} + +void Fl_X::q_end_image() { + CGContextRestoreGState(fl_gc); +} + +#endif + +//////////////////////////////////////////////////////////////// +// Cut & paste. + +Fl_Widget *fl_selection_requestor = 0; +char *fl_selection_buffer[2]; +int fl_selection_length[2]; +int fl_selection_buffer_length[2]; +static ScrapRef myScrap = 0; + +/** + * create a selection + * owner: widget that created the selection + * stuff: pointer to selected data + * size of selected data + */ +void Fl::copy(const char *stuff, int len, int clipboard) { + if (!stuff || len<0) return; + if (len+1 > fl_selection_buffer_length[clipboard]) { + delete[] fl_selection_buffer[clipboard]; + fl_selection_buffer[clipboard] = new char[len+100]; + fl_selection_buffer_length[clipboard] = len+100; + } + memcpy(fl_selection_buffer[clipboard], stuff, len); + fl_selection_buffer[clipboard][len] = 0; // needed for direct paste + fl_selection_length[clipboard] = len; + if (clipboard) { + ClearCurrentScrap(); + OSStatus ret = GetCurrentScrap( &myScrap ); + if ( ret != noErr ) { + myScrap = 0; + return; + } + // Previous version changed \n to \r before sending the text, but I would + // prefer to leave the local buffer alone, so a copied buffer may be + // needed. Check to see if this is necessary on OS/X. + PutScrapFlavor( myScrap, kScrapFlavorTypeText, 0, + len, fl_selection_buffer[1] ); + } +} + +// Call this when a "paste" operation happens: +void Fl::paste(Fl_Widget &receiver, int clipboard) { + if (clipboard) { + // see if we own the selection, if not go get it: + ScrapRef scrap = 0; + Size len = 0; + if (GetCurrentScrap(&scrap) == noErr && scrap != myScrap && + GetScrapFlavorSize(scrap, kScrapFlavorTypeText, &len) == noErr) { + if ( len >= fl_selection_buffer_length[1] ) { + fl_selection_buffer_length[1] = len + 32; + delete[] fl_selection_buffer[1]; + fl_selection_buffer[1] = new char[len + 32]; + } + fl_selection_length[1] = len; len++; + GetScrapFlavorData( scrap, kScrapFlavorTypeText, &len, + fl_selection_buffer[1] ); + fl_selection_buffer[1][fl_selection_length[1]] = 0; + // turn all \r characters into \n: + for (int x = 0; x < len; x++) { + if (fl_selection_buffer[1][x] == '\r') + fl_selection_buffer[1][x] = '\n'; + } + } + } + Fl::e_text = fl_selection_buffer[clipboard]; + Fl::e_length = fl_selection_length[clipboard]; + if (!Fl::e_text) Fl::e_text = (char *)""; + receiver.handle(FL_PASTE); + return; +} + +void Fl::add_timeout(double time, Fl_Timeout_Handler cb, void* data) +{ + // check, if this timer slot exists already + for (int i = 0; i < mac_timer_used; ++i) { + MacTimeout& t = mac_timers[i]; + // if so, simply change the fire interval + if (t.callback == cb && t.data == data) { + SetEventLoopTimerNextFireTime(t.timer, (EventTimerInterval)time); + t.pending = 1; + return; + } + } + // no existing timer to use. Create a new one: + int timer_id = -1; + // find an empty slot in the timer array + for (int i = 0; i < mac_timer_used; ++i) { + if ( !mac_timers[i].timer ) { + timer_id = i; + break; + } + } + // if there was no empty slot, append a new timer + if (timer_id == -1) { + // make space if needed + if (mac_timer_used == mac_timer_alloc) { + realloc_timers(); + } + timer_id = mac_timer_used++; + } + // now install a brand new timer + MacTimeout& t = mac_timers[timer_id]; + EventTimerInterval fireDelay = (EventTimerInterval)time; + EventLoopTimerUPP timerUPP = NewEventLoopTimerUPP(do_timer); + EventLoopTimerRef timerRef = 0; + OSStatus err = InstallEventLoopTimer(GetMainEventLoop(), fireDelay, 0, timerUPP, data, &timerRef); + if (err == noErr) { + t.callback = cb; + t.data = data; + t.timer = timerRef; + t.upp = timerUPP; + t.pending = 1; + } else { + if (timerRef) + RemoveEventLoopTimer(timerRef); + if (timerUPP) + DisposeEventLoopTimerUPP(timerUPP); + } +} + +void Fl::repeat_timeout(double time, Fl_Timeout_Handler cb, void* data) +{ + // currently, repeat_timeout does not subtract the trigger time of the previous timer event as it should. + add_timeout(time, cb, data); +} + +int Fl::has_timeout(Fl_Timeout_Handler cb, void* data) +{ + for (int i = 0; i < mac_timer_used; ++i) { + MacTimeout& t = mac_timers[i]; + if (t.callback == cb && t.data == data && t.pending) { + return 1; + } + } + return 0; +} + +void Fl::remove_timeout(Fl_Timeout_Handler cb, void* data) +{ + for (int i = 0; i < mac_timer_used; ++i) { + MacTimeout& t = mac_timers[i]; + if (t.callback == cb && ( t.data == data || data == NULL)) { + delete_timer(t); + } + } +} + +int MacUnlinkWindow(Fl_X *ip, Fl_X *start) { + if (!ip) return 0; + if (start) { + Fl_X *pc = start; + while (pc) { + if (pc->xidNext == ip) { + pc->xidNext = ip->xidNext; + return 1; + } + if (pc->xidChildren) { + if (pc->xidChildren == ip) { + pc->xidChildren = ip->xidNext; + return 1; + } + if (MacUnlinkWindow(ip, pc->xidChildren)) + return 1; + } + pc = pc->xidNext; + } + } else { + for ( Fl_X *pc = Fl_X::first; pc; pc = pc->next ) { + if (MacUnlinkWindow(ip, pc)) + return 1; + } + } + return 0; +} + +static void MacRelinkWindow(Fl_X *x, Fl_X *p) { + if (!x || !p) return; + // first, check if 'x' is already registered as a child of 'p' + for (Fl_X *i = p->xidChildren; i; i=i->xidNext) { + if (i == x) return; + } + // now add 'x' as the first child of 'p' + x->xidNext = p->xidChildren; + p->xidChildren = x; +} + +void MacDestroyWindow(Fl_Window *w, WindowPtr p) { + MacUnmapWindow(w, p); + if (w && !w->parent() && p) + DisposeWindow(p); +} + +void MacMapWindow(Fl_Window *w, WindowPtr p) { + if (w && p) + ShowWindow(p); + //+ link to window list + if (w && w->parent()) { + MacRelinkWindow(Fl_X::i(w), Fl_X::i(w->window())); + w->redraw(); + } +} + +void MacUnmapWindow(Fl_Window *w, WindowPtr p) { + if (w && !w->parent() && p) + HideWindow(p); + if (w && Fl_X::i(w)) + MacUnlinkWindow(Fl_X::i(w)); +} + +// +// End of "$Id: Fl_mac.cxx 6033 2008-02-20 18:17:34Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_own_colormap.cxx b/plugins/zynaddsubfx/fltk/src/Fl_own_colormap.cxx new file mode 100644 index 000000000..b0df4bbd6 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_own_colormap.cxx @@ -0,0 +1,83 @@ +// +// "$Id: Fl_own_colormap.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Private colormap support for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Using the default system colormap can be a bad idea on PseudoColor +// visuals, since typically every application uses the default colormap and +// you can run out of colormap entries easily. +// +// The solution is to always create a new colormap on PseudoColor displays +// and copy the first 16 colors from the default colormap so that we won't +// get huge color changes when switching windows. + +#include +#include +#include + +#ifdef WIN32 +// There is probably something relevant to do on MSWindows 8-bit displays +// but I don't know what it is + +void Fl::own_colormap() {} + +#elif defined(__APPLE__) +// MacOS X always provides a TrueColor interface... + +void Fl::own_colormap() {} +#else +// X version + +void Fl::own_colormap() { + fl_open_display(); +#if USE_COLORMAP + switch (fl_visual->c_class) { + case GrayScale : + case PseudoColor : + case DirectColor : + break; + default: + return; // don't do anything for non-colormapped visuals + } + int i; + XColor colors[16]; + // Get the first 16 colors from the default colormap... + for (i = 0; i < 16; i ++) colors[i].pixel = i; + XQueryColors(fl_display, fl_colormap, colors, 16); + // Create a new colormap... + fl_colormap = XCreateColormap(fl_display, + RootWindow(fl_display,fl_screen), + fl_visual->visual, AllocNone); + // Copy those first 16 colors to our own colormap: + for (i = 0; i < 16; i ++) + XAllocColor(fl_display, fl_colormap, colors + i); +#endif +} + +#endif + +// +// End of "$Id: Fl_own_colormap.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_visual.cxx b/plugins/zynaddsubfx/fltk/src/Fl_visual.cxx new file mode 100644 index 000000000..b0c954461 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_visual.cxx @@ -0,0 +1,121 @@ +// +// "$Id: Fl_visual.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Visual support for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Set the default visual according to passed switches: + +#include +#include +#include + +#ifdef WIN32 +int Fl::visual(int flags) { + fl_GetDC(0); + if (flags & FL_DOUBLE) return 0; + if (!(flags & FL_INDEX) && + GetDeviceCaps(fl_gc,BITSPIXEL) <= 8) return 0; + if ((flags & FL_RGB8) && GetDeviceCaps(fl_gc,BITSPIXEL)<24) return 0; + return 1; +} +#elif defined(__APPLE__) + +// \todo Mac : need to implement Visual flags +int Fl::visual(int flags) { + (void)flags; + return 1; +} + +#else + +#if USE_XDBE +#include +#endif + +static int test_visual(XVisualInfo& v, int flags) { + if (v.screen != fl_screen) return 0; +#if USE_COLORMAP + if (!(flags & FL_INDEX)) { + if (v.c_class != StaticColor && v.c_class != TrueColor) return 0; + if (v.depth <= 8) return 0; // fltk will work better in colormap mode + } + if (flags & FL_RGB8) { + if (v.depth < 24) return 0; + } + // for now, fltk does not like colormaps of more than 8 bits: + if ((v.c_class&1) && v.depth > 8) return 0; +#else + // simpler if we can't use colormapped visuals at all: + if (v.c_class != StaticColor && v.c_class != TrueColor) return 0; +#endif +#if USE_XDBE + if (flags & FL_DOUBLE) { + static XdbeScreenVisualInfo *xdbejunk; + if (!xdbejunk) { + int event_base, error_base; + if (!XdbeQueryExtension(fl_display, &event_base, &error_base)) return 0; + Drawable root = RootWindow(fl_display,fl_screen); + int numscreens = 1; + xdbejunk = XdbeGetVisualInfo(fl_display,&root,&numscreens); + if (!xdbejunk) return 0; + } + for (int j = 0; ; j++) { + if (j >= xdbejunk->count) return 0; + if (xdbejunk->visinfo[j].visual == v.visualid) break; + } + } +#endif + return 1; +} + +int Fl::visual(int flags) { +#if USE_XDBE == 0 + if (flags & FL_DOUBLE) return 0; +#endif + fl_open_display(); + // always use default if possible: + if (test_visual(*fl_visual, flags)) return 1; + // get all the visuals: + XVisualInfo vTemplate; + int num; + XVisualInfo *visualList = XGetVisualInfo(fl_display, 0, &vTemplate, &num); + // find all matches, use the one with greatest depth: + XVisualInfo *found = 0; + for (int i=0; idepth < visualList[i].depth) + found = &visualList[i]; + } + if (!found) {XFree((void*)visualList); return 0;} + fl_visual = found; + fl_colormap = XCreateColormap(fl_display, RootWindow(fl_display,fl_screen), + fl_visual->visual, AllocNone); + return 1; +} + +#endif + +// +// End of "$Id: Fl_visual.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_win32.cxx b/plugins/zynaddsubfx/fltk/src/Fl_win32.cxx new file mode 100644 index 000000000..78ce234ec --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_win32.cxx @@ -0,0 +1,1691 @@ +// +// "$Id: Fl_win32.cxx 6017 2008-01-10 21:53:34Z matt $" +// +// WIN32-specific code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2007 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// This file contains win32-specific code for fltk which is always linked +// in. Search other files for "WIN32" or filenames ending in _win32.cxx +// for other system-specific code. + +#include +#include +#include +#include +#include +#include "flstring.h" +#include "Fl_Font.H" +#include +#include +#include +#include +#ifdef __CYGWIN__ +# include +# include +#else +# include +#endif +#include +#include + +// The following include files require GCC 3.x or a non-GNU compiler... +#if !defined(__GNUC__) || __GNUC__ >= 3 +# include +# include +#endif // !__GNUC__ || __GNUC__ >= 3 + + +// +// USE_ASYNC_SELECT - define it if you have WSAAsyncSelect()... +// +// This currently doesn't appear to work; needs to be fixed! +// + +//#define USE_ASYNC_SELECT + + +// +// USE_TRACK_MOUSE - define it if you have TrackMouseEvent()... +// +// Apparently, at least some versions of Cygwin/MingW don't provide +// the TrackMouseEvent() function. You can define this by hand +// if you have it - this is only needed to support subwindow +// enter/leave notification under Windows. +// + +//#define USE_TRACK_MOUSE + +#if !defined(__GNUC__) +# define USE_TRACK_MOUSE +#endif // !__GNUC__ + + +// +// WM_SYNCPAINT is an "undocumented" message, which is finally defined in +// VC++ 6.0. +// + +#ifndef WM_SYNCPAINT +# define WM_SYNCPAINT 0x0088 +#endif + +#ifndef WM_MOUSELEAVE +# define WM_MOUSELEAVE 0x02a3 +#endif + +#ifndef WM_MOUSEWHEEL +# define WM_MOUSEWHEEL 0x020a +#endif + +#ifndef WHEEL_DELTA +# define WHEEL_DELTA 120 // according to MSDN. +#endif + + +// +// WM_FLSELECT is the user-defined message that we get when one of +// the sockets has pending data, etc. +// + +#define WM_FLSELECT (WM_APP+1) // WM_APP is used for hide-window + + +//////////////////////////////////////////////////////////////// +// interface to poll/select call: + +// fd's are only implemented for sockets. Microsoft Windows does not +// have a unified IO system, so it doesn't support select() on files, +// devices, or pipes... +// +// Microsoft provides the Berkeley select() call and an asynchronous +// select function that sends a WIN32 message when the select condition +// exists... +static int maxfd = 0; +#ifndef USE_ASYNC_SELECT +static fd_set fdsets[3]; +#endif // !USE_ASYNC_SELECT + +#define POLLIN 1 +#define POLLOUT 4 +#define POLLERR 8 + +#if !defined(__GNUC__) || __GNUC__ >= 3 +extern IDropTarget *flIDropTarget; +#endif // !__GNUC__ || __GNUC__ >= 3 + +static int nfds = 0; +static int fd_array_size = 0; +static struct FD { + int fd; + short events; + void (*cb)(int, void*); + void* arg; +} *fd = 0; + +void Fl::add_fd(int n, int events, void (*cb)(int, void*), void *v) { + remove_fd(n,events); + int i = nfds++; + if (i >= fd_array_size) { + fd_array_size = 2*fd_array_size+1; + fd = (FD*)realloc(fd, fd_array_size*sizeof(FD)); + } + fd[i].fd = n; + fd[i].events = (short)events; + fd[i].cb = cb; + fd[i].arg = v; + +#ifdef USE_ASYNC_SELECT + int mask = 0; + if (events & POLLIN) mask |= FD_READ; + if (events & POLLOUT) mask |= FD_WRITE; + if (events & POLLERR) mask |= FD_CLOSE; + WSAAsyncSelect(n, fl_window, WM_FLSELECT, mask); +#else + if (events & POLLIN) FD_SET((unsigned)n, &fdsets[0]); + if (events & POLLOUT) FD_SET((unsigned)n, &fdsets[1]); + if (events & POLLERR) FD_SET((unsigned)n, &fdsets[2]); + if (n > maxfd) maxfd = n; +#endif // USE_ASYNC_SELECT +} + +void Fl::add_fd(int fd, void (*cb)(int, void*), void* v) { + Fl::add_fd(fd, POLLIN, cb, v); +} + +void Fl::remove_fd(int n, int events) { + int i,j; + for (i=j=0; i0 if any callbacks were done. This version only +// returns zero if nothing happens during a 0.0 timeout, otherwise +// it returns 1. +int fl_wait(double time_to_wait) { + int have_message = 0; + + run_checks(); + + // idle processing + static char in_idle; + if (Fl::idle && !in_idle) { + in_idle = 1; + Fl::idle(); + in_idle = 0; + } + +#ifndef USE_ASYNC_SELECT + if (nfds) { + // For WIN32 we need to poll for socket input FIRST, since + // the event queue is not something we can select() on... + timeval t; + t.tv_sec = 0; + t.tv_usec = 0; + + fd_set fdt[3]; + fdt[0] = fdsets[0]; + fdt[1] = fdsets[1]; + fdt[2] = fdsets[2]; + if (::select(maxfd+1,&fdt[0],&fdt[1],&fdt[2],&t)) { + // We got something - do the callback! + for (int i = 0; i < nfds; i ++) { + int f = fd[i].fd; + short revents = 0; + if (FD_ISSET(f,&fdt[0])) revents |= POLLIN; + if (FD_ISSET(f,&fdt[1])) revents |= POLLOUT; + if (FD_ISSET(f,&fdt[2])) revents |= POLLERR; + if (fd[i].events & revents) fd[i].cb(f, fd[i].arg); + } + time_to_wait = 0.0; // just peek for any messages + } else { + // we need to check them periodically, so set a short timeout: + if (time_to_wait > .001) time_to_wait = .001; + } + } +#endif // USE_ASYNC_SELECT + + if (Fl::idle || Fl::damage()) + time_to_wait = 0.0; + + // if there are no more windows and this timer is set + // to FOREVER, continue through or look up indefinetely + if (!Fl::first_window() && time_to_wait==1e20) + time_to_wait = 0.0; + + fl_unlock_function(); + + time_to_wait = (time_to_wait > 10000 ? 10000 : time_to_wait); + int t_msec = (int) (time_to_wait * 1000.0 + 0.5); + MsgWaitForMultipleObjects(0, NULL, FALSE, t_msec, QS_ALLINPUT); + + fl_lock_function(); + + // Execute the message we got, and all other pending messages: + have_message = PeekMessage(&fl_msg, NULL, 0, 0, PM_REMOVE); + if (have_message > 0) { + while (have_message != 0 && have_message != -1) { +#ifdef USE_ASYNC_SELECT + if (fl_msg.message == WM_FLSELECT) { + // Got notification for socket + for (int i = 0; i < nfds; i ++) + if (fd[i].fd == (int)fl_msg.wParam) { + (fd[i].cb)(fd[i].fd, fd[i].arg); + break; + } + // looks like it is best to do the dispatch-message anyway: + } +#endif + + if (fl_msg.message == fl_wake_msg) { + // Used for awaking wait() from another thread + thread_message_ = (void*)fl_msg.wParam; + Fl_Awake_Handler func; + void *data; + while (Fl::get_awake_handler_(func, data)==0) { + func(data); + } + } + + TranslateMessage(&fl_msg); + DispatchMessage(&fl_msg); + have_message = PeekMessage(&fl_msg, NULL, 0, 0, PM_REMOVE); + } + } + Fl::flush(); + + // This should return 0 if only timer events were handled: + return 1; +} + +// fl_ready() is just like fl_wait(0.0) except no callbacks are done: +int fl_ready() { + if (PeekMessage(&fl_msg, NULL, 0, 0, PM_NOREMOVE)) return 1; +#ifdef USE_ASYNC_SELECT + return 0; +#else + timeval t; + t.tv_sec = 0; + t.tv_usec = 0; + fd_set fdt[3]; + fdt[0] = fdsets[0]; + fdt[1] = fdsets[1]; + fdt[2] = fdsets[2]; + return ::select(0,&fdt[0],&fdt[1],&fdt[2],&t); +#endif // USE_ASYNC_SELECT +} + +//////////////////////////////////////////////////////////////// + +int Fl::x() +{ + RECT r; + + SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0); + return r.left; +} + +int Fl::y() +{ + RECT r; + + SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0); + return r.top; +} + +int Fl::h() +{ + RECT r; + + SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0); + return r.bottom - r.top; +} + +int Fl::w() +{ + RECT r; + + SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0); + return r.right - r.left; +} + +void Fl::get_mouse(int &x, int &y) { + POINT p; + GetCursorPos(&p); + x = p.x; + y = p.y; +} + +//////////////////////////////////////////////////////////////// +// code used for selections: + +char *fl_selection_buffer[2]; +int fl_selection_length[2]; +int fl_selection_buffer_length[2]; +char fl_i_own_selection[2]; + +// Convert \n -> \r\n +class Lf2CrlfConvert { + char *out; + int outlen; +public: + Lf2CrlfConvert(const char *in, int inlen) { + outlen = 0; + const char *i; + char *o; + int lencount; + // Predict size of \r\n conversion buffer + for ( i=in, lencount = inlen; lencount--; ) { + if ( *i == '\r' && *(i+1) == '\n' ) // leave \r\n untranslated + { i+=2; outlen+=2; } + else if ( *i == '\n' ) // \n by itself? leave room to insert \r + { i++; outlen+=2; } + else + { ++i; ++outlen; } + } + // Alloc conversion buffer + NULL + out = new char[outlen+1]; + // Handle \n -> \r\n conversion + for ( i=in, o=out, lencount = inlen; lencount--; ) { + if ( *i == '\r' && *(i+1) == '\n' ) // leave \r\n untranslated + { *o++ = *i++; *o++ = *i++; } + else if ( *i == '\n' ) // \n by itself? insert \r + { *o++ = '\r'; *o++ = *i++; } + else + { *o++ = *i++; } + } + *o++ = 0; + } + ~Lf2CrlfConvert() { + delete[] out; + } + int GetLength() const { return(outlen); } + const char* GetValue() const { return(out); } +}; + +// call this when you create a selection: +void Fl::copy(const char *stuff, int len, int clipboard) { + if (!stuff || len<0) return; + + // Convert \n -> \r\n (for old apps like Notepad, DOS) + Lf2CrlfConvert buf(stuff, len); + len = buf.GetLength(); + stuff = buf.GetValue(); + + if (len+1 > fl_selection_buffer_length[clipboard]) { + delete[] fl_selection_buffer[clipboard]; + fl_selection_buffer[clipboard] = new char[len+100]; + fl_selection_buffer_length[clipboard] = len+100; + } + memcpy(fl_selection_buffer[clipboard], stuff, len); + fl_selection_buffer[clipboard][len] = 0; // needed for direct paste + fl_selection_length[clipboard] = len; + if (clipboard) { + // set up for "delayed rendering": + if (OpenClipboard(fl_xid(Fl::first_window()))) { + // if the system clipboard works, use it + EmptyClipboard(); + SetClipboardData(CF_TEXT, NULL); + CloseClipboard(); + fl_i_own_selection[clipboard] = 0; + } else { + // only if it fails, instruct paste() to use the internal buffers + fl_i_own_selection[clipboard] = 1; + } + } +} + +// Call this when a "paste" operation happens: +void Fl::paste(Fl_Widget &receiver, int clipboard) { + if (!clipboard || fl_i_own_selection[clipboard]) { + // We already have it, do it quickly without window server. + // Notice that the text is clobbered if set_selection is + // called in response to FL_PASTE! + + // Convert \r\n -> \n + char *i = fl_selection_buffer[clipboard]; + if (i==0L) { + Fl::e_text = 0; + return; + } + Fl::e_text = new char[fl_selection_length[clipboard]+1]; + char *o = Fl::e_text; + while (*i) { + if ( *i == '\r' && *(i+1) == '\n') i++; + else *o++ = *i++; + } + *o = 0; + Fl::e_length = o - Fl::e_text; + receiver.handle(FL_PASTE); + delete [] Fl::e_text; + Fl::e_text = 0; + } else { + if (!OpenClipboard(NULL)) return; + HANDLE h = GetClipboardData(CF_TEXT); + if (h) { + Fl::e_text = (LPSTR)GlobalLock(h); + LPSTR a,b; + a = b = Fl::e_text; + while (*a) { // strip the CRLF pairs ($%$#@^) + if (*a == '\r' && a[1] == '\n') a++; + else *b++ = *a++; + } + *b = 0; + Fl::e_length = b - Fl::e_text; + receiver.handle(FL_PASTE); + GlobalUnlock(h); + } + CloseClipboard(); + } +} + +//////////////////////////////////////////////////////////////// + +HWND fl_capture; + +static int mouse_event(Fl_Window *window, int what, int button, + WPARAM wParam, LPARAM lParam) +{ + static int px, py, pmx, pmy; + POINT pt; + Fl::e_x = pt.x = (signed short)LOWORD(lParam); + Fl::e_y = pt.y = (signed short)HIWORD(lParam); + ClientToScreen(fl_xid(window), &pt); + Fl::e_x_root = pt.x; + Fl::e_y_root = pt.y; + while (window->parent()) { + Fl::e_x += window->x(); + Fl::e_y += window->y(); + window = window->window(); + } + + ulong state = Fl::e_state & 0xff0000; // keep shift key states +#if 0 + // mouse event reports some shift flags, perhaps save them? + if (wParam & MK_SHIFT) state |= FL_SHIFT; + if (wParam & MK_CONTROL) state |= FL_CTRL; +#endif + if (wParam & MK_LBUTTON) state |= FL_BUTTON1; + if (wParam & MK_MBUTTON) state |= FL_BUTTON2; + if (wParam & MK_RBUTTON) state |= FL_BUTTON3; + Fl::e_state = state; + + switch (what) { + case 1: // double-click + if (Fl::e_is_click) {Fl::e_clicks++; goto J1;} + case 0: // single-click + Fl::e_clicks = 0; + J1: + if (!fl_capture) SetCapture(fl_xid(window)); + Fl::e_keysym = FL_Button + button; + Fl::e_is_click = 1; + px = pmx = Fl::e_x_root; py = pmy = Fl::e_y_root; + return Fl::handle(FL_PUSH,window); + + case 2: // release: + if (!fl_capture) ReleaseCapture(); + Fl::e_keysym = FL_Button + button; + return Fl::handle(FL_RELEASE,window); + + case 3: // move: + default: // avoid compiler warning + // MSWindows produces extra events even if mouse does not move, ignore em: + if (Fl::e_x_root == pmx && Fl::e_y_root == pmy) return 1; + pmx = Fl::e_x_root; pmy = Fl::e_y_root; + if (abs(Fl::e_x_root-px)>5 || abs(Fl::e_y_root-py)>5) Fl::e_is_click = 0; + return Fl::handle(FL_MOVE,window); + + } +} + +// convert a MSWindows VK_x to an Fltk (X) Keysym: +// See also the inverse converter in Fl_get_key_win32.cxx +// This table is in numeric order by VK: +static const struct {unsigned short vk, fltk, extended;} vktab[] = { + {VK_BACK, FL_BackSpace}, + {VK_TAB, FL_Tab}, + {VK_CLEAR, FL_KP+'5', 0xff0b/*XK_Clear*/}, + {VK_RETURN, FL_Enter, FL_KP_Enter}, + {VK_SHIFT, FL_Shift_L, FL_Shift_R}, + {VK_CONTROL, FL_Control_L, FL_Control_R}, + {VK_MENU, FL_Alt_L, FL_Alt_R}, + {VK_PAUSE, FL_Pause}, + {VK_CAPITAL, FL_Caps_Lock}, + {VK_ESCAPE, FL_Escape}, + {VK_SPACE, ' '}, + {VK_PRIOR, FL_KP+'9', FL_Page_Up}, + {VK_NEXT, FL_KP+'3', FL_Page_Down}, + {VK_END, FL_KP+'1', FL_End}, + {VK_HOME, FL_KP+'7', FL_Home}, + {VK_LEFT, FL_KP+'4', FL_Left}, + {VK_UP, FL_KP+'8', FL_Up}, + {VK_RIGHT, FL_KP+'6', FL_Right}, + {VK_DOWN, FL_KP+'2', FL_Down}, + {VK_SNAPSHOT, FL_Print}, // does not work on NT + {VK_INSERT, FL_KP+'0', FL_Insert}, + {VK_DELETE, FL_KP+'.', FL_Delete}, + {VK_LWIN, FL_Meta_L}, + {VK_RWIN, FL_Meta_R}, + {VK_APPS, FL_Menu}, + {VK_MULTIPLY, FL_KP+'*'}, + {VK_ADD, FL_KP+'+'}, + {VK_SUBTRACT, FL_KP+'-'}, + {VK_DECIMAL, FL_KP+'.'}, + {VK_DIVIDE, FL_KP+'/'}, + {VK_NUMLOCK, FL_Num_Lock}, + {VK_SCROLL, FL_Scroll_Lock}, + {0xba, ';'}, + {0xbb, '='}, + {0xbc, ','}, + {0xbd, '-'}, + {0xbe, '.'}, + {0xbf, '/'}, + {0xc0, '`'}, + {0xdb, '['}, + {0xdc, '\\'}, + {0xdd, ']'}, + {0xde, '\''} +}; +static int ms2fltk(int vk, int extended) { + static unsigned short vklut[256]; + static unsigned short extendedlut[256]; + if (!vklut[1]) { // init the table + unsigned int i; + for (i = 0; i < 256; i++) vklut[i] = tolower(i); + for (i=VK_F1; i<=VK_F16; i++) vklut[i] = i+(FL_F-(VK_F1-1)); + for (i=VK_NUMPAD0; i<=VK_NUMPAD9; i++) vklut[i] = i+(FL_KP+'0'-VK_NUMPAD0); + for (i = 0; i < sizeof(vktab)/sizeof(*vktab); i++) { + vklut[vktab[i].vk] = vktab[i].fltk; + extendedlut[vktab[i].vk] = vktab[i].extended; + } + for (i = 0; i < 256; i++) if (!extendedlut[i]) extendedlut[i] = vklut[i]; + } + return extended ? extendedlut[vk] : vklut[vk]; +} + +#if USE_COLORMAP +extern HPALETTE fl_select_palette(void); // in fl_color_win32.cxx +#endif + + +///////////////////////////////////////////////////////////////////////////// +/// Win32 timers +/// + +struct Win32Timer +{ + UINT_PTR handle; + Fl_Timeout_Handler callback; + void *data; +}; +static Win32Timer* win32_timers; +static int win32_timer_alloc; +static int win32_timer_used; +static HWND s_TimerWnd; + +static void realloc_timers() +{ + if (win32_timer_alloc == 0) { + win32_timer_alloc = 8; + } + win32_timer_alloc *= 2; + Win32Timer* new_timers = new Win32Timer[win32_timer_alloc]; + memset(new_timers, 0, sizeof(Win32Timer) * win32_timer_used); + memcpy(new_timers, win32_timers, sizeof(Win32Timer) * win32_timer_used); + Win32Timer* delete_me = win32_timers; + win32_timers = new_timers; + delete [] delete_me; +} + +static void delete_timer(Win32Timer& t) +{ + KillTimer(s_TimerWnd, t.handle); + memset(&t, 0, sizeof(Win32Timer)); +} + +/// END TIMERS +///////////////////////////////////////////////////////////////////////////// + +static Fl_Window* resize_bug_fix; + +extern void fl_save_pen(void); +extern void fl_restore_pen(void); + +static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + // Copy the message to fl_msg so add_handler code can see it, it is + // already there if this is called by DispatchMessage, but not if + // Windows calls this directly. + fl_msg.hwnd = hWnd; + fl_msg.message = uMsg; + fl_msg.wParam = wParam; + fl_msg.lParam = lParam; + //fl_msg.time = ??? + //fl_msg.pt = ??? + //fl_msg.lPrivate = ??? + + Fl_Window *window = fl_find(hWnd); + + if (window) switch (uMsg) { + + case WM_QUIT: // this should not happen? + Fl::fatal("WM_QUIT message"); + + case WM_CLOSE: // user clicked close box + Fl::handle(FL_CLOSE, window); + PostQuitMessage(0); + return 0; + + case WM_SYNCPAINT : + case WM_NCPAINT : + case WM_ERASEBKGND : + // Andreas Weitl - WM_SYNCPAINT needs to be passed to DefWindowProc + // so that Windows can generate the proper paint messages... + // Similarly, WM_NCPAINT and WM_ERASEBKGND need this, too... + break; + + case WM_PAINT: { + Fl_Region R; + Fl_X *i = Fl_X::i(window); + i->wait_for_expose = 0; + char redraw_whole_window = false; + if (!i->region && window->damage()) { + // Redraw the whole window... + i->region = CreateRectRgn(0, 0, window->w(), window->h()); + redraw_whole_window = true; + } + + // We need to merge WIN32's damage into FLTK's damage. + R = CreateRectRgn(0,0,0,0); + int r = GetUpdateRgn(hWnd,R,0); + if (r==NULLREGION && !redraw_whole_window) { + break; + } + + if (i->region) { + // Also tell WIN32 that we are drawing someplace else as well... + CombineRgn(i->region, i->region, R, RGN_OR); + XDestroyRegion(R); + } else { + i->region = R; + } + if (window->type() == FL_DOUBLE_WINDOW) ValidateRgn(hWnd,0); + else ValidateRgn(hWnd,i->region); + + window->clear_damage((uchar)(window->damage()|FL_DAMAGE_EXPOSE)); + // These next two statements should not be here, so that all update + // is deferred until Fl::flush() is called during idle. However WIN32 + // apparently is very unhappy if we don't obey it and draw right now. + // Very annoying! + fl_GetDC(hWnd); // Make sure we have a DC for this window... + fl_save_pen(); + i->flush(); + fl_restore_pen(); + window->clear_damage(); + } return 0; + + case WM_LBUTTONDOWN: mouse_event(window, 0, 1, wParam, lParam); return 0; + case WM_LBUTTONDBLCLK:mouse_event(window, 1, 1, wParam, lParam); return 0; + case WM_LBUTTONUP: mouse_event(window, 2, 1, wParam, lParam); return 0; + case WM_MBUTTONDOWN: mouse_event(window, 0, 2, wParam, lParam); return 0; + case WM_MBUTTONDBLCLK:mouse_event(window, 1, 2, wParam, lParam); return 0; + case WM_MBUTTONUP: mouse_event(window, 2, 2, wParam, lParam); return 0; + case WM_RBUTTONDOWN: mouse_event(window, 0, 3, wParam, lParam); return 0; + case WM_RBUTTONDBLCLK:mouse_event(window, 1, 3, wParam, lParam); return 0; + case WM_RBUTTONUP: mouse_event(window, 2, 3, wParam, lParam); return 0; + + case WM_MOUSEMOVE: +#ifdef USE_TRACK_MOUSE + if (Fl::belowmouse() != window) { + TRACKMOUSEEVENT tme; + tme.cbSize = sizeof(TRACKMOUSEEVENT); + tme.dwFlags = TME_LEAVE; + tme.hwndTrack = hWnd; + _TrackMouseEvent(&tme); + } +#endif // USE_TRACK_MOUSE + mouse_event(window, 3, 0, wParam, lParam); + return 0; + + case WM_MOUSELEAVE: + Fl::belowmouse(0); + if (!window->parent()) Fl::handle(FL_LEAVE, window); + break; + + case WM_SETFOCUS: + Fl::handle(FL_FOCUS, window); + break; + + case WM_KILLFOCUS: + Fl::handle(FL_UNFOCUS, window); + Fl::flush(); // it never returns to main loop when deactivated... + break; + + case WM_SHOWWINDOW: + if (!window->parent()) { + Fl::handle(wParam ? FL_SHOW : FL_HIDE, window); + } + break; + + case WM_ACTIVATEAPP: + // From eric@vfx.sel.sony.com, we should process WM_ACTIVATEAPP + // messages to restore the correct state of the shift/ctrl/alt/lock + // keys... Added control, shift, alt, and meta keys, and changed + // to use GetAsyncKeyState and do it when wParam is 1 + // (that means we have focus...) + if (wParam) + { + ulong state = 0; + if (GetAsyncKeyState(VK_CAPITAL)) state |= FL_CAPS_LOCK; + if (GetAsyncKeyState(VK_NUMLOCK)) state |= FL_NUM_LOCK; + if (GetAsyncKeyState(VK_SCROLL)) state |= FL_SCROLL_LOCK; + if (GetAsyncKeyState(VK_CONTROL)&~1) state |= FL_CTRL; + if (GetAsyncKeyState(VK_SHIFT)&~1) state |= FL_SHIFT; + if (GetAsyncKeyState(VK_MENU)) state |= FL_ALT; + if ((GetAsyncKeyState(VK_LWIN)|GetAsyncKeyState(VK_RWIN))&~1) state |= FL_META; + Fl::e_state = state; + return 0; + } + break; + + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + case WM_KEYUP: + case WM_SYSKEYUP: + // save the keysym until we figure out the characters: + Fl::e_keysym = Fl::e_original_keysym = ms2fltk(wParam,lParam&(1<<24)); + // See if TranslateMessage turned it into a WM_*CHAR message: + if (PeekMessage(&fl_msg, hWnd, WM_CHAR, WM_SYSDEADCHAR, PM_REMOVE)) { + uMsg = fl_msg.message; + wParam = fl_msg.wParam; + lParam = fl_msg.lParam; + } + case WM_DEADCHAR: + case WM_SYSDEADCHAR: + case WM_CHAR: + case WM_SYSCHAR: { + ulong state = Fl::e_state & 0xff000000; // keep the mouse button state + // if GetKeyState is expensive we might want to comment some of these out: + if (GetKeyState(VK_SHIFT)&~1) state |= FL_SHIFT; + if (GetKeyState(VK_CAPITAL)) state |= FL_CAPS_LOCK; + if (GetKeyState(VK_CONTROL)&~1) state |= FL_CTRL; + // Alt gets reported for the Alt-GR switch on foreign keyboards. + // so we need to check the event as well to get it right: + if ((lParam&(1<<29)) //same as GetKeyState(VK_MENU) + && uMsg != WM_CHAR) state |= FL_ALT; + if (GetKeyState(VK_NUMLOCK)) state |= FL_NUM_LOCK; + if ((GetKeyState(VK_LWIN)|GetKeyState(VK_RWIN))&~1) { + // WIN32 bug? GetKeyState returns garbage if the user hit the + // meta key to pop up start menu. Sigh. + if ((GetAsyncKeyState(VK_LWIN)|GetAsyncKeyState(VK_RWIN))&~1) + state |= FL_META; + } + if (GetKeyState(VK_SCROLL)) state |= FL_SCROLL_LOCK; + Fl::e_state = state; + static char buffer[2]; + if (uMsg == WM_CHAR || uMsg == WM_SYSCHAR) { + buffer[0] = char(wParam); + Fl::e_length = 1; + } else if (Fl::e_keysym >= FL_KP && Fl::e_keysym <= FL_KP_Last) { + if (state & FL_NUM_LOCK) { + // Convert to regular keypress... + buffer[0] = Fl::e_keysym-FL_KP; + Fl::e_length = 1; + } else { + // Convert to special keypress... + buffer[0] = 0; + Fl::e_length = 0; + switch (Fl::e_keysym) { + case FL_KP + '0' : + Fl::e_keysym = FL_Insert; + break; + case FL_KP + '1' : + Fl::e_keysym = FL_End; + break; + case FL_KP + '2' : + Fl::e_keysym = FL_Down; + break; + case FL_KP + '3' : + Fl::e_keysym = FL_Page_Down; + break; + case FL_KP + '4' : + Fl::e_keysym = FL_Left; + break; + case FL_KP + '6' : + Fl::e_keysym = FL_Right; + break; + case FL_KP + '7' : + Fl::e_keysym = FL_Home; + break; + case FL_KP + '8' : + Fl::e_keysym = FL_Up; + break; + case FL_KP + '9' : + Fl::e_keysym = FL_Page_Up; + break; + case FL_KP + '.' : + Fl::e_keysym = FL_Delete; + break; + case FL_KP + '/' : + case FL_KP + '*' : + case FL_KP + '-' : + case FL_KP + '+' : + buffer[0] = Fl::e_keysym-FL_KP; + Fl::e_length = 1; + break; + } + } + } else if ((lParam & (1<<31))==0){ + buffer[0] = 0; + Fl::e_length = 0; + } + Fl::e_text = buffer; + if (lParam & (1<<31)) { // key up events. + if (Fl::handle(FL_KEYUP, window)) return 0; + break; + } + // for (int i = lParam&0xff; i--;) + while (window->parent()) window = window->window(); + if (Fl::handle(FL_KEYBOARD,window)) return 0; + break;} + + case WM_MOUSEWHEEL: { + static int delta = 0; // running total of all motion + delta += (SHORT)(HIWORD(wParam)); + Fl::e_dy = -delta / WHEEL_DELTA; + delta += Fl::e_dy * WHEEL_DELTA; + if (Fl::e_dy) Fl::handle(FL_MOUSEWHEEL, window); + return 0; + } + + case WM_GETMINMAXINFO: + Fl_X::i(window)->set_minmax((LPMINMAXINFO)lParam); + break; + + case WM_SIZE: + if (!window->parent()) { + if (wParam == SIZE_MINIMIZED || wParam == SIZE_MAXHIDE) { + Fl::handle(FL_HIDE, window); + } else { + Fl::handle(FL_SHOW, window); + resize_bug_fix = window; + window->size(LOWORD(lParam), HIWORD(lParam)); + } + } + break; + + case WM_MOVE: { + resize_bug_fix = window; + int nx = LOWORD(lParam); + int ny = HIWORD(lParam); + if (nx & 0x8000) nx -= 65536; + if (ny & 0x8000) ny -= 65536; + window->position(nx, ny); } + break; + + case WM_SETCURSOR: + if (LOWORD(lParam) == HTCLIENT) { + while (window->parent()) window = window->window(); + SetCursor(Fl_X::i(window)->cursor); + return 0; + } + break; + +#if USE_COLORMAP + case WM_QUERYNEWPALETTE : + fl_GetDC(hWnd); + if (fl_select_palette()) InvalidateRect(hWnd, NULL, FALSE); + break; + + case WM_PALETTECHANGED: + fl_GetDC(hWnd); + if ((HWND)wParam != hWnd && fl_select_palette()) UpdateColors(fl_gc); + break; + + case WM_CREATE : + fl_GetDC(hWnd); + fl_select_palette(); + break; +#endif + + case WM_DESTROYCLIPBOARD: + fl_i_own_selection[1] = 0; + return 1; + + case WM_RENDERALLFORMATS: + fl_i_own_selection[1] = 0; + // Windoze seems unhappy unless I do these two steps. Documentation + // seems to vary on whether opening the clipboard is necessary or + // is in fact wrong: + CloseClipboard(); + OpenClipboard(NULL); + // fall through... + case WM_RENDERFORMAT: { + HANDLE h = GlobalAlloc(GHND, fl_selection_length[1]+1); + if (h) { + LPSTR p = (LPSTR)GlobalLock(h); + memcpy(p, fl_selection_buffer[1], fl_selection_length[1]); + p[fl_selection_length[1]] = 0; + GlobalUnlock(h); + SetClipboardData(CF_TEXT, h); + } + // Windoze also seems unhappy if I don't do this. Documentation very + // unclear on what is correct: + if (fl_msg.message == WM_RENDERALLFORMATS) CloseClipboard(); + return 1;} + + default: + if (Fl::handle(0,0)) return 0; + break; + } + + return DefWindowProc(hWnd, uMsg, wParam, lParam); +} + +//////////////////////////////////////////////////////////////// +// This function gets the dimensions of the top/left borders and +// the title bar, if there is one, based on the FL_BORDER, FL_MODAL +// and FL_NONMODAL flags, and on the window's size range. +// It returns the following values: +// +// value | border | title bar +// 0 | none | no +// 1 | fix | yes +// 2 | size | yes + +int Fl_X::fake_X_wm(const Fl_Window* w,int &X,int &Y, int &bt,int &bx, int &by) { + int W, H, xoff, yoff, dx, dy; + int ret = bx = by = bt = 0; + + int fallback = 1; + if (!w->parent()) { + HWND hwnd = fl_xid(w); + if (hwnd) { + // The block below calculates the window borders by requesting the + // required decorated window rectangle for a desired client rectangle. + // If any part of the function above fails, we will drop to a + // fallback to get the best guess which is always available. + HWND hwnd = fl_xid(w); + // request the style flags of this window, as WIN32 sees them + LONG style = GetWindowLong(hwnd, GWL_STYLE); + LONG exstyle = GetWindowLong(hwnd, GWL_EXSTYLE); + RECT r; + r.left = w->x(); + r.top = w->y(); + r.right = w->x()+w->w(); + r.bottom = w->y()+w->h(); + // get the decoration rectangle for the desired client rectangle + BOOL ok = AdjustWindowRectEx(&r, style, FALSE, exstyle); + if (ok) { + X = r.left; + Y = r.top; + W = r.right - r.left; + H = r.bottom - r.top; + bx = w->x() - r.left; + by = r.bottom - w->y() - w->h(); // height of the bootm frame + bt = w->y() - r.top - by; // height of top caption bar + xoff = bx; + yoff = by + bt; + dx = W - w->w(); + dy = H - w->h(); + if (w->size_range_set && (w->maxw != w->minw || w->maxh != w->minh)) + ret = 2; + else + ret = 1; + fallback = 0; + } + } + } + // This is the original (pre 1.1.7) routine to calculate window border sizes. + if (fallback) { + if (w->border() && !w->parent()) { + if (w->size_range_set && (w->maxw != w->minw || w->maxh != w->minh)) { + ret = 2; + bx = GetSystemMetrics(SM_CXSIZEFRAME); + by = GetSystemMetrics(SM_CYSIZEFRAME); + } else { + ret = 1; + bx = GetSystemMetrics(SM_CXFIXEDFRAME); + by = GetSystemMetrics(SM_CYFIXEDFRAME); + } + bt = GetSystemMetrics(SM_CYCAPTION); + } + //The coordinates of the whole window, including non-client area + xoff = bx; + yoff = by + bt; + dx = 2*bx; + dy = 2*by + bt; + X = w->x()-xoff; + Y = w->y()-yoff; + W = w->w()+dx; + H = w->h()+dy; + } + + //Proceed to positioning the window fully inside the screen, if possible + //Make border's lower right corner visible + int scr_x, scr_y, scr_w, scr_h; + Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h, X, Y); + if (scr_x+scr_w < X+W) X = scr_x+scr_w - W; + if (scr_y+scr_h < Y+H) Y = scr_y+scr_h - H; + //Make border's upper left corner visible + if (Xw()) X = scr_x+scr_w - w->w() - dx; + if (scr_y+scr_h < Y+dy+ w->h()) Y = scr_y+scr_h - w->h() - dy; + //Make client area's upper left corner visible + if (X+xoff < scr_x) X = scr_x-xoff; + if (Y+yoff < scr_y) Y = scr_y-yoff; + //Return the client area's top left corner in (X,Y) + X+=xoff; + Y+=yoff; + + return ret; +} + +//////////////////////////////////////////////////////////////// + +void Fl_Window::resize(int X,int Y,int W,int H) { + UINT flags = SWP_NOSENDCHANGING | SWP_NOZORDER + | SWP_NOACTIVATE | SWP_NOOWNERZORDER; + int is_a_resize = (W != w() || H != h()); + int resize_from_program = (this != resize_bug_fix); + if (!resize_from_program) resize_bug_fix = 0; + if (X != x() || Y != y()) { + set_flag(FL_FORCE_POSITION); + } else { + if (!is_a_resize) return; + flags |= SWP_NOMOVE; + } + if (is_a_resize) { + Fl_Group::resize(X,Y,W,H); + if (visible_r()) { + redraw(); + // only wait for exposure if this window has a size - a window + // with no width or height will never get an exposure event + if (i && W>0 && H>0) + i->wait_for_expose = 1; + } + } else { + x(X); y(Y); + flags |= SWP_NOSIZE; + } + if (!border()) flags |= SWP_NOACTIVATE; + if (resize_from_program && shown()) { + if (!resizable()) size_range(w(),h(),w(),h()); + int dummy_x, dummy_y, bt, bx, by; + //Ignore window managing when resizing, so that windows (and more + //specifically menus) can be moved offscreen. + if (Fl_X::fake_X_wm(this, dummy_x, dummy_y, bt, bx, by)) { + X -= bx; + Y -= by+bt; + W += 2*bx; + H += 2*by+bt; + } + // avoid zero size windows. A zero sized window on Win32 + // will cause continouly new redraw events. + if (W<=0) W = 1; + if (H<=0) H = 1; + SetWindowPos(i->xid, 0, X, Y, W, H, flags); + } +} + +//////////////////////////////////////////////////////////////// + +/* + * This silly little class remembers the name of all window classes + * we register to avoid double registration. It has the added bonus + * of freeing everything on application colse as well. + */ +class NameList { +public: + NameList() { name = (char**)malloc(sizeof(char**)); NName = 1; nName = 0; } + ~NameList() { + int i; + for (i=0; iparent() && !Fl_X::i(w->window())) { + w->set_visible(); + return 0L; + } + + static NameList class_name_list; + static const char *first_class_name = 0L; + const char *class_name = w->xclass(); + if (!class_name) class_name = first_class_name; // reuse first class name used + if (!class_name) class_name = "FLTK"; // default to create a "FLTK" WNDCLASS + if (!first_class_name) { + first_class_name = class_name; + } + + if (!class_name_list.has_name(class_name)) { + WNDCLASSEX wc; + memset(&wc, 0, sizeof(wc)); + wc.cbSize = sizeof(WNDCLASSEX); + // Documentation states a device context consumes about 800 bytes + // of memory... so who cares? If 800 bytes per window is what it + // takes to speed things up, I'm game. + //wc.style = CS_HREDRAW | CS_VREDRAW | CS_CLASSDC | CS_DBLCLKS; + wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS; + wc.lpfnWndProc = (WNDPROC)WndProc; + wc.hInstance = fl_display; + if (!w->icon()) + w->icon((void *)LoadIcon(NULL, IDI_APPLICATION)); + wc.hIcon = wc.hIconSm = (HICON)w->icon(); + wc.hCursor = fl_default_cursor = LoadCursor(NULL, IDC_ARROW); + //uchar r,g,b; Fl::get_color(FL_GRAY,r,g,b); + //wc.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(r,g,b)); + wc.lpszClassName = class_name; + RegisterClassEx(&wc); + class_name_list.add_name(class_name); + } + + const char* message_name = "FLTK::ThreadWakeup"; + if (!fl_wake_msg) fl_wake_msg = RegisterWindowMessage(message_name); + + HWND parent; + DWORD style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS; + DWORD styleEx = WS_EX_LEFT; + + int xp = w->x(); + int yp = w->y(); + int wp = w->w(); + int hp = w->h(); + + int showit = 1; + + if (w->parent()) { + style |= WS_CHILD; + styleEx |= WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT; + parent = fl_xid(w->window()); + } else { + if (!w->size_range_set) { + if (w->resizable()) { + Fl_Widget *o = w->resizable(); + int minw = o->w(); if (minw > 100) minw = 100; + int minh = o->h(); if (minh > 100) minh = 100; + w->size_range(w->w() - o->w() + minw, w->h() - o->h() + minh, 0, 0); + } else { + w->size_range(w->w(), w->h(), w->w(), w->h()); + } + } + styleEx |= WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT; + int xwm = xp , ywm = yp , bt, bx, by; + switch (fake_X_wm(w, xwm, ywm, bt, bx, by)) { + // No border (used for menus) + case 0: style |= WS_POPUP; + styleEx |= WS_EX_TOOLWINDOW; + break; + + // Thin border and title bar + case 1: style |= WS_DLGFRAME | WS_CAPTION; break; + + // Thick, resizable border and title bar, with maximize button + case 2: style |= WS_THICKFRAME | WS_MAXIMIZEBOX | WS_CAPTION ; break; + } + if (by+bt) { + if (!w->modal()) style |= WS_SYSMENU | WS_MINIMIZEBOX; + wp += 2*bx; + hp += 2*by+bt; + } + if (!(w->flags() & Fl_Window::FL_FORCE_POSITION)) { + xp = yp = CW_USEDEFAULT; + } else { + if (!Fl::grab()) { + xp = xwm; yp = ywm; + w->x(xp);w->y(yp); + } + xp -= bx; + yp -= by+bt; + } + + parent = 0; + if (w->non_modal() && Fl_X::first && !fl_disable_transient_for) { + // find some other window to be "transient for": + Fl_Window* w = Fl_X::first->w; + while (w->parent()) w = w->window(); + parent = fl_xid(w); + if (!w->visible()) showit = 0; + } else if (Fl::grab()) parent = fl_xid(Fl::grab()); + } + + Fl_X* x = new Fl_X; + x->other_xid = 0; + x->setwindow(w); + x->region = 0; + x->private_dc = 0; + x->cursor = fl_default_cursor; + x->xid = CreateWindowEx( + styleEx, + class_name, w->label(), style, + xp, yp, wp, hp, + parent, + NULL, // menu + fl_display, + NULL // creation parameters + ); + x->next = Fl_X::first; + Fl_X::first = x; + + x->wait_for_expose = 1; + if (fl_show_iconic) {showit = 0; fl_show_iconic = 0;} + if (showit) { + w->set_visible(); + int old_event = Fl::e_number; + w->handle(Fl::e_number = FL_SHOW); // get child windows to appear + Fl::e_number = old_event; + w->redraw(); // force draw to happen + } + // If we've captured the mouse, we dont want to activate any + // other windows from the code, or we loose the capture. + ShowWindow(x->xid, !showit ? SW_SHOWMINNOACTIVE : + (Fl::grab() || (style & WS_POPUP)) ? SW_SHOWNOACTIVATE : SW_SHOWNORMAL); + + // Drag-n-drop requires GCC 3.x or a non-GNU compiler... +#if !defined(__GNUC__) || __GNUC__ >= 3 + // Register all windows for potential drag'n'drop operations + static char oleInitialized = 0; + if (!oleInitialized) { OleInitialize(0L); oleInitialized=1; } + + RegisterDragDrop(x->xid, flIDropTarget); +#endif // !__GNUC__ || __GNUC__ >= 3 + + if (w->modal()) {Fl::modal_ = w; fl_fix_focus();} + return x; +} + + + + +///////////////////////////////////////////////////////////////////////////// +/// Win32 timers +/// + + +static LRESULT CALLBACK s_TimerProc(HWND hwnd, UINT msg, + WPARAM wParam, LPARAM lParam) +{ + switch (msg) { + case WM_TIMER: + { + unsigned int id = wParam - 1; + if (id < (unsigned int)win32_timer_used && win32_timers[id].handle) { + Fl_Timeout_Handler cb = win32_timers[id].callback; + void* data = win32_timers[id].data; + delete_timer(win32_timers[id]); + if (cb) { + (*cb)(data); + } + } + } + return 0; + + default: + break; + } + + return DefWindowProc(hwnd, msg, wParam, lParam); +} + +void Fl::add_timeout(double time, Fl_Timeout_Handler cb, void* data) +{ + repeat_timeout(time, cb, data); +} + +void Fl::repeat_timeout(double time, Fl_Timeout_Handler cb, void* data) +{ + int timer_id = -1; + for (int i = 0; i < win32_timer_used; ++i) { + if ( !win32_timers[i].handle ) { + timer_id = i; + break; + } + } + if (timer_id == -1) { + if (win32_timer_used == win32_timer_alloc) { + realloc_timers(); + } + timer_id = win32_timer_used++; + } + unsigned int elapsed = (unsigned int)(time * 1000); + + if ( !s_TimerWnd ) { + const char* timer_class = "FLTimer"; + WNDCLASSEX wc; + memset(&wc, 0, sizeof(wc)); + wc.cbSize = sizeof (wc); + wc.style = CS_CLASSDC; + wc.lpfnWndProc = (WNDPROC)s_TimerProc; + wc.hInstance = fl_display; + wc.lpszClassName = timer_class; + /*ATOM atom =*/ RegisterClassEx(&wc); + // create a zero size window to handle timer events + s_TimerWnd = CreateWindowEx(WS_EX_LEFT | WS_EX_TOOLWINDOW, + timer_class, "", + WS_POPUP, + 0, 0, 0, 0, + NULL, NULL, fl_display, NULL); + // just in case this OS won't let us create a 0x0 size window: + if (!s_TimerWnd) + s_TimerWnd = CreateWindowEx(WS_EX_LEFT | WS_EX_TOOLWINDOW, + timer_class, "", + WS_POPUP, + 0, 0, 1, 1, + NULL, NULL, fl_display, NULL); + ShowWindow(s_TimerWnd, SW_SHOWNOACTIVATE); + } + + win32_timers[timer_id].callback = cb; + win32_timers[timer_id].data = data; + + win32_timers[timer_id].handle = + SetTimer(s_TimerWnd, timer_id + 1, elapsed, NULL); +} + +int Fl::has_timeout(Fl_Timeout_Handler cb, void* data) +{ + for (int i = 0; i < win32_timer_used; ++i) { + Win32Timer& t = win32_timers[i]; + if (t.handle && t.callback == cb && t.data == data) { + return 1; + } + } + return 0; +} + +void Fl::remove_timeout(Fl_Timeout_Handler cb, void* data) +{ + int i; + for (i = 0; i < win32_timer_used; ++i) { + Win32Timer& t = win32_timers[i]; + if (t.handle && t.callback == cb && + (t.data == data || data == NULL)) { + delete_timer(t); + } + } +} + +/// END TIMERS +///////////////////////////////////////////////////////////////////////////// + + + +//////////////////////////////////////////////////////////////// + +HINSTANCE fl_display = GetModuleHandle(NULL); + +void Fl_Window::size_range_() { + size_range_set = 1; +} + +void Fl_X::set_minmax(LPMINMAXINFO minmax) +{ + int td, wd, hd, dummy_x, dummy_y; + + fake_X_wm(w, dummy_x, dummy_y, td, wd, hd); + wd *= 2; + hd *= 2; + hd += td; + + minmax->ptMinTrackSize.x = w->minw + wd; + minmax->ptMinTrackSize.y = w->minh + hd; + if (w->maxw) { + minmax->ptMaxTrackSize.x = w->maxw + wd; + minmax->ptMaxSize.x = w->maxw + wd; + } + if (w->maxh) { + minmax->ptMaxTrackSize.y = w->maxh + hd; + minmax->ptMaxSize.y = w->maxh + hd; + } +} + +//////////////////////////////////////////////////////////////// + +#include // need so FL_EXPORT fl_filename_name works + +// returns pointer to the filename, or null if name ends with '/' +const char *fl_filename_name(const char *name) { + const char *p,*q; + if (!name) return (0); + q = name; + if (q[0] && q[1]==':') q += 2; // skip leading drive letter + for (p = q; *p; p++) if (*p == '/' || *p == '\\') q = p+1; + return q; +} + +void Fl_Window::label(const char *name,const char *iname) { + Fl_Widget::label(name); + iconlabel_ = iname; + if (shown() && !parent()) { + if (!name) name = ""; + SetWindowText(i->xid, name); + // if (!iname) iname = fl_filename_name(name); + // should do something with iname here... + } +} + +//////////////////////////////////////////////////////////////// +// Implement the virtual functions for the base Fl_Window class: + +// If the box is a filled rectangle, we can make the redisplay *look* +// faster by using X's background pixel erasing. We can make it +// actually *be* faster by drawing the frame only, this is done by +// setting fl_boxcheat, which is seen by code in fl_drawbox.cxx: +// For WIN32 it looks like all windows share a background color, so +// I use FL_GRAY for this and only do this cheat for windows that are +// that color. +// Actually it is totally disabled. +// Fl_Widget *fl_boxcheat; +//static inline int can_boxcheat(uchar b) {return (b==1 || (b&2) && b<=15);} + +void Fl_Window::show() { + image(Fl::scheme_bg_); + if (Fl::scheme_bg_) { + labeltype(FL_NORMAL_LABEL); + align(FL_ALIGN_CENTER | FL_ALIGN_INSIDE | FL_ALIGN_CLIP); + } else { + labeltype(FL_NO_LABEL); + } + Fl_Tooltip::exit(this); + if (!shown()) { + // if (can_boxcheat(box())) fl_background_pixel = fl_xpixel(color()); + Fl_X::make(this); + } else { + // Once again, we would lose the capture if we activated the window. + if (IsIconic(i->xid)) OpenIcon(i->xid); + if (!fl_capture) BringWindowToTop(i->xid); + //ShowWindow(i->xid,fl_capture?SW_SHOWNOACTIVATE:SW_RESTORE); + } +} + +Fl_Window *Fl_Window::current_; +// the current context +HDC fl_gc = 0; +// the current window handle, initially set to -1 so we can correctly +// allocate fl_GetDC(0) +HWND fl_window = NULL; + +// Here we ensure only one GetDC is ever in place. +HDC fl_GetDC(HWND w) { + if (fl_gc) { + if (w == fl_window && fl_window != NULL) return fl_gc; + if (fl_window) fl_release_dc(fl_window, fl_gc); // ReleaseDC + } + fl_gc = GetDC(w); + fl_save_dc(w, fl_gc); + fl_window = w; + // calling GetDC seems to always reset these: (?) + SetTextAlign(fl_gc, TA_BASELINE|TA_LEFT); + SetBkMode(fl_gc, TRANSPARENT); + return fl_gc; +} + +// make X drawing go into this window (called by subclass flush() impl.) +void Fl_Window::make_current() { + fl_GetDC(fl_xid(this)); + +#if USE_COLORMAP + // Windows maintains a hardware and software color palette; the + // SelectPalette() call updates the current soft->hard mapping + // for all drawing calls, so we must select it here before any + // code does any drawing... + + fl_select_palette(); +#endif // USE_COLORMAP + + current_ = this; + fl_clip_region(0); +} + +/* Make sure that all allocated fonts are released. This works only if + Fl::run() is allowed to exit by closing all windows. Calling 'exit(int)' + will not automatically free any fonts. */ +void fl_free_fonts(void) +{ +// remove the Fl_FontSize chains + int i; + Fl_Fontdesc * s; + Fl_FontSize * f; + Fl_FontSize * ff; + for (i=0; ifirst; f; f=ff) { + ff = f->next; + delete f; + s->first = ff; + } + } +} + + +/////////////////////////////////////////////////////////////////////// +// +// The following routines help fix a problem with the leaking of Windows +// Device Context (DC) objects. The 'proper' protocol is for a program to +// acquire a DC, save its state, do the modifications needed for drawing, +// perform the drawing, restore the initial state, and release the DC. In +// FLTK, the save and restore steps have previously been omitted and DCs are +// not properly released, leading to a great number of DC leaks. As some +// Windows "OSs" will hang when any process exceeds roughly 10,000 GDI objects, +// it is important to control GDI leaks, which are much more important than memory +// leaks. The following struct, global variable, and routines help implement +// the above protocol for those cases where the GetDC and RestoreDC are not in +// the same routine. For each GetDC, fl_save_dc is used to create an entry in +// a linked list that saves the window handle, the DC handle, and the initial +// state. When the DC is to be released, 'fl_release_dc' is called. It restores +// the initial state and releases the DC. When the program exits, 'fl_cleanup_dc_list' +// frees any remaining nodes in the list. + +struct Win_DC_List { // linked list + HWND window; // window handle + HDC dc; // device context handle + int saved_dc; // initial state of DC + Win_DC_List * next; // pointer to next item +}; + +static Win_DC_List * win_DC_list = 0; + +void fl_save_dc( HWND w, HDC dc) { + Win_DC_List * t; + t = new Win_DC_List; + t->window = w; + t->dc = dc; + t->saved_dc = SaveDC(dc); + if (win_DC_list) + t->next = win_DC_list; + else + t->next = NULL; + win_DC_list = t; +} + +void fl_release_dc(HWND w, HDC dc) { + Win_DC_List * t= win_DC_list; + Win_DC_List * prev = 0; + if (!t) + return; + do { + if (t->dc == dc) { + RestoreDC(dc, t->saved_dc); + ReleaseDC(w, dc); + if (!prev) { + win_DC_list = t->next; // delete first item + } else { + prev->next = t->next; // one in the middle + } + delete (t); + return; + } + prev = t; + t = t->next; + } while (t); +} + +void fl_cleanup_dc_list(void) { // clean up the list + Win_DC_List * t = win_DC_list; + if (!t)return; + do { + RestoreDC(t->dc, t->saved_dc); + ReleaseDC(t->window, t->dc); + win_DC_list = t->next; + delete (t); + t = win_DC_list; + } while(t); +} + + +// +// End of "$Id: Fl_win32.cxx 6017 2008-01-10 21:53:34Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/Fl_x.cxx b/plugins/zynaddsubfx/fltk/src/Fl_x.cxx new file mode 100644 index 000000000..a1fff05a5 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/Fl_x.cxx @@ -0,0 +1,1413 @@ +// +// "$Id: Fl_x.cxx 5914 2007-06-18 13:08:57Z matt $" +// +// X specific code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2007 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifdef WIN32 +//# include "Fl_win32.cxx" +#elif defined(__APPLE__) +//# include "Fl_mac.cxx" +#else + +# define CONSOLIDATE_MOTION 1 +/**** Define this if your keyboard lacks a backspace key... ****/ +/* #define BACKSPACE_HACK 1 */ + +# include +# include +# include +# include +# include +# include +# include "flstring.h" +# include +# include + +//////////////////////////////////////////////////////////////// +// interface to poll/select call: + +# if USE_POLL + +# include +static pollfd *pollfds = 0; + +# else +# if HAVE_SYS_SELECT_H +# include +# endif /* HAVE_SYS_SELECT_H */ + +// The following #define is only needed for HP-UX 9.x and earlier: +//#define select(a,b,c,d,e) select((a),(int *)(b),(int *)(c),(int *)(d),(e)) + +static fd_set fdsets[3]; +static int maxfd; +# define POLLIN 1 +# define POLLOUT 4 +# define POLLERR 8 + +# endif /* USE_POLL */ + +static int nfds = 0; +static int fd_array_size = 0; +struct FD { +# if !USE_POLL + int fd; + short events; +# endif + void (*cb)(int, void*); + void* arg; +}; + +static FD *fd = 0; + +void Fl::add_fd(int n, int events, void (*cb)(int, void*), void *v) { + remove_fd(n,events); + int i = nfds++; + if (i >= fd_array_size) { + FD *temp; + fd_array_size = 2*fd_array_size+1; + + if (!fd) temp = (FD*)malloc(fd_array_size*sizeof(FD)); + else temp = (FD*)realloc(fd, fd_array_size*sizeof(FD)); + + if (!temp) return; + fd = temp; + +# if USE_POLL + pollfd *tpoll; + + if (!pollfds) tpoll = (pollfd*)malloc(fd_array_size*sizeof(pollfd)); + else tpoll = (pollfd*)realloc(pollfds, fd_array_size*sizeof(pollfd)); + + if (!tpoll) return; + pollfds = tpoll; +# endif + } + fd[i].cb = cb; + fd[i].arg = v; +# if USE_POLL + pollfds[i].fd = n; + pollfds[i].events = events; +# else + fd[i].fd = n; + fd[i].events = events; + if (events & POLLIN) FD_SET(n, &fdsets[0]); + if (events & POLLOUT) FD_SET(n, &fdsets[1]); + if (events & POLLERR) FD_SET(n, &fdsets[2]); + if (n > maxfd) maxfd = n; +# endif +} + +void Fl::add_fd(int n, void (*cb)(int, void*), void* v) { + Fl::add_fd(n, POLLIN, cb, v); +} + +void Fl::remove_fd(int n, int events) { + int i,j; + maxfd = -1; // recalculate maxfd on the fly + for (i=j=0; i maxfd) maxfd = fd[i].fd; + // move it down in the array if necessary: + if (j0 if any callbacks were done. +int fl_wait(double time_to_wait) { + + // OpenGL and other broken libraries call XEventsQueued + // unnecessarily and thus cause the file descriptor to not be ready, + // so we must check for already-read events: + if (fl_display && XQLength(fl_display)) {do_queued_events(); return 1;} + +# if !USE_POLL + fd_set fdt[3]; + fdt[0] = fdsets[0]; + fdt[1] = fdsets[1]; + fdt[2] = fdsets[2]; +# endif + int n; + + fl_unlock_function(); + + if (time_to_wait < 2147483.648) { +# if USE_POLL + n = ::poll(pollfds, nfds, int(time_to_wait*1000 + .5)); +# else + timeval t; + t.tv_sec = int(time_to_wait); + t.tv_usec = int(1000000 * (time_to_wait-t.tv_sec)); + n = ::select(maxfd+1,&fdt[0],&fdt[1],&fdt[2],&t); +# endif + } else { +# if USE_POLL + n = ::poll(pollfds, nfds, -1); +# else + n = ::select(maxfd+1,&fdt[0],&fdt[1],&fdt[2],0); +# endif + } + + fl_lock_function(); + + if (n > 0) { + for (int i=0; irequest_code); + XGetErrorDatabaseText(d,"",buf1,buf1,buf2,128); + XGetErrorText(d, e->error_code, buf1, 128); + Fl::warning("%s: %s 0x%lx", buf2, buf1, e->resourceid); + return 0; + } +} + +void fl_open_display() { + if (fl_display) return; + + XSetIOErrorHandler(io_error_handler); + XSetErrorHandler(xerror_handler); + + Display *d = XOpenDisplay(0); + if (!d) Fl::fatal("Can't open display: %s",XDisplayName(0)); + + fl_open_display(d); +} + +void fl_open_display(Display* d) { + fl_display = d; + + WM_DELETE_WINDOW = XInternAtom(d, "WM_DELETE_WINDOW", 0); + WM_PROTOCOLS = XInternAtom(d, "WM_PROTOCOLS", 0); + fl_MOTIF_WM_HINTS = XInternAtom(d, "_MOTIF_WM_HINTS", 0); + TARGETS = XInternAtom(d, "TARGETS", 0); + CLIPBOARD = XInternAtom(d, "CLIPBOARD", 0); + fl_XdndAware = XInternAtom(d, "XdndAware", 0); + fl_XdndSelection = XInternAtom(d, "XdndSelection", 0); + fl_XdndEnter = XInternAtom(d, "XdndEnter", 0); + fl_XdndTypeList = XInternAtom(d, "XdndTypeList", 0); + fl_XdndPosition = XInternAtom(d, "XdndPosition", 0); + fl_XdndLeave = XInternAtom(d, "XdndLeave", 0); + fl_XdndDrop = XInternAtom(d, "XdndDrop", 0); + fl_XdndStatus = XInternAtom(d, "XdndStatus", 0); + fl_XdndActionCopy = XInternAtom(d, "XdndActionCopy", 0); + fl_XdndFinished = XInternAtom(d, "XdndFinished", 0); + //fl_XdndProxy = XInternAtom(d, "XdndProxy", 0); + fl_XdndEnter = XInternAtom(d, "XdndEnter", 0); + fl_XdndURIList = XInternAtom(d, "text/uri-list", 0); + + Fl::add_fd(ConnectionNumber(d), POLLIN, fd_callback); + + fl_screen = DefaultScreen(d); + + fl_message_window = + XCreateSimpleWindow(d, RootWindow(d,fl_screen), 0,0,1,1,0, 0, 0); + +// construct an XVisualInfo that matches the default Visual: + XVisualInfo templt; int num; + templt.visualid = XVisualIDFromVisual(DefaultVisual(d, fl_screen)); + fl_visual = XGetVisualInfo(d, VisualIDMask, &templt, &num); + fl_colormap = DefaultColormap(d, fl_screen); + +#if !USE_COLORMAP + Fl::visual(FL_RGB); +#endif +} + +void fl_close_display() { + Fl::remove_fd(ConnectionNumber(fl_display)); + XCloseDisplay(fl_display); +} + +static int fl_workarea_xywh[4] = { -1, -1, -1, -1 }; + +static void fl_init_workarea() { + fl_open_display(); + + Atom _NET_WORKAREA = XInternAtom(fl_display, "_NET_WORKAREA", 0); + Atom actual; + unsigned long count, remaining; + int format; + unsigned *xywh; + + if (XGetWindowProperty(fl_display, RootWindow(fl_display, fl_screen), + _NET_WORKAREA, 0, 4 * sizeof(unsigned), False, + XA_CARDINAL, &actual, &format, &count, &remaining, + (unsigned char **)&xywh) || !xywh || !xywh[2] || + !xywh[3]) + { + fl_workarea_xywh[0] = 0; + fl_workarea_xywh[1] = 0; + fl_workarea_xywh[2] = DisplayWidth(fl_display, fl_screen); + fl_workarea_xywh[3] = DisplayHeight(fl_display, fl_screen); + } + else + { + fl_workarea_xywh[0] = (int)xywh[0]; + fl_workarea_xywh[1] = (int)xywh[1]; + fl_workarea_xywh[2] = (int)xywh[2]; + fl_workarea_xywh[3] = (int)xywh[3]; + XFree(xywh); + } +} + +int Fl::x() { + if (fl_workarea_xywh[0] < 0) fl_init_workarea(); + return fl_workarea_xywh[0]; +} + +int Fl::y() { + if (fl_workarea_xywh[0] < 0) fl_init_workarea(); + return fl_workarea_xywh[1]; +} + +int Fl::w() { + if (fl_workarea_xywh[0] < 0) fl_init_workarea(); + return fl_workarea_xywh[2]; +} + +int Fl::h() { + if (fl_workarea_xywh[0] < 0) fl_init_workarea(); + return fl_workarea_xywh[3]; +} + +void Fl::get_mouse(int &xx, int &yy) { + fl_open_display(); + Window root = RootWindow(fl_display, fl_screen); + Window c; int mx,my,cx,cy; unsigned int mask; + XQueryPointer(fl_display,root,&root,&c,&mx,&my,&cx,&cy,&mask); + xx = mx; + yy = my; +} + +//////////////////////////////////////////////////////////////// +// Code used for paste and DnD into the program: + +Fl_Widget *fl_selection_requestor; +char *fl_selection_buffer[2]; +int fl_selection_length[2]; +int fl_selection_buffer_length[2]; +char fl_i_own_selection[2]; + +// Call this when a "paste" operation happens: +void Fl::paste(Fl_Widget &receiver, int clipboard) { + if (fl_i_own_selection[clipboard]) { + // We already have it, do it quickly without window server. + // Notice that the text is clobbered if set_selection is + // called in response to FL_PASTE! + Fl::e_text = fl_selection_buffer[clipboard]; + Fl::e_length = fl_selection_length[clipboard]; + if (!Fl::e_text) Fl::e_text = (char *)""; + receiver.handle(FL_PASTE); + return; + } + // otherwise get the window server to return it: + fl_selection_requestor = &receiver; + Atom property = clipboard ? CLIPBOARD : XA_PRIMARY; + XConvertSelection(fl_display, property, XA_STRING, property, + fl_xid(Fl::first_window()), fl_event_time); +} + +Window fl_dnd_source_window; +Atom *fl_dnd_source_types; // null-terminated list of data types being supplied +Atom fl_dnd_type; +Atom fl_dnd_source_action; +Atom fl_dnd_action; + +void fl_sendClientMessage(Window window, Atom message, + unsigned long d0, + unsigned long d1=0, + unsigned long d2=0, + unsigned long d3=0, + unsigned long d4=0) +{ + XEvent e; + e.xany.type = ClientMessage; + e.xany.window = window; + e.xclient.message_type = message; + e.xclient.format = 32; + e.xclient.data.l[0] = (long)d0; + e.xclient.data.l[1] = (long)d1; + e.xclient.data.l[2] = (long)d2; + e.xclient.data.l[3] = (long)d3; + e.xclient.data.l[4] = (long)d4; + XSendEvent(fl_display, window, 0, 0, &e); +} + +//////////////////////////////////////////////////////////////// +// Code for copying to clipboard and DnD out of the program: + +void Fl::copy(const char *stuff, int len, int clipboard) { + if (!stuff || len<0) return; + if (len+1 > fl_selection_buffer_length[clipboard]) { + delete[] fl_selection_buffer[clipboard]; + fl_selection_buffer[clipboard] = new char[len+100]; + fl_selection_buffer_length[clipboard] = len+100; + } + memcpy(fl_selection_buffer[clipboard], stuff, len); + fl_selection_buffer[clipboard][len] = 0; // needed for direct paste + fl_selection_length[clipboard] = len; + fl_i_own_selection[clipboard] = 1; + Atom property = clipboard ? CLIPBOARD : XA_PRIMARY; + XSetSelectionOwner(fl_display, property, fl_message_window, fl_event_time); +} + +//////////////////////////////////////////////////////////////// + +const XEvent* fl_xevent; // the current x event +ulong fl_event_time; // the last timestamp from an x event + +char fl_key_vector[32]; // used by Fl::get_key() + +// Record event mouse position and state from an XEvent: + +static int px, py; +static ulong ptime; + +static void set_event_xy() { +# if CONSOLIDATE_MOTION + send_motion = 0; +# endif + Fl::e_x_root = fl_xevent->xbutton.x_root; + Fl::e_x = fl_xevent->xbutton.x; + Fl::e_y_root = fl_xevent->xbutton.y_root; + Fl::e_y = fl_xevent->xbutton.y; + Fl::e_state = fl_xevent->xbutton.state << 16; + fl_event_time = fl_xevent->xbutton.time; +# ifdef __sgi + // get the meta key off PC keyboards: + if (fl_key_vector[18]&0x18) Fl::e_state |= FL_META; +# endif + // turn off is_click if enough time or mouse movement has passed: + if (abs(Fl::e_x_root-px)+abs(Fl::e_y_root-py) > 3 || + fl_event_time >= ptime+1000) + Fl::e_is_click = 0; +} + +// if this is same event as last && is_click, increment click count: +static inline void checkdouble() { + if (Fl::e_is_click == Fl::e_keysym) + Fl::e_clicks++; + else { + Fl::e_clicks = 0; + Fl::e_is_click = Fl::e_keysym; + } + px = Fl::e_x_root; + py = Fl::e_y_root; + ptime = fl_event_time; +} + +static Fl_Window* resize_bug_fix; + +extern "C" { + static Bool fake_keyup_test(Display*, XEvent* event, char* previous) { + return + event->type == KeyPress && + event->xkey.keycode == ((XKeyEvent*)previous)->keycode && + event->xkey.time == ((XKeyEvent*)previous)->time; + } +} + +//////////////////////////////////////////////////////////////// + +static char unknown[] = ""; +const int unknown_len = 10; + +int fl_handle(const XEvent& thisevent) +{ + XEvent xevent = thisevent; + fl_xevent = &thisevent; + Window xid = xevent.xany.window; + + switch (xevent.type) { + + case KeymapNotify: + memcpy(fl_key_vector, xevent.xkeymap.key_vector, 32); + return 0; + + case MappingNotify: + XRefreshKeyboardMapping((XMappingEvent*)&xevent.xmapping); + return 0; + + case SelectionNotify: { + if (!fl_selection_requestor) return 0; + static unsigned char* buffer; + if (buffer) {XFree(buffer); buffer = 0;} + long bytesread = 0; + if (fl_xevent->xselection.property) for (;;) { + // The Xdnd code pastes 64K chunks together, possibly to avoid + // bugs in X servers, or maybe to avoid an extra round-trip to + // get the property length. I copy this here: + Atom actual; int format; unsigned long count, remaining; + unsigned char* portion; + if (XGetWindowProperty(fl_display, + fl_xevent->xselection.requestor, + fl_xevent->xselection.property, + bytesread/4, 65536, 1, 0, + &actual, &format, &count, &remaining, + &portion)) break; // quit on error + if (bytesread) { // append to the accumulated buffer + buffer = (unsigned char*)realloc(buffer, bytesread+count*format/8+remaining); + memcpy(buffer+bytesread, portion, count*format/8); + XFree(portion); + } else { // Use the first section without moving the memory: + buffer = portion; + } + bytesread += count*format/8; + if (!remaining) break; + } + Fl::e_text = buffer ? (char*)buffer : (char *)""; + Fl::e_length = bytesread; + int old_event = Fl::e_number; + fl_selection_requestor->handle(Fl::e_number = FL_PASTE); + Fl::e_number = old_event; + // Detect if this paste is due to Xdnd by the property name (I use + // XA_SECONDARY for that) and send an XdndFinished message. It is not + // clear if this has to be delayed until now or if it can be done + // immediatly after calling XConvertSelection. + if (fl_xevent->xselection.property == XA_SECONDARY && + fl_dnd_source_window) { + fl_sendClientMessage(fl_dnd_source_window, fl_XdndFinished, + fl_xevent->xselection.requestor); + fl_dnd_source_window = 0; // don't send a second time + } + return 1;} + + case SelectionClear: { + int clipboard = fl_xevent->xselectionclear.selection == CLIPBOARD; + fl_i_own_selection[clipboard] = 0; + return 1;} + + case SelectionRequest: { + XSelectionEvent e; + e.type = SelectionNotify; + e.requestor = fl_xevent->xselectionrequest.requestor; + e.selection = fl_xevent->xselectionrequest.selection; + int clipboard = e.selection == CLIPBOARD; + e.target = fl_xevent->xselectionrequest.target; + e.time = fl_xevent->xselectionrequest.time; + e.property = fl_xevent->xselectionrequest.property; + if (e.target == TARGETS) { + Atom a = XA_STRING; + XChangeProperty(fl_display, e.requestor, e.property, + XA_ATOM, sizeof(Atom)*8, 0, (unsigned char*)&a, 1); + } else if (/*e.target == XA_STRING &&*/ fl_selection_length[clipboard]) { + XChangeProperty(fl_display, e.requestor, e.property, + e.target, 8, 0, + (unsigned char *)fl_selection_buffer[clipboard], + fl_selection_length[clipboard]); + } else { +// char* x = XGetAtomName(fl_display,e.target); +// fprintf(stderr,"selection request of %s\n",x); +// XFree(x); + e.property = 0; + } + XSendEvent(fl_display, e.requestor, 0, 0, (XEvent *)&e);} + return 1; + + // events where interesting window id is in a different place: + case CirculateNotify: + case CirculateRequest: + case ConfigureNotify: + case ConfigureRequest: + case CreateNotify: + case DestroyNotify: + case GravityNotify: + case MapNotify: + case MapRequest: + case ReparentNotify: + case UnmapNotify: + xid = xevent.xmaprequest.window; + break; + } + + int event = 0; + Fl_Window* window = fl_find(xid); + + if (window) switch (xevent.type) { + + case ClientMessage: { + Atom message = fl_xevent->xclient.message_type; + const long* data = fl_xevent->xclient.data.l; + if ((Atom)(data[0]) == WM_DELETE_WINDOW) { + event = FL_CLOSE; + } else if (message == fl_XdndEnter) { + fl_xmousewin = window; + in_a_window = true; + fl_dnd_source_window = data[0]; + // version number is data[1]>>24 +// printf("XdndEnter, version %ld\n", data[1] >> 24); + if (data[1]&1) { + // get list of data types: + Atom actual; int format; unsigned long count, remaining; + unsigned char *buffer = 0; + XGetWindowProperty(fl_display, fl_dnd_source_window, fl_XdndTypeList, + 0, 0x8000000L, False, XA_ATOM, &actual, &format, + &count, &remaining, &buffer); + if (actual != XA_ATOM || format != 32 || count<4 || !buffer) + goto FAILED; + delete [] fl_dnd_source_types; + fl_dnd_source_types = new Atom[count+1]; + for (unsigned i = 0; i < count; i++) + fl_dnd_source_types[i] = ((Atom*)buffer)[i]; + fl_dnd_source_types[count] = 0; + } else { + FAILED: + // less than four data types, or if the above messes up: + if (!fl_dnd_source_types) fl_dnd_source_types = new Atom[4]; + fl_dnd_source_types[0] = data[2]; + fl_dnd_source_types[1] = data[3]; + fl_dnd_source_types[2] = data[4]; + fl_dnd_source_types[3] = 0; + } + + // Loop through the source types and pick the first text type... + int i; + + for (i = 0; fl_dnd_source_types[i]; i ++) + { +// printf("fl_dnd_source_types[%d] = %ld (%s)\n", i, +// fl_dnd_source_types[i], +// XGetAtomName(fl_display, fl_dnd_source_types[i])); + + if (!strncmp(XGetAtomName(fl_display, fl_dnd_source_types[i]), + "text/", 5)) + break; + } + + if (fl_dnd_source_types[i]) + fl_dnd_type = fl_dnd_source_types[i]; + else + fl_dnd_type = fl_dnd_source_types[0]; + + event = FL_DND_ENTER; + Fl::e_text = unknown; + Fl::e_length = unknown_len; + break; + + } else if (message == fl_XdndPosition) { + fl_xmousewin = window; + in_a_window = true; + fl_dnd_source_window = data[0]; + Fl::e_x_root = data[2]>>16; + Fl::e_y_root = data[2]&0xFFFF; + if (window) { + Fl::e_x = Fl::e_x_root-window->x(); + Fl::e_y = Fl::e_y_root-window->y(); + } + fl_event_time = data[3]; + fl_dnd_source_action = data[4]; + fl_dnd_action = fl_XdndActionCopy; + Fl::e_text = unknown; + Fl::e_length = unknown_len; + int accept = Fl::handle(FL_DND_DRAG, window); + fl_sendClientMessage(data[0], fl_XdndStatus, + fl_xevent->xclient.window, + accept ? 1 : 0, + 0, // used for xy rectangle to not send position inside + 0, // used for width+height of rectangle + accept ? fl_dnd_action : None); + return 1; + + } else if (message == fl_XdndLeave) { + fl_dnd_source_window = 0; // don't send a finished message to it + event = FL_DND_LEAVE; + Fl::e_text = unknown; + Fl::e_length = unknown_len; + break; + + } else if (message == fl_XdndDrop) { + fl_xmousewin = window; + in_a_window = true; + fl_dnd_source_window = data[0]; + fl_event_time = data[2]; + Window to_window = fl_xevent->xclient.window; + Fl::e_text = unknown; + Fl::e_length = unknown_len; + if (Fl::handle(FL_DND_RELEASE, window)) { + fl_selection_requestor = Fl::belowmouse(); + XConvertSelection(fl_display, fl_XdndSelection, + fl_dnd_type, XA_SECONDARY, + to_window, fl_event_time); + } else { + // Send the finished message if I refuse the drop. + // It is not clear whether I can just send finished always, + // or if I have to wait for the SelectionNotify event as the + // code is currently doing. + fl_sendClientMessage(fl_dnd_source_window, fl_XdndFinished, to_window); + fl_dnd_source_window = 0; + } + return 1; + + } + break;} + + case UnmapNotify: + event = FL_HIDE; + break; + + case Expose: + Fl_X::i(window)->wait_for_expose = 0; +# if 0 + // try to keep windows on top even if WM_TRANSIENT_FOR does not work: + // opaque move/resize window managers do not like this, so I disabled it. + if (Fl::first_window()->non_modal() && window != Fl::first_window()) + Fl::first_window()->show(); +# endif + + case GraphicsExpose: + window->damage(FL_DAMAGE_EXPOSE, xevent.xexpose.x, xevent.xexpose.y, + xevent.xexpose.width, xevent.xexpose.height); + return 1; + + case FocusIn: + event = FL_FOCUS; + break; + + case FocusOut: + event = FL_UNFOCUS; + break; + + case KeyPress: + case KeyRelease: { + KEYPRESS: + int keycode = xevent.xkey.keycode; + fl_key_vector[keycode/8] |= (1 << (keycode%8)); + static char buffer[21]; + int len; + KeySym keysym; + if (xevent.type == KeyPress) { + event = FL_KEYDOWN; + //static XComposeStatus compose; + len = XLookupString((XKeyEvent*)&(xevent.xkey), + buffer, 20, &keysym, 0/*&compose*/); + if (keysym && keysym < 0x400) { // a character in latin-1,2,3,4 sets + // force it to type a character (not sure if this ever is needed): + if (!len) {buffer[0] = char(keysym); len = 1;} + // ignore all effects of shift on the keysyms, which makes it a lot + // easier to program shortcuts and is Windoze-compatable: + keysym = XKeycodeToKeysym(fl_display, keycode, 0); + } + // MRS: Can't use Fl::event_state(FL_CTRL) since the state is not + // set until set_event_xy() is called later... + if ((xevent.xkey.state & ControlMask) && keysym == '-') buffer[0] = 0x1f; // ^_ + buffer[len] = 0; + Fl::e_text = buffer; + Fl::e_length = len; + } else { + // Stupid X sends fake key-up events when a repeating key is held + // down, probably due to some back compatability problem. Fortunately + // we can detect this because the repeating KeyPress event is in + // the queue, get it and execute it instead: + XEvent temp; + if (XCheckIfEvent(fl_display,&temp,fake_keyup_test,(char*)(&xevent))){ + xevent = temp; + goto KEYPRESS; + } + event = FL_KEYUP; + fl_key_vector[keycode/8] &= ~(1 << (keycode%8)); + // keyup events just get the unshifted keysym: + keysym = XKeycodeToKeysym(fl_display, keycode, 0); + } +# ifdef __sgi + // You can plug a microsoft keyboard into an sgi but the extra shift + // keys are not translated. Make them translate like XFree86 does: + if (!keysym) switch(keycode) { + case 147: keysym = FL_Meta_L; break; + case 148: keysym = FL_Meta_R; break; + case 149: keysym = FL_Menu; break; + } +# endif +# if BACKSPACE_HACK + // Attempt to fix keyboards that send "delete" for the key in the + // upper-right corner of the main keyboard. But it appears that + // very few of these remain? + static int got_backspace; + if (!got_backspace) { + if (keysym == FL_Delete) keysym = FL_BackSpace; + else if (keysym == FL_BackSpace) got_backspace = 1; + } +# endif + // We have to get rid of the XK_KP_function keys, because they are + // not produced on Windoze and thus case statements tend not to check + // for them. There are 15 of these in the range 0xff91 ... 0xff9f + if (keysym >= 0xff91 && keysym <= 0xff9f) { + // Map keypad keysym to character or keysym depending on + // numlock state... + unsigned long keysym1 = XKeycodeToKeysym(fl_display, keycode, 1); + if (keysym1 <= 0x7f || (keysym1 > 0xff9f && keysym1 <= FL_KP_Last)) + Fl::e_original_keysym = (int)(keysym1 | FL_KP); + if ((xevent.xkey.state & Mod2Mask) && + (keysym1 <= 0x7f || (keysym1 > 0xff9f && keysym1 <= FL_KP_Last))) { + // Store ASCII numeric keypad value... + keysym = keysym1 | FL_KP; + buffer[0] = char(keysym1) & 0x7F; + len = 1; + } else { + // Map keypad to special key... + static const unsigned short table[15] = { + FL_F+1, FL_F+2, FL_F+3, FL_F+4, + FL_Home, FL_Left, FL_Up, FL_Right, + FL_Down, FL_Page_Up, FL_Page_Down, FL_End, + 0xff0b/*XK_Clear*/, FL_Insert, FL_Delete}; + keysym = table[keysym-0xff91]; + } + } else { + // Store this so we can later know if the KP was used + Fl::e_original_keysym = (int)keysym; + } + Fl::e_keysym = int(keysym); + set_event_xy(); + Fl::e_is_click = 0; + break;} + + case ButtonPress: + Fl::e_keysym = FL_Button + xevent.xbutton.button; + set_event_xy(); + if (xevent.xbutton.button == Button4) { + Fl::e_dy = -1; // Up + event = FL_MOUSEWHEEL; + } else if (xevent.xbutton.button == Button5) { + Fl::e_dy = +1; // Down + event = FL_MOUSEWHEEL; + } else { + Fl::e_state |= (FL_BUTTON1 << (xevent.xbutton.button-1)); + event = FL_PUSH; + checkdouble(); + } + + fl_xmousewin = window; + in_a_window = true; + break; + + case MotionNotify: + set_event_xy(); +# if CONSOLIDATE_MOTION + send_motion = fl_xmousewin = window; + in_a_window = true; + return 0; +# else + event = FL_MOVE; + fl_xmousewin = window; + in_a_window = true; + break; +# endif + + case ButtonRelease: + Fl::e_keysym = FL_Button + xevent.xbutton.button; + set_event_xy(); + Fl::e_state &= ~(FL_BUTTON1 << (xevent.xbutton.button-1)); + if (xevent.xbutton.button == Button4 || + xevent.xbutton.button == Button5) return 0; + event = FL_RELEASE; + + fl_xmousewin = window; + in_a_window = true; + break; + + case EnterNotify: + if (xevent.xcrossing.detail == NotifyInferior) break; + // XInstallColormap(fl_display, Fl_X::i(window)->colormap); + set_event_xy(); + Fl::e_state = xevent.xcrossing.state << 16; + event = FL_ENTER; + + fl_xmousewin = window; + in_a_window = true; + break; + + case LeaveNotify: + if (xevent.xcrossing.detail == NotifyInferior) break; + set_event_xy(); + Fl::e_state = xevent.xcrossing.state << 16; + fl_xmousewin = 0; + in_a_window = false; // make do_queued_events produce FL_LEAVE event + return 0; + + // We cannot rely on the x,y position in the configure notify event. + // I now think this is an unavoidable problem with X: it is impossible + // for a window manager to prevent the "real" notify event from being + // sent when it resizes the contents, even though it can send an + // artificial event with the correct position afterwards (and some + // window managers do not send this fake event anyway) + // So anyway, do a round trip to find the correct x,y: + case MapNotify: + event = FL_SHOW; + + case ConfigureNotify: { + if (window->parent()) break; // ignore child windows + + // figure out where OS really put window + XWindowAttributes actual; + XGetWindowAttributes(fl_display, fl_xid(window), &actual); + Window cr; int X, Y, W = actual.width, H = actual.height; + XTranslateCoordinates(fl_display, fl_xid(window), actual.root, + 0, 0, &X, &Y, &cr); + + // tell Fl_Window about it and set flag to prevent echoing: + resize_bug_fix = window; + window->resize(X, Y, W, H); + break; // allow add_handler to do something too + } + + case ReparentNotify: { + int xpos, ypos; + Window junk; + + //ReparentNotify gives the new position of the window relative to + //the new parent. FLTK cares about the position on the root window. + XTranslateCoordinates(fl_display, xevent.xreparent.parent, + XRootWindow(fl_display, fl_screen), + xevent.xreparent.x, xevent.xreparent.y, + &xpos, &ypos, &junk); + + // tell Fl_Window about it and set flag to prevent echoing: + resize_bug_fix = window; + window->position(xpos, ypos); + break; + } + } + + return Fl::handle(event, window); +} + +//////////////////////////////////////////////////////////////// + +void Fl_Window::resize(int X,int Y,int W,int H) { + int is_a_move = (X != x() || Y != y()); + int is_a_resize = (W != w() || H != h()); + int resize_from_program = (this != resize_bug_fix); + if (!resize_from_program) resize_bug_fix = 0; + if (is_a_move && resize_from_program) set_flag(FL_FORCE_POSITION); + else if (!is_a_resize && !is_a_move) return; + if (is_a_resize) { + Fl_Group::resize(X,Y,W,H); + if (shown()) {redraw(); i->wait_for_expose = 1;} + } else { + x(X); y(Y); + } + + if (resize_from_program && is_a_resize && !resizable()) { + size_range(w(), h(), w(), h()); + } + + if (resize_from_program && shown()) { + if (is_a_resize) { + if (!resizable()) size_range(w(),h(),w(),h()); + if (is_a_move) { + XMoveResizeWindow(fl_display, i->xid, X, Y, W>0 ? W : 1, H>0 ? H : 1); + } else { + XResizeWindow(fl_display, i->xid, W>0 ? W : 1, H>0 ? H : 1); + } + } else + XMoveWindow(fl_display, i->xid, X, Y); + } +} + +//////////////////////////////////////////////////////////////// + +// A subclass of Fl_Window may call this to associate an X window it +// creates with the Fl_Window: + +void fl_fix_focus(); // in Fl.cxx + +Fl_X* Fl_X::set_xid(Fl_Window* win, Window winxid) { + Fl_X* xp = new Fl_X; + xp->xid = winxid; + xp->other_xid = 0; + xp->setwindow(win); + xp->next = Fl_X::first; + xp->region = 0; + xp->wait_for_expose = 1; + xp->backbuffer_bad = 1; + Fl_X::first = xp; + if (win->modal()) {Fl::modal_ = win; fl_fix_focus();} + return xp; +} + +// More commonly a subclass calls this, because it hides the really +// ugly parts of X and sets all the stuff for a window that is set +// normally. The global variables like fl_show_iconic are so that +// subclasses of *that* class may change the behavior... + +char fl_show_iconic; // hack for iconize() +int fl_background_pixel = -1; // hack to speed up bg box drawing +int fl_disable_transient_for; // secret method of removing TRANSIENT_FOR + +static const int childEventMask = ExposureMask; + +static const int XEventMask = +ExposureMask|StructureNotifyMask +|KeyPressMask|KeyReleaseMask|KeymapStateMask|FocusChangeMask +|ButtonPressMask|ButtonReleaseMask +|EnterWindowMask|LeaveWindowMask +|PointerMotionMask; + +void Fl_X::make_xid(Fl_Window* win, XVisualInfo *visual, Colormap colormap) +{ + Fl_Group::current(0); // get rid of very common user bug: forgot end() + + int X = win->x(); + int Y = win->y(); + int W = win->w(); + if (W <= 0) W = 1; // X don't like zero... + int H = win->h(); + if (H <= 0) H = 1; // X don't like zero... + if (!win->parent() && !Fl::grab()) { + // center windows in case window manager does not do anything: +#ifdef FL_CENTER_WINDOWS + if (!(win->flags() & Fl_Window::FL_FORCE_POSITION)) { + win->x(X = scr_x+(scr_w-W)/2); + win->y(Y = scr_y+(scr_h-H)/2); + } +#endif // FL_CENTER_WINDOWS + + // force the window to be on-screen. Usually the X window manager + // does this, but a few don't, so we do it here for consistency: + int scr_x, scr_y, scr_w, scr_h; + Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h, X, Y); + + if (win->border()) { + // ensure border is on screen: + // (assumme extremely minimal dimensions for this border) + const int top = 20; + const int left = 1; + const int right = 1; + const int bottom = 1; + if (X+W+right > scr_x+scr_w) X = scr_x+scr_w-right-W; + if (X-left < scr_x) X = scr_x+left; + if (Y+H+bottom > scr_y+scr_h) Y = scr_y+scr_h-bottom-H; + if (Y-top < scr_y) Y = scr_y+top; + } + // now insure contents are on-screen (more important than border): + if (X+W > scr_x+scr_w) X = scr_x+scr_w-W; + if (X < scr_x) X = scr_x; + if (Y+H > scr_y+scr_h) Y = scr_y+scr_h-H; + if (Y < scr_y) Y = scr_y; + } + + // if the window is a subwindow and our parent is not mapped yet, we + // mark this window visible, so that mapping the parent at a later + // point in time will call this function again to finally map the subwindow. + if (win->parent() && !Fl_X::i(win->window())) { + win->set_visible(); + return; + } + + ulong root = win->parent() ? + fl_xid(win->window()) : RootWindow(fl_display, fl_screen); + + XSetWindowAttributes attr; + int mask = CWBorderPixel|CWColormap|CWEventMask|CWBitGravity; + attr.event_mask = win->parent() ? childEventMask : XEventMask; + attr.colormap = colormap; + attr.border_pixel = 0; + attr.bit_gravity = 0; // StaticGravity; + if (win->override()) { + attr.override_redirect = 1; + attr.save_under = 1; + mask |= CWOverrideRedirect | CWSaveUnder; + } else attr.override_redirect = 0; + if (Fl::grab()) { + attr.save_under = 1; mask |= CWSaveUnder; + if (!win->border()) {attr.override_redirect = 1; mask |= CWOverrideRedirect;} + } + if (fl_background_pixel >= 0) { + attr.background_pixel = fl_background_pixel; + fl_background_pixel = -1; + mask |= CWBackPixel; + } + + Fl_X* xp = + set_xid(win, XCreateWindow(fl_display, + root, + X, Y, W, H, + 0, // borderwidth + visual->depth, + InputOutput, + visual->visual, + mask, &attr)); + int showit = 1; + + if (!win->parent() && !attr.override_redirect) { + // Communicate all kinds 'o junk to the X Window Manager: + + win->label(win->label(), win->iconlabel()); + + XChangeProperty(fl_display, xp->xid, WM_PROTOCOLS, + XA_ATOM, 32, 0, (uchar*)&WM_DELETE_WINDOW, 1); + + // send size limits and border: + xp->sendxjunk(); + + // set the class property, which controls the icon used: + if (win->xclass()) { + char buffer[1024]; + char *p; const char *q; + // truncate on any punctuation, because they break XResource lookup: + for (p = buffer, q = win->xclass(); isalnum(*q)||(*q&128);) *p++ = *q++; + *p++ = 0; + // create the capitalized version: + q = buffer; + *p = toupper(*q++); if (*p++ == 'X') *p++ = toupper(*q++); + while ((*p++ = *q++)); + XChangeProperty(fl_display, xp->xid, XA_WM_CLASS, XA_STRING, 8, 0, + (unsigned char *)buffer, p-buffer-1); + } + + if (win->non_modal() && xp->next && !fl_disable_transient_for) { + // find some other window to be "transient for": + Fl_Window* wp = xp->next->w; + while (wp->parent()) wp = wp->window(); + XSetTransientForHint(fl_display, xp->xid, fl_xid(wp)); + if (!wp->visible()) showit = 0; // guess that wm will not show it + } + + // Make sure that borderless windows do not show in the task bar + if (!win->border()) { + Atom net_wm_state = XInternAtom (fl_display, "_NET_WM_STATE", 0); + Atom net_wm_state_skip_taskbar = XInternAtom (fl_display, "_NET_WM_STATE_SKIP_TASKBAR", 0); + XChangeProperty (fl_display, xp->xid, net_wm_state, XA_ATOM, 32, + PropModeAppend, (unsigned char*) &net_wm_state_skip_taskbar, 1); + } + + // Make it receptive to DnD: + long version = 4; + XChangeProperty(fl_display, xp->xid, fl_XdndAware, + XA_ATOM, sizeof(int)*8, 0, (unsigned char*)&version, 1); + + XWMHints *hints = XAllocWMHints(); + hints->input = True; + hints->flags = InputHint; + if (fl_show_iconic) { + hints->flags |= StateHint; + hints->initial_state = IconicState; + fl_show_iconic = 0; + showit = 0; + } + if (win->icon()) { + hints->icon_pixmap = (Pixmap)win->icon(); + hints->flags |= IconPixmapHint; + } + XSetWMHints(fl_display, xp->xid, hints); + XFree(hints); + } + + XMapWindow(fl_display, xp->xid); + if (showit) { + win->set_visible(); + int old_event = Fl::e_number; + win->handle(Fl::e_number = FL_SHOW); // get child windows to appear + Fl::e_number = old_event; + win->redraw(); + } +} + +//////////////////////////////////////////////////////////////// +// Send X window stuff that can be changed over time: + +void Fl_X::sendxjunk() { + if (w->parent() || w->override()) return; // it's not a window manager window! + + if (!w->size_range_set) { // default size_range based on resizable(): + if (w->resizable()) { + Fl_Widget *o = w->resizable(); + int minw = o->w(); if (minw > 100) minw = 100; + int minh = o->h(); if (minh > 100) minh = 100; + w->size_range(w->w() - o->w() + minw, w->h() - o->h() + minh, 0, 0); + } else { + w->size_range(w->w(), w->h(), w->w(), w->h()); + } + return; // because this recursively called here + } + + XSizeHints *hints = XAllocSizeHints(); + // memset(&hints, 0, sizeof(hints)); jreiser suggestion to fix purify? + hints->min_width = w->minw; + hints->min_height = w->minh; + hints->max_width = w->maxw; + hints->max_height = w->maxh; + hints->width_inc = w->dw; + hints->height_inc = w->dh; + hints->win_gravity = StaticGravity; + + // see the file /usr/include/X11/Xm/MwmUtil.h: + // fill all fields to avoid bugs in kwm and perhaps other window managers: + // 0, MWM_FUNC_ALL, MWM_DECOR_ALL + long prop[5] = {0, 1, 1, 0, 0}; + + if (hints->min_width != hints->max_width || + hints->min_height != hints->max_height) { // resizable + hints->flags = PMinSize|PWinGravity; + if (hints->max_width >= hints->min_width || + hints->max_height >= hints->min_height) { + hints->flags = PMinSize|PMaxSize|PWinGravity; + // unfortunately we can't set just one maximum size. Guess a + // value for the other one. Some window managers will make the + // window fit on screen when maximized, others will put it off screen: + if (hints->max_width < hints->min_width) hints->max_width = Fl::w(); + if (hints->max_height < hints->min_height) hints->max_height = Fl::h(); + } + if (hints->width_inc && hints->height_inc) hints->flags |= PResizeInc; + if (w->aspect) { + // stupid X! It could insist that the corner go on the + // straight line between min and max... + hints->min_aspect.x = hints->max_aspect.x = hints->min_width; + hints->min_aspect.y = hints->max_aspect.y = hints->min_height; + hints->flags |= PAspect; + } + } else { // not resizable: + hints->flags = PMinSize|PMaxSize|PWinGravity; + prop[0] = 1; // MWM_HINTS_FUNCTIONS + prop[1] = 1|2|16; // MWM_FUNC_ALL | MWM_FUNC_RESIZE | MWM_FUNC_MAXIMIZE + } + + if (w->flags() & Fl_Window::FL_FORCE_POSITION) { + hints->flags |= USPosition; + hints->x = w->x(); + hints->y = w->y(); + } + + if (!w->border()) { + prop[0] |= 2; // MWM_HINTS_DECORATIONS + prop[2] = 0; // no decorations + } + + XSetWMNormalHints(fl_display, xid, hints); + XChangeProperty(fl_display, xid, + fl_MOTIF_WM_HINTS, fl_MOTIF_WM_HINTS, + 32, 0, (unsigned char *)prop, 5); + XFree(hints); +} + +void Fl_Window::size_range_() { + size_range_set = 1; + if (shown()) i->sendxjunk(); +} + +//////////////////////////////////////////////////////////////// + +// returns pointer to the filename, or null if name ends with '/' +const char *fl_filename_name(const char *name) { + const char *p,*q; + if (!name) return (0); + for (p=q=name; *p;) if (*p++ == '/') q = p; + return q; +} + +void Fl_Window::label(const char *name,const char *iname) { + Fl_Widget::label(name); + iconlabel_ = iname; + if (shown() && !parent()) { + if (!name) name = ""; + XChangeProperty(fl_display, i->xid, XA_WM_NAME, + XA_STRING, 8, 0, (uchar*)name, strlen(name)); + if (!iname) iname = fl_filename_name(name); + XChangeProperty(fl_display, i->xid, XA_WM_ICON_NAME, + XA_STRING, 8, 0, (uchar*)iname, strlen(iname)); + } +} + +//////////////////////////////////////////////////////////////// +// Implement the virtual functions for the base Fl_Window class: + +// If the box is a filled rectangle, we can make the redisplay *look* +// faster by using X's background pixel erasing. We can make it +// actually *be* faster by drawing the frame only, this is done by +// setting fl_boxcheat, which is seen by code in fl_drawbox.cxx: +// +// On XFree86 (and prehaps all X's) this has a problem if the window +// is resized while a save-behind window is atop it. The previous +// contents are restored to the area, but this assummes the area +// is cleared to background color. So this is disabled in this version. +// Fl_Window *fl_boxcheat; +static inline int can_boxcheat(uchar b) {return (b==1 || (b&2) && b<=15);} + +void Fl_Window::show() { + image(Fl::scheme_bg_); + if (Fl::scheme_bg_) { + labeltype(FL_NORMAL_LABEL); + align(FL_ALIGN_CENTER | FL_ALIGN_INSIDE | FL_ALIGN_CLIP); + } else { + labeltype(FL_NO_LABEL); + } + Fl_Tooltip::exit(this); + if (!shown()) { + fl_open_display(); + // Don't set background pixel for double-buffered windows... + if (type() == FL_WINDOW && can_boxcheat(box())) { + fl_background_pixel = int(fl_xpixel(color())); + } + Fl_X::make_xid(this); + } else { + XMapRaised(fl_display, i->xid); + } +} + +Window fl_window; +Fl_Window *Fl_Window::current_; +GC fl_gc; + +// make X drawing go into this window (called by subclass flush() impl.) +void Fl_Window::make_current() { + static GC gc; // the GC used by all X windows + if (!gc) gc = XCreateGC(fl_display, i->xid, 0, 0); + fl_window = i->xid; + fl_gc = gc; + current_ = this; + fl_clip_region(0); +} + +#endif + +// +// End of "$Id: Fl_x.cxx 5914 2007-06-18 13:08:57Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fastarrow.h b/plugins/zynaddsubfx/fltk/src/fastarrow.h new file mode 100644 index 000000000..e381acdce --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fastarrow.h @@ -0,0 +1,6 @@ +#define fastarrow_width 16 +#define fastarrow_height 16 +static unsigned char fastarrow_bits[] = { + 0x00, 0x00, 0x00, 0x07, 0xe0, 0x07, 0xfc, 0x03, 0xff, 0xff, 0xfc, 0x03, + 0xe0, 0x07, 0x00, 0x07, 0xe0, 0x00, 0xe0, 0x07, 0xc0, 0x3f, 0xff, 0xff, + 0xc0, 0x3f, 0xe0, 0x07, 0xe0, 0x00, 0x00, 0x00}; diff --git a/plugins/zynaddsubfx/fltk/src/filename_absolute.cxx b/plugins/zynaddsubfx/fltk/src/filename_absolute.cxx new file mode 100644 index 000000000..13135a58b --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/filename_absolute.cxx @@ -0,0 +1,212 @@ +// +// "$Id: filename_absolute.cxx 6102 2008-04-21 19:54:34Z matt $" +// +// Filename expansion routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* expand a file name by prepending current directory, deleting . and + .. (not really correct for symbolic links) between the prepended + current directory. Use $PWD if it exists. + Returns true if any changes were made. +*/ + +#include +#include +#include "flstring.h" +#include +#if defined(WIN32) && !defined(__CYGWIN__) +# include +// Visual C++ 2005 incorrectly displays a warning about the use of POSIX APIs +// on Windows, which is supposed to be POSIX compliant... +# define getcwd _getcwd +#else +# include +# ifdef __EMX__ +# define getcwd _getcwd2 +# endif +#endif + +#if defined(WIN32) || defined(__EMX__) && !defined(__CYGWIN__) +inline int isdirsep(char c) {return c=='/' || c=='\\';} +#else +#define isdirsep(c) ((c)=='/') +#endif + +int fl_filename_absolute(char *to, int tolen, const char *from) { + if (isdirsep(*from) || *from == '|' +#if defined(WIN32) || defined(__EMX__) && !defined(__CYGWIN__) + || from[1]==':' +#endif + ) { + strlcpy(to, from, tolen); + return 0; + } + + char *a; + char *temp = new char[tolen]; + const char *start = from; + + a = getcwd(temp, tolen); + if (!a) { + strlcpy(to, from, tolen); + delete[] temp; + return 0; + } +#if defined(WIN32) || defined(__EMX__) && !defined(__CYGWIN__) + for (a = temp; *a; a++) if (*a=='\\') *a = '/'; // ha ha +#else + a = temp+strlen(temp); +#endif + if (isdirsep(*(a-1))) a--; + /* remove intermediate . and .. names: */ + while (*start == '.') { + if (start[1]=='.' && isdirsep(start[2])) { + char *b; + for (b = a-1; b >= temp && !isdirsep(*b); b--); + if (b < temp) break; + a = b; + start += 3; + } else if (isdirsep(start[1])) { + start += 2; + } else if (!start[1]) { + start ++; // Skip lone "." + break; + } else + break; + } + + *a++ = '/'; + strlcpy(a,start,tolen - (a - temp)); + + strlcpy(to, temp, tolen); + + delete[] temp; + + return 1; +} + +/* + * 'fl_filename_relative()' - Make a filename relative to the current working directory. + */ + +int // O - 0 if no change, 1 if changed +fl_filename_relative(char *to, // O - Relative filename + int tolen, // I - Size of "to" buffer + const char *from) {// I - Absolute filename + char *newslash; // Directory separator + const char *slash; // Directory separator + char cwd_buf[1024]; // Current directory + char *cwd = cwd_buf; + + + // return if "from" is not an absolue path +#if defined(WIN32) || defined(__EMX__) + if (from[0] == '\0' || + (!isdirsep(*from) && !isalpha(*from) && from[1] != ':' && + !isdirsep(from[2]))) { +#else + if (from[0] == '\0' || !isdirsep(*from)) { +#endif // WIN32 || __EMX__ + strlcpy(to, from, tolen); + return 0; + } + + // get the current directory and return if we can't + if (!getcwd(cwd_buf, sizeof(cwd_buf))) { + strlcpy(to, from, tolen); + return 0; + } + +#if defined(WIN32) || defined(__EMX__) + // convert all backslashes into forward slashes + for (newslash = strchr(cwd, '\\'); newslash; newslash = strchr(newslash + 1, '\\')) + *newslash = '/'; + + // test for the exact same string and return "." if so + if (!strcasecmp(from, cwd)) { + strlcpy(to, ".", tolen); + return (1); + } + + // test for the same drive. Return the absolute path if not + if (tolower(*from & 255) != tolower(*cwd & 255)) { + strlcpy(to, from, tolen); + return 0; + } + + // compare the path name without the drive prefix + from += 2; cwd += 2; +#else + // test for the exact same string and return "." if so + if (!strcmp(from, cwd)) { + strlcpy(to, ".", tolen); + return (1); + } +#endif // WIN32 || __EMX__ + + // compare both path names until we find a difference + for (slash = from, newslash = cwd; + *slash != '\0' && *newslash != '\0'; + slash ++, newslash ++) + if (isdirsep(*slash) && isdirsep(*newslash)) continue; +#if defined(WIN32) || defined(__EMX__) || defined(__APPLE__) + else if (tolower(*slash & 255) != tolower(*newslash & 255)) break; +#else + else if (*slash != *newslash) break; +#endif // WIN32 || __EMX__ || __APPLE__ + + // skip over trailing slashes + if ( *newslash == '\0' && *slash != '\0' && !isdirsep(*slash) + &&(newslash==cwd || !isdirsep(newslash[-1])) ) + newslash--; + + // now go back to the first character of the first differing paths segment + while (!isdirsep(*slash) && slash > from) slash --; + if (isdirsep(*slash)) slash ++; + + // do the same for the current dir + if (*newslash != '\0') + while (!isdirsep(*newslash) && newslash > cwd) newslash --; + + // prepare the destination buffer + to[0] = '\0'; + to[tolen - 1] = '\0'; + + // now add a "previous dir" sequence for every following slash in the cwd + while (*newslash != '\0') { + if (isdirsep(*newslash)) strlcat(to, "../", tolen); + + newslash ++; + } + + // finally add the differing path from "from" + strlcat(to, slash, tolen); + + return 1; +} + + +// +// End of "$Id: filename_absolute.cxx 6102 2008-04-21 19:54:34Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/filename_expand.cxx b/plugins/zynaddsubfx/fltk/src/filename_expand.cxx new file mode 100644 index 000000000..a308a8de6 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/filename_expand.cxx @@ -0,0 +1,110 @@ +// +// "$Id: filename_expand.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Filename expansion routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* expand a file name by substuting environment variables and + home directories. Returns true if any changes were made. + to & from may be the same buffer. +*/ + +#include +#include +#include "flstring.h" +#if defined(WIN32) && !defined(__CYGWIN__) +#else +# include +# include +#endif + +#if defined(WIN32) || defined(__EMX__) && !defined(__CYGWIN__) +static inline int isdirsep(char c) {return c=='/' || c=='\\';} +#else +#define isdirsep(c) ((c)=='/') +#endif + +int fl_filename_expand(char *to,int tolen, const char *from) { + + char *temp = new char[tolen]; + strlcpy(temp,from, tolen); + char *start = temp; + char *end = temp+strlen(temp); + + int ret = 0; + + for (char *a=temp; apw_dir; +#endif + } + break; + case '$': /* an environment variable */ + {char t = *e; *(char *)e = 0; value = getenv(a+1); *(char *)e = t;} + break; + } + if (value) { + // substitutions that start with slash delete everything before them: + if (isdirsep(value[0])) start = a; +#if defined(WIN32) || defined(__EMX__) && !defined(__CYGWIN__) + // also if it starts with "A:" + if (value[0] && value[1]==':') start = a; +#endif + int t = strlen(value); if (isdirsep(value[t-1])) t--; + if ((end+1-e+t) >= tolen) end += tolen - (end+1-e+t); + memmove(a+t, e, end+1-e); + end = a+t+(end-e); + *end = '\0'; + memcpy(a, value, t); + ret++; + } else { + a = e+1; +#if defined(WIN32) || defined(__EMX__) && !defined(__CYGWIN__) + if (*e == '\\') {*e = '/'; ret++;} // ha ha! +#endif + } + } + + strlcpy(to, start, tolen); + + delete[] temp; + + return ret; +} + + +// +// End of "$Id: filename_expand.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/filename_ext.cxx b/plugins/zynaddsubfx/fltk/src/filename_ext.cxx new file mode 100644 index 000000000..464827392 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/filename_ext.cxx @@ -0,0 +1,47 @@ +// +// "$Id: filename_ext.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Filename extension routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// returns pointer to the last '.' or to the null if none: + +#include + +const char *fl_filename_ext(const char *buf) { + const char *q = 0; + const char *p = buf; + for (p=buf; *p; p++) { + if (*p == '/') q = 0; +#if defined(WIN32) || defined(__EMX__) && !defined(__CYGWIN__) + else if (*p == '\\') q = 0; +#endif + else if (*p == '.') q = p; + } + return q ? q : p; +} + +// +// End of "$Id: filename_ext.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/filename_isdir.cxx b/plugins/zynaddsubfx/fltk/src/filename_isdir.cxx new file mode 100644 index 000000000..afa4c7103 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/filename_isdir.cxx @@ -0,0 +1,91 @@ +// +// "$Id: filename_isdir.cxx 5948 2007-10-07 10:12:32Z matt $" +// +// Directory detection routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Used by fl_file_chooser + +#include "flstring.h" +#include +#include +#include +#include + + +#if defined(WIN32) || defined(__EMX__) && !defined(__CYGWIN__) +static inline int isdirsep(char c) {return c=='/' || c=='\\';} +#else +#define isdirsep(c) ((c)=='/') +#endif + +int _fl_filename_isdir_quick(const char* n) { + // Do a quick optimization for filenames with a trailing slash... + if (*n && isdirsep(n[strlen(n) - 1])) return 1; + return fl_filename_isdir(n); +} + +int fl_filename_isdir(const char* n) { + struct stat s; + char fn[1024]; + int length; + + length = strlen(n); + +#ifdef WIN32 + // This workaround brought to you by the fine folks at Microsoft! + // (read lots of sarcasm in that...) + if (length < (int)(sizeof(fn) - 1)) { + if (length < 4 && isalpha(n[0]) && n[1] == ':' && + (isdirsep(n[2]) || !n[2])) { + // Always use D:/ for drive letters + fn[0] = n[0]; + strcpy(fn + 1, ":/"); + n = fn; + } else if (length > 0 && isdirsep(n[length - 1])) { + // Strip trailing slash from name... + length --; + memcpy(fn, n, length); + fn[length] = '\0'; + n = fn; + } + } +#else + // Matt: Just in case, we strip the slash for other operating + // systems as well, avoid bugs by sloppy implementations + // of "stat". + if (length > 1 && isdirsep(n[length - 1])) { + length --; + memcpy(fn, n, length); + fn[length] = '\0'; + n = fn; + } +#endif + + return !stat(n, &s) && (s.st_mode&0170000)==0040000; +} + +// +// End of "$Id: filename_isdir.cxx 5948 2007-10-07 10:12:32Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/filename_list.cxx b/plugins/zynaddsubfx/fltk/src/filename_list.cxx new file mode 100644 index 000000000..d986ff464 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/filename_list.cxx @@ -0,0 +1,107 @@ +// +// "$Id: filename_list.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Filename list routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Wrapper for scandir with const-correct function prototypes. + +#include +#include "flstring.h" +#include + + +extern "C" { +#ifndef HAVE_SCANDIR + int fl_scandir (const char *dir, dirent ***namelist, + int (*select)(dirent *), + int (*compar)(dirent **, dirent **)); +# define scandir fl_scandir +#endif +} + +int fl_alphasort(struct dirent **a, struct dirent **b) { + return strcmp((*a)->d_name, (*b)->d_name); +} + +int fl_casealphasort(struct dirent **a, struct dirent **b) { + return strcasecmp((*a)->d_name, (*b)->d_name); +} + + +int fl_filename_list(const char *d, dirent ***list, + Fl_File_Sort_F *sort) { +#ifndef HAVE_SCANDIR + int n = scandir(d, list, 0, sort); +#elif defined(__hpux) || defined(__CYGWIN__) + // HP-UX, Cygwin define the comparison function like this: + int n = scandir(d, list, 0, (int(*)(const dirent **, const dirent **))sort); +#elif defined(__osf__) + // OSF, DU 4.0x + int n = scandir(d, list, 0, (int(*)(dirent **, dirent **))sort); +#elif defined(_AIX) + // AIX is almost standard... + int n = scandir(d, list, 0, (int(*)(void*, void*))sort); +#elif !defined(__sgi) + // The vast majority of UNIX systems want the sort function to have this + // prototype, most likely so that it can be passed to qsort without any + // changes: + int n = scandir(d, list, 0, (int(*)(const void*,const void*))sort); +#else + // This version is when we define our own scandir (WIN32 and perhaps + // some Unix systems) and apparently on IRIX: + int n = scandir(d, list, 0, sort); +#endif + +#if defined(WIN32) && !defined(__CYGWIN__) + // we did this already during fl_scandir/win32 +#else + // append a '/' to all filenames that are directories + int i, dirlen = strlen(d); + char *fullname = (char*)malloc(dirlen+FL_PATH_MAX+3); // Add enough extra for two /'s and a nul + // Use memcpy for speed since we already know the length of the string... + memcpy(fullname, d, dirlen+1); + char *name = fullname + dirlen; + if (name!=fullname && name[-1]!='/') *name++ = '/'; + for (i=0; id_name); + if (de->d_name[len-1]=='/' || len>FL_PATH_MAX) continue; + // Use memcpy for speed since we already know the length of the string... + memcpy(name, de->d_name, len+1); + if (fl_filename_isdir(fullname)) { + (*list)[i] = de = (dirent*)realloc(de, de->d_name - (char*)de + len + 2); + char *dst = de->d_name + len; + *dst++ = '/'; + *dst = 0; + } + } + free(fullname); +#endif + return n; +} + +// +// End of "$Id: filename_list.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/filename_match.cxx b/plugins/zynaddsubfx/fltk/src/filename_match.cxx new file mode 100644 index 000000000..6b61308b7 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/filename_match.cxx @@ -0,0 +1,106 @@ +// +// "$Id: filename_match.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Pattern matching routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +/* Adapted from Rich Salz. */ +#include +#include + +int fl_filename_match(const char *s, const char *p) { + int matched; + + for (;;) { + switch(*p++) { + + case '?' : // match any single character + if (!*s++) return 0; + break; + + case '*' : // match 0-n of any characters + if (!*p) return 1; // do trailing * quickly + while (!fl_filename_match(s, p)) if (!*s++) return 0; + return 1; + + case '[': { // match one character in set of form [abc-d] or [^a-b] + if (!*s) return 0; + int reverse = (*p=='^' || *p=='!'); if (reverse) p++; + matched = 0; + char last = 0; + while (*p) { + if (*p=='-' && last) { + if (*s <= *++p && *s >= last ) matched = 1; + last = 0; + } else { + if (*s == *p) matched = 1; + } + last = *p++; + if (*p==']') break; + } + if (matched == reverse) return 0; + s++; p++;} + break; + + case '{' : // {pattern1|pattern2|pattern3} + NEXTCASE: + if (fl_filename_match(s,p)) return 1; + for (matched = 0;;) { + switch (*p++) { + case '\\': if (*p) p++; break; + case '{': matched++; break; + case '}': if (!matched--) return 0; break; + case '|': case ',': if (matched==0) goto NEXTCASE; + case 0: return 0; + } + } + case '|': // skip rest of |pattern|pattern} when called recursively + case ',': + for (matched = 0; *p && matched >= 0;) { + switch (*p++) { + case '\\': if (*p) p++; break; + case '{': matched++; break; + case '}': matched--; break; + } + } + break; + case '}': + break; + + case 0: // end of pattern + return !*s; + + case '\\': // quote next character + if (*p) p++; + default: + if (tolower(*s) != tolower(*(p-1))) return 0; + s++; + break; + } + } +} + +// +// End of "$Id: filename_match.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/filename_setext.cxx b/plugins/zynaddsubfx/fltk/src/filename_setext.cxx new file mode 100644 index 000000000..20222bdae --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/filename_setext.cxx @@ -0,0 +1,46 @@ +// +// "$Id: filename_setext.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Filename extension routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Replace .ext with new extension +// If no . in name, append new extension +// If new extension is null, act like it is "" + +#include +#include "flstring.h" + +char *fl_filename_setext(char *buf, int buflen, const char *ext) { + char *q = (char *)fl_filename_ext(buf); + if (ext) { + strlcpy(q,ext,buflen - (q - buf)); + } else *q = 0; + return(buf); +} + + +// +// End of "$Id: filename_setext.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_arc.cxx b/plugins/zynaddsubfx/fltk/src/fl_arc.cxx new file mode 100644 index 000000000..4fef5c966 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_arc.cxx @@ -0,0 +1,87 @@ +// +// "$Id: fl_arc.cxx 5349 2006-08-23 14:43:07Z matt $" +// +// Arc functions for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Utility for drawing arcs and circles. They are added to +// the current fl_begin/fl_vertex/fl_end path. +// Incremental math implementation: + +#include +#include + +// avoid problems with some platforms that don't +// implement hypot. +static double _fl_hypot(double x, double y) { + return sqrt(x*x + y*y); +} + + +void fl_arc(double x, double y, double r, double start, double end) { + + // draw start point accurately: + + double A = start*(M_PI/180); // Initial angle (radians) + double X = r*cos(A); // Initial displacement, (X,Y) + double Y = -r*sin(A); // from center to initial point + fl_vertex(x+X,y+Y); // Insert initial point + + // Maximum arc length to approximate with chord with error <= 0.125 + + double epsilon; { + double r1 = _fl_hypot(fl_transform_dx(r,0), // Horizontal "radius" + fl_transform_dy(r,0)); + double r2 = _fl_hypot(fl_transform_dx(0,r), // Vertical "radius" + fl_transform_dy(0,r)); + + if (r1 > r2) r1 = r2; // r1 = minimum "radius" + if (r1 < 2.) r1 = 2.; // radius for circa 9 chords/circle + + epsilon = 2*acos(1.0 - 0.125/r1); // Maximum arc angle + } + A = end*(M_PI/180) - A; // Displacement angle (radians) + int i = int(ceil(fabs(A)/epsilon)); // Segments in approximation + + if (i) { + epsilon = A/i; // Arc length for equal-size steps + double cos_e = cos(epsilon); // Rotation coefficients + double sin_e = sin(epsilon); + do { + double Xnew = cos_e*X + sin_e*Y; + Y = -sin_e*X + cos_e*Y; + fl_vertex(x + (X=Xnew), y + Y); + } while (--i); + } +} + +#if 0 // portable version. X-specific one in fl_vertex.cxx +void fl_circle(double x,double y,double r) { + _fl_arc(x, y, r, r, 0, 360); +} +#endif + +// +// End of "$Id: fl_arc.cxx 5349 2006-08-23 14:43:07Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_arci.cxx b/plugins/zynaddsubfx/fltk/src/fl_arci.cxx new file mode 100644 index 000000000..7d8b33f34 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_arci.cxx @@ -0,0 +1,126 @@ +// +// "$Id: fl_arci.cxx 5518 2006-10-11 01:23:52Z mike $" +// +// Arc (integer) drawing functions for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2006 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// "integer" circle drawing functions. These draw the limited +// circle types provided by X and NT graphics. The advantage of +// these is that small ones draw quite nicely (probably due to stored +// hand-drawn bitmaps of small circles!) and may be implemented by +// hardware and thus are fast. + +// Probably should add fl_chord. + +// 3/10/98: created + +#include +#include +#ifdef WIN32 +# include +#endif +#ifdef __APPLE__ +# include +#endif + +void fl_arc(int x,int y,int w,int h,double a1,double a2) { + if (w <= 0 || h <= 0) return; +#ifdef WIN32 + int xa = x+w/2+int(w*cos(a1/180.0*M_PI)); + int ya = y+h/2-int(h*sin(a1/180.0*M_PI)); + int xb = x+w/2+int(w*cos(a2/180.0*M_PI)); + int yb = y+h/2-int(h*sin(a2/180.0*M_PI)); + if (fabs(a1 - a2) < 90) { + if (xa == xb && ya == yb) SetPixel(fl_gc, xa, ya, fl_RGB()); + else Arc(fl_gc, x, y, x+w, y+h, xa, ya, xb, yb); + } else Arc(fl_gc, x, y, x+w, y+h, xa, ya, xb, yb); +#elif defined(__APPLE_QD__) + Rect r; r.left=x; r.right=x+w; r.top=y; r.bottom=y+h; + a1 = a2-a1; a2 = 450-a2; + FrameArc(&r, (short int)a2, (short int)a1); +#elif defined(__APPLE_QUARTZ__) + a1 = (-a1)/180.0f*M_PI; a2 = (-a2)/180.0f*M_PI; + float cx = x + 0.5f*w - 0.5f, cy = y + 0.5f*h - 0.5f; + if (w!=h) { + CGContextSaveGState(fl_gc); + CGContextTranslateCTM(fl_gc, cx, cy); + CGContextScaleCTM(fl_gc, w-1.0f, h-1.0f); + CGContextAddArc(fl_gc, 0, 0, 0.5, a1, a2, 1); + CGContextRestoreGState(fl_gc); + } else { + float r = (w+h)*0.25f-0.5f; + CGContextAddArc(fl_gc, cx, cy, r, a1, a2, 1); + } + CGContextStrokePath(fl_gc); +#else + XDrawArc(fl_display, fl_window, fl_gc, x,y,w-1,h-1, int(a1*64),int((a2-a1)*64)); +#endif +} + +void fl_pie(int x,int y,int w,int h,double a1,double a2) { + if (w <= 0 || h <= 0) return; +#ifdef WIN32 + if (a1 == a2) return; + int xa = x+w/2+int(w*cos(a1/180.0*M_PI)); + int ya = y+h/2-int(h*sin(a1/180.0*M_PI)); + int xb = x+w/2+int(w*cos(a2/180.0*M_PI)); + int yb = y+h/2-int(h*sin(a2/180.0*M_PI)); + SelectObject(fl_gc, fl_brush()); + if (fabs(a1 - a2) < 90) { + if (xa == xb && ya == yb) { + MoveToEx(fl_gc, x+w/2, y+h/2, 0L); + LineTo(fl_gc, xa, ya); + SetPixel(fl_gc, xa, ya, fl_RGB()); + } else Pie(fl_gc, x, y, x+w, y+h, xa, ya, xb, yb); + } else Pie(fl_gc, x, y, x+w, y+h, xa, ya, xb, yb); +#elif defined(__APPLE_QD__) + Rect r; r.left=x; r.right=x+w; r.top=y; r.bottom=y+h; + a1 = a2-a1; a2 = 450-a2; + PaintArc(&r, (short int)a2, (short int)a1); +#elif defined(__APPLE_QUARTZ__) + a1 = (-a1)/180.0f*M_PI; a2 = (-a2)/180.0f*M_PI; + float cx = x + 0.5f*w - 0.5f, cy = y + 0.5f*h - 0.5f; + if (w!=h) { + CGContextSaveGState(fl_gc); + CGContextTranslateCTM(fl_gc, cx, cy); + CGContextScaleCTM(fl_gc, w, h); + CGContextAddArc(fl_gc, 0, 0, 0.5, a1, a2, 1); + CGContextAddLineToPoint(fl_gc, 0, 0); + CGContextClosePath(fl_gc); + CGContextRestoreGState(fl_gc); + } else { + float r = (w+h)*0.25f; + CGContextAddArc(fl_gc, cx, cy, r, a1, a2, 1); + CGContextAddLineToPoint(fl_gc, cx, cy); + CGContextClosePath(fl_gc); + } + CGContextFillPath(fl_gc); +#else + XFillArc(fl_display, fl_window, fl_gc, x,y,w-1,h-1, int(a1*64),int((a2-a1)*64)); +#endif +} + +// +// End of "$Id: fl_arci.cxx 5518 2006-10-11 01:23:52Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_ask.cxx b/plugins/zynaddsubfx/fltk/src/fl_ask.cxx new file mode 100644 index 000000000..0a5cd8e07 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_ask.cxx @@ -0,0 +1,371 @@ +// +// "$Id: fl_ask.cxx 6035 2008-02-20 18:33:25Z matt $" +// +// Standard dialog functions for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Implementation of fl_message, fl_ask, fl_choice, fl_input +// The three-message fl_show_x functions are for forms compatibility +// mostly. In most cases it is easier to get a multi-line message +// by putting newlines in the message. + +#include +#include +#include "flstring.h" + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static Fl_Window *message_form; +static Fl_Box *message; +static Fl_Box *icon; +static Fl_Button *button[3]; +static Fl_Input *input; +static const char *iconlabel = "?"; +Fl_Font fl_message_font_ = FL_HELVETICA; +uchar fl_message_size_ = 14; + +static Fl_Window *makeform() { + if (message_form) { + message_form->size(410,103); + return message_form; + } + // make sure that the dialog does not become the child of some + // current group + Fl_Group *previously_current_group = Fl_Group::current(); + Fl_Group::current(0); + // create a new top level window + Fl_Window *w = message_form = new Fl_Window(410,103,""); + // w->clear_border(); + // w->box(FL_UP_BOX); + (message = new Fl_Box(60, 25, 340, 20)) + ->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE|FL_ALIGN_WRAP); + (input = new Fl_Input(60, 37, 340, 23))->hide(); + {Fl_Box* o = icon = new Fl_Box(10, 10, 50, 50); + o->box(FL_THIN_UP_BOX); + o->labelfont(FL_TIMES_BOLD); + o->labelsize(34); + o->color(FL_WHITE); + o->labelcolor(FL_BLUE); + } + button[0] = new Fl_Button(310, 70, 90, 23); + button[0]->shortcut(FL_Escape); + button[0]->align(FL_ALIGN_INSIDE|FL_ALIGN_WRAP); + button[1] = new Fl_Return_Button(210, 70, 90, 23); + button[1]->align(FL_ALIGN_INSIDE|FL_ALIGN_WRAP); + button[2] = new Fl_Button(110, 70, 90, 23); + button[2]->align(FL_ALIGN_INSIDE|FL_ALIGN_WRAP); + w->resizable(new Fl_Box(60,10,110-60,27)); + w->end(); + w->set_modal(); + Fl_Group::current(previously_current_group); + return w; +} + +/* + * 'resizeform()' - Resize the form and widgets so that they hold everything + * that is asked of them... + */ + +void resizeform() { + int i; + int message_w, message_h; + int text_height; + int button_w[3], button_h[3]; + int x, w, h, max_w, max_h; + const int icon_size = 50; + + fl_font(fl_message_font_, fl_message_size_); + message_w = message_h = 0; + fl_measure(message->label(), message_w, message_h); + + message_w += 10; + message_h += 10; + if (message_w < 340) + message_w = 340; + if (message_h < 30) + message_h = 30; + + fl_font(button[0]->labelfont(), button[0]->labelsize()); + + memset(button_w, 0, sizeof(button_w)); + memset(button_h, 0, sizeof(button_h)); + + for (max_h = 25, i = 0; i < 3; i ++) + if (button[i]->visible()) + { + fl_measure(button[i]->label(), button_w[i], button_h[i]); + + if (i == 1) + button_w[1] += 20; + + button_w[i] += 30; + button_h[i] += 10; + + if (button_h[i] > max_h) + max_h = button_h[i]; + } + + if (input->visible()) text_height = message_h + 25; + else text_height = message_h; + + max_w = message_w + 10 + icon_size; + w = button_w[0] + button_w[1] + button_w[2] - 10; + + if (w > max_w) + max_w = w; + + message_w = max_w - 10 - icon_size; + + w = max_w + 20; + h = max_h + 30 + text_height; + + message_form->size(w, h); + message_form->size_range(w, h, w, h); + + message->resize(20 + icon_size, 10, message_w, message_h); + icon->resize(10, 10, icon_size, icon_size); + icon->labelsize((uchar)(icon_size - 10)); + input->resize(20 + icon_size, 10 + message_h, message_w, 25); + + for (x = w, i = 0; i < 3; i ++) + if (button_w[i]) + { + x -= button_w[i]; + button[i]->resize(x, h - 10 - max_h, button_w[i] - 10, max_h); + +// printf("button %d (%s) is %dx%d+%d,%d\n", i, button[i]->label(), +// button[i]->w(), button[i]->h(), +// button[i]->x(), button[i]->y()); + } +} + +static int innards(const char* fmt, va_list ap, + const char *b0, + const char *b1, + const char *b2) +{ + makeform(); + char buffer[1024]; + if (!strcmp(fmt,"%s")) { + message->label(va_arg(ap, const char*)); + } else { + //: matt: MacOS provides two equally named vsnprintf's... + ::vsnprintf(buffer, 1024, fmt, ap); + message->label(buffer); + } + + message->labelfont(fl_message_font_); + message->labelsize(fl_message_size_); + if (b0) {button[0]->show(); button[0]->label(b0); button[1]->position(210,70);} + else {button[0]->hide(); button[1]->position(310,70);} + if (b1) {button[1]->show(); button[1]->label(b1);} + else button[1]->hide(); + if (b2) {button[2]->show(); button[2]->label(b2);} + else button[2]->hide(); + const char* prev_icon_label = icon->label(); + if (!prev_icon_label) icon->label(iconlabel); + + resizeform(); + + if (button[1]->visible() && !input->visible()) + button[1]->take_focus(); + message_form->hotspot(button[0]); + if (b0 && Fl_Widget::label_shortcut(b0)) + button[0]->shortcut(0); + else + button[0]->shortcut(FL_Escape); + + message_form->show(); + // deactivate Fl::grab(), because it is incompatible with Fl::readqueue() + Fl_Window* g = Fl::grab(); + if (g) // do an alternative grab to avoid floating menus, if possible + Fl::grab(message_form); + int r; + for (;;) { + Fl_Widget *o = Fl::readqueue(); + if (!o) Fl::wait(); + else if (o == button[0]) {r = 0; break;} + else if (o == button[1]) {r = 1; break;} + else if (o == button[2]) {r = 2; break;} + else if (o == message_form) {r = 0; break;} + } + if (g) // regrab the previous popup menu, if there was one + Fl::grab(g); + message_form->hide(); + icon->label(prev_icon_label); + return r; +} + +// pointers you can use to change FLTK to a foreign language: +const char* fl_no = "No"; +const char* fl_yes= "Yes"; +const char* fl_ok = "OK"; +const char* fl_cancel= "Cancel"; +const char* fl_close= "Close"; + +// fltk functions: +void fl_beep(int type) { +#ifdef WIN32 + switch (type) { + case FL_BEEP_QUESTION : + case FL_BEEP_PASSWORD : + MessageBeep(MB_ICONQUESTION); + break; + case FL_BEEP_MESSAGE : + MessageBeep(MB_ICONASTERISK); + break; + case FL_BEEP_NOTIFICATION : + MessageBeep(MB_ICONASTERISK); + break; + case FL_BEEP_ERROR : + MessageBeep(MB_ICONERROR); + break; + default : + MessageBeep(0xFFFFFFFF); + break; + } +#elif defined(__APPLE__) + switch (type) { + case FL_BEEP_DEFAULT : + case FL_BEEP_ERROR : + SysBeep(30); + break; + default : + break; + } +#else + switch (type) { + case FL_BEEP_DEFAULT : + case FL_BEEP_ERROR : + if (!fl_display) fl_open_display(); + + XBell(fl_display, 100); + break; + default : + if (!fl_display) fl_open_display(); + + XBell(fl_display, 50); + break; + } +#endif // WIN32 +} + +void fl_message(const char *fmt, ...) { + va_list ap; + + fl_beep(FL_BEEP_MESSAGE); + + va_start(ap, fmt); + iconlabel = "i"; + innards(fmt, ap, 0, fl_close, 0); + va_end(ap); + iconlabel = "?"; +} + +void fl_alert(const char *fmt, ...) { + va_list ap; + + fl_beep(FL_BEEP_ERROR); + + va_start(ap, fmt); + iconlabel = "!"; + innards(fmt, ap, 0, fl_close, 0); + va_end(ap); + iconlabel = "?"; +} + +int fl_ask(const char *fmt, ...) { + va_list ap; + + fl_beep(FL_BEEP_QUESTION); + + va_start(ap, fmt); + int r = innards(fmt, ap, fl_no, fl_yes, 0); + va_end(ap); + + return r; +} + +int fl_choice(const char*fmt,const char *b0,const char *b1,const char *b2,...){ + va_list ap; + + fl_beep(FL_BEEP_QUESTION); + + va_start(ap, b2); + int r = innards(fmt, ap, b0, b1, b2); + va_end(ap); + return r; +} + +Fl_Widget *fl_message_icon() {makeform(); return icon;} + +static const char* input_innards(const char* fmt, va_list ap, + const char* defstr, uchar type) { + makeform(); + message->position(60,10); + input->type(type); + input->show(); + input->value(defstr); + input->take_focus(); + + int r = innards(fmt, ap, fl_cancel, fl_ok, 0); + input->hide(); + message->position(60,25); + return r ? input->value() : 0; +} + +const char* fl_input(const char *fmt, const char *defstr, ...) { + fl_beep(FL_BEEP_QUESTION); + + va_list ap; + va_start(ap, defstr); + const char* r = input_innards(fmt, ap, defstr, FL_NORMAL_INPUT); + va_end(ap); + return r; +} + +const char *fl_password(const char *fmt, const char *defstr, ...) { + fl_beep(FL_BEEP_PASSWORD); + + va_list ap; + va_start(ap, defstr); + const char* r = input_innards(fmt, ap, defstr, FL_SECRET_INPUT); + va_end(ap); + return r; +} + +// +// End of "$Id: fl_ask.cxx 6035 2008-02-20 18:33:25Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_boxtype.cxx b/plugins/zynaddsubfx/fltk/src/fl_boxtype.cxx new file mode 100644 index 000000000..d86dea3be --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_boxtype.cxx @@ -0,0 +1,322 @@ +// +// "$Id: fl_boxtype.cxx 5505 2006-10-03 02:35:12Z mike $" +// +// Box drawing code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2006 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Box drawing code for the common box types and the table of +// boxtypes. Other box types are in seperate files so they are not +// linked in if not used. + +#include +#include +#include +#include + +//////////////////////////////////////////////////////////////// + +static uchar active_ramp[24] = { + FL_GRAY_RAMP+0, FL_GRAY_RAMP+1, FL_GRAY_RAMP+2, FL_GRAY_RAMP+3, + FL_GRAY_RAMP+4, FL_GRAY_RAMP+5, FL_GRAY_RAMP+6, FL_GRAY_RAMP+7, + FL_GRAY_RAMP+8, FL_GRAY_RAMP+9, FL_GRAY_RAMP+10,FL_GRAY_RAMP+11, + FL_GRAY_RAMP+12,FL_GRAY_RAMP+13,FL_GRAY_RAMP+14,FL_GRAY_RAMP+15, + FL_GRAY_RAMP+16,FL_GRAY_RAMP+17,FL_GRAY_RAMP+18,FL_GRAY_RAMP+19, + FL_GRAY_RAMP+20,FL_GRAY_RAMP+21,FL_GRAY_RAMP+22,FL_GRAY_RAMP+23}; +static uchar inactive_ramp[24] = { + 43, 43, 44, 44, + 44, 45, 45, 46, + 46, 46, 47, 47, + 48, 48, 48, 49, + 49, 49, 50, 50, + 51, 51, 52, 52}; +static int draw_it_active = 1; + +int Fl::draw_box_active() { return draw_it_active; } + +uchar *fl_gray_ramp() {return (draw_it_active?active_ramp:inactive_ramp)-'A';} + +void fl_frame(const char* s, int x, int y, int w, int h) { + uchar *g = fl_gray_ramp(); + if (h > 0 && w > 0) for (;*s;) { + // draw top line: + fl_color(g[*s++]); + fl_xyline(x, y, x+w-1); + y++; if (--h <= 0) break; + // draw left line: + fl_color(g[*s++]); + fl_yxline(x, y+h-1, y); + x++; if (--w <= 0) break; + // draw bottom line: + fl_color(g[*s++]); + fl_xyline(x, y+h-1, x+w-1); + if (--h <= 0) break; + // draw right line: + fl_color(g[*s++]); + fl_yxline(x+w-1, y+h-1, y); + if (--w <= 0) break; + } +} + +void fl_frame2(const char* s, int x, int y, int w, int h) { + uchar *g = fl_gray_ramp(); + if (h > 0 && w > 0) for (;*s;) { + // draw bottom line: + fl_color(g[*s++]); + fl_xyline(x, y+h-1, x+w-1); + if (--h <= 0) break; + // draw right line: + fl_color(g[*s++]); + fl_yxline(x+w-1, y+h-1, y); + if (--w <= 0) break; + // draw top line: + fl_color(g[*s++]); + fl_xyline(x, y, x+w-1); + y++; if (--h <= 0) break; + // draw left line: + fl_color(g[*s++]); + fl_yxline(x, y+h-1, y); + x++; if (--w <= 0) break; + } +} + +void fl_no_box(int, int, int, int, Fl_Color) {} + +void fl_thin_down_frame(int x, int y, int w, int h, Fl_Color) { + fl_frame2("WWHH",x,y,w,h); +} + +void fl_thin_down_box(int x, int y, int w, int h, Fl_Color c) { + fl_thin_down_frame(x,y,w,h,c); + fl_color(draw_it_active ? c : fl_inactive(c)); + fl_rectf(x+1, y+1, w-2, h-2); +} + +void fl_thin_up_frame(int x, int y, int w, int h, Fl_Color) { + fl_frame2("HHWW",x,y,w,h); +} + +void fl_thin_up_box(int x, int y, int w, int h, Fl_Color c) { + fl_thin_up_frame(x,y,w,h,c); + fl_color(draw_it_active ? c : fl_inactive(c)); + fl_rectf(x+1, y+1, w-2, h-2); +} + +void fl_up_frame(int x, int y, int w, int h, Fl_Color) { +#if BORDER_WIDTH == 1 + fl_frame2("HHWW",x,y,w,h); +#else +#if BORDER_WIDTH == 2 + fl_frame2("AAWWMMTT",x,y,w,h); +#else + fl_frame("AAAAWWJJUTNN",x,y,w,h); +#endif +#endif +} + +#define D1 BORDER_WIDTH +#define D2 (BORDER_WIDTH+BORDER_WIDTH) + +void fl_up_box(int x, int y, int w, int h, Fl_Color c) { + fl_up_frame(x,y,w,h,c); + fl_color(draw_it_active ? c : fl_inactive(c)); + fl_rectf(x+D1, y+D1, w-D2, h-D2); +} + +void fl_down_frame(int x, int y, int w, int h, Fl_Color) { +#if BORDER_WIDTH == 1 + fl_frame2("WWHH",x,y,w,h); +#else +#if BORDER_WIDTH == 2 + fl_frame2("WWMMPPAA",x,y,w,h); +#else + fl_frame("NNTUJJWWAAAA",x,y,w,h); +#endif +#endif +} + +void fl_down_box(int x, int y, int w, int h, Fl_Color c) { + fl_down_frame(x,y,w,h,c); + fl_color(c); fl_rectf(x+D1, y+D1, w-D2, h-D2); +} + +void fl_engraved_frame(int x, int y, int w, int h, Fl_Color) { + fl_frame("HHWWWWHH",x,y,w,h); +} + +void fl_engraved_box(int x, int y, int w, int h, Fl_Color c) { + fl_engraved_frame(x,y,w,h,c); + fl_color(draw_it_active ? c : fl_inactive(c)); + fl_rectf(x+2, y+2, w-4, h-4); +} + +void fl_embossed_frame(int x, int y, int w, int h, Fl_Color) { + fl_frame("WWHHHHWW",x,y,w,h); +} + +void fl_embossed_box(int x, int y, int w, int h, Fl_Color c) { + fl_embossed_frame(x,y,w,h,c); + fl_color(draw_it_active ? c : fl_inactive(c)); + fl_rectf(x+2, y+2, w-4, h-4); +} + +void fl_rectbound(int x, int y, int w, int h, Fl_Color bgcolor) { + fl_color(draw_it_active ? FL_BLACK : fl_inactive(FL_BLACK)); + fl_rect(x, y, w, h); + fl_color(draw_it_active ? bgcolor : fl_inactive(bgcolor)); + fl_rectf(x+1, y+1, w-2, h-2); +} +#define fl_border_box fl_rectbound + +void fl_border_frame(int x, int y, int w, int h, Fl_Color c) { + fl_color(draw_it_active ? c : fl_inactive(c)); + fl_rect(x, y, w, h); +} + +//////////////////////////////////////////////////////////////// + +static struct { + Fl_Box_Draw_F *f; + uchar dx, dy, dw, dh; + int set; +} fl_box_table[256] = { +// must match list in Enumerations.H!!! + {fl_no_box, 0,0,0,0,1}, + {fl_rectf, 0,0,0,0,1}, // FL_FLAT_BOX + {fl_up_box, D1,D1,D2,D2,1}, + {fl_down_box, D1,D1,D2,D2,1}, + {fl_up_frame, D1,D1,D2,D2,1}, + {fl_down_frame, D1,D1,D2,D2,1}, + {fl_thin_up_box, 1,1,2,2,1}, + {fl_thin_down_box, 1,1,2,2,1}, + {fl_thin_up_frame, 1,1,2,2,1}, + {fl_thin_down_frame, 1,1,2,2,1}, + {fl_engraved_box, 2,2,4,4,1}, + {fl_embossed_box, 2,2,4,4,1}, + {fl_engraved_frame, 2,2,4,4,1}, + {fl_embossed_frame, 2,2,4,4,1}, + {fl_border_box, 1,1,2,2,1}, + {fl_border_box, 1,1,5,5,0}, // _FL_SHADOW_BOX, + {fl_border_frame, 1,1,2,2,1}, + {fl_border_frame, 1,1,5,5,0}, // _FL_SHADOW_FRAME, + {fl_border_box, 1,1,2,2,0}, // _FL_ROUNDED_BOX, + {fl_border_box, 1,1,2,2,0}, // _FL_RSHADOW_BOX, + {fl_border_frame, 1,1,2,2,0}, // _FL_ROUNDED_FRAME + {fl_rectf, 0,0,0,0,0}, // _FL_RFLAT_BOX, + {fl_up_box, 3,3,6,6,0}, // _FL_ROUND_UP_BOX + {fl_down_box, 3,3,6,6,0}, // _FL_ROUND_DOWN_BOX, + {fl_up_box, 0,0,0,0,0}, // _FL_DIAMOND_UP_BOX + {fl_down_box, 0,0,0,0,0}, // _FL_DIAMOND_DOWN_BOX + {fl_border_box, 1,1,2,2,0}, // _FL_OVAL_BOX, + {fl_border_box, 1,1,2,2,0}, // _FL_OVAL_SHADOW_BOX, + {fl_border_frame, 1,1,2,2,0}, // _FL_OVAL_FRAME + {fl_rectf, 0,0,0,0,0}, // _FL_OVAL_FLAT_BOX, + {fl_up_box, 4,4,8,8,0}, // _FL_PLASTIC_UP_BOX, + {fl_down_box, 2,2,4,4,0}, // _FL_PLASTIC_DOWN_BOX, + {fl_up_frame, 2,2,4,4,0}, // _FL_PLASTIC_UP_FRAME, + {fl_down_frame, 2,2,4,4,0}, // _FL_PLASTIC_DOWN_FRAME, + {fl_up_box, 2,2,4,4,0}, // _FL_PLASTIC_THIN_UP_BOX, + {fl_down_box, 2,2,4,4,0}, // _FL_PLASTIC_THIN_DOWN_BOX, + {fl_up_box, 2,2,4,4,0}, // _FL_PLASTIC_ROUND_UP_BOX, + {fl_down_box, 2,2,4,4,0}, // _FL_PLASTIC_ROUND_DOWN_BOX, + {fl_up_box, 2,2,4,4,0}, // _FL_GTK_UP_BOX, + {fl_down_box, 2,2,4,4,0}, // _FL_GTK_DOWN_BOX, + {fl_up_frame, 2,2,4,4,0}, // _FL_GTK_UP_FRAME, + {fl_down_frame, 2,2,4,4,0}, // _FL_GTK_DOWN_FRAME, + {fl_up_frame, 1,1,2,2,0}, // _FL_GTK_THIN_UP_FRAME, + {fl_down_frame, 1,1,2,2,0}, // _FL_GTK_THIN_DOWN_FRAME, + {fl_up_box, 1,1,2,2,0}, // _FL_GTK_THIN_ROUND_UP_BOX, + {fl_down_box, 1,1,2,2,0}, // _FL_GTK_THIN_ROUND_DOWN_BOX, + {fl_up_box, 2,2,4,4,0}, // _FL_GTK_ROUND_UP_BOX, + {fl_down_box, 2,2,4,4,0}, // _FL_GTK_ROUND_DOWN_BOX, + {fl_up_box, 3,3,6,6,0}, // FL_FREE_BOX+0 + {fl_down_box, 3,3,6,6,0}, // FL_FREE_BOX+1 + {fl_up_box, 3,3,6,6,0}, // FL_FREE_BOX+2 + {fl_down_box, 3,3,6,6,0}, // FL_FREE_BOX+3 + {fl_up_box, 3,3,6,6,0}, // FL_FREE_BOX+4 + {fl_down_box, 3,3,6,6,0}, // FL_FREE_BOX+5 + {fl_up_box, 3,3,6,6,0}, // FL_FREE_BOX+6 + {fl_down_box, 3,3,6,6,0}, // FL_FREE_BOX+7 +}; + +int Fl::box_dx(Fl_Boxtype t) {return fl_box_table[t].dx;} +int Fl::box_dy(Fl_Boxtype t) {return fl_box_table[t].dy;} +int Fl::box_dw(Fl_Boxtype t) {return fl_box_table[t].dw;} +int Fl::box_dh(Fl_Boxtype t) {return fl_box_table[t].dh;} + +void fl_internal_boxtype(Fl_Boxtype t, Fl_Box_Draw_F* f) { + if (!fl_box_table[t].set) { + fl_box_table[t].f = f; + fl_box_table[t].set = 1; + } +} + +Fl_Box_Draw_F *Fl::get_boxtype(Fl_Boxtype t) { + return fl_box_table[t].f; +} + +void Fl::set_boxtype(Fl_Boxtype t, Fl_Box_Draw_F* f, + uchar a, uchar b, uchar c, uchar d) { + fl_box_table[t].f = f; + fl_box_table[t].set = 1; + fl_box_table[t].dx = a; + fl_box_table[t].dy = b; + fl_box_table[t].dw = c; + fl_box_table[t].dh = d; +} + +void Fl::set_boxtype(Fl_Boxtype t, Fl_Boxtype f) { + fl_box_table[t] = fl_box_table[f]; +} + +void fl_draw_box(Fl_Boxtype t, int x, int y, int w, int h, Fl_Color c) { + if (t && fl_box_table[t].f) fl_box_table[t].f(x,y,w,h,c); +} + +//extern Fl_Widget *fl_boxcheat; // hack set by Fl_Window.cxx + +void Fl_Widget::draw_box() const { + int t = box_; + if (!t) return; +// if (this == fl_boxcheat) { +// fl_boxcheat = 0; +// if (t == FL_FLAT_BOX) return; +// t += 2; // convert box to frame +// } + draw_box((Fl_Boxtype)t, x_, y_, w_, h_, (Fl_Color)color_); +} + +void Fl_Widget::draw_box(Fl_Boxtype b, Fl_Color c) const { + draw_box(b, x_, y_, w_, h_, c); +} + +void Fl_Widget::draw_box(Fl_Boxtype b, int X, int Y, int W, int H, Fl_Color c) +const { + draw_it_active = active_r(); + fl_box_table[b].f(X, Y, W, H, c); + draw_it_active = 1; +} + +// +// End of "$Id: fl_boxtype.cxx 5505 2006-10-03 02:35:12Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_call_main.c b/plugins/zynaddsubfx/fltk/src/fl_call_main.c new file mode 100644 index 000000000..aa217d3f4 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_call_main.c @@ -0,0 +1,107 @@ +/* + * "$Id: fl_call_main.c 5848 2007-05-20 16:18:31Z mike $" + * + * Copyright 1998-2005 by Bill Spitzak and others. + * + * fl_call_main() calls main() for you Windows people. Needs to be done in C + * because Borland C++ won't let you call main() from C++. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems on the following page: + * + * http://www.fltk.org/str.php + */ + +/* + * This WinMain() function can be overridden by an application and + * is provided for compatibility with programs written for other + * operating systems that conform to the ANSI standard entry point + * "main()". This will allow you to build a WIN32 Application + * without any special settings. + * + * Because of problems with the Microsoft Visual C++ header files + * and/or compiler, you cannot have a WinMain function in a DLL. + * I don't know why. Thus, this nifty feature is only available + * if you link to the static library. + * + * Currently the debug version of this library will create a + * console window for your application so you can put printf() + * statements for debugging or informational purposes. Ultimately + * we want to update this to always use the parent's console, + * but at present we have not identified a function or API in + * Microsoft(r) Windows(r) that allows for it. + */ + +#if defined(WIN32) && !defined(FL_DLL) && !defined (__GNUC__) + +# include +# include +# include + +# ifdef __MWERKS__ +# include +# endif + +extern int main(int, char *[]); + +# ifdef BORLAND5 +# define __argc _argc +# define __argv _argv +# endif /* BORLAND5 */ + +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, + LPSTR lpCmdLine, int nCmdShow) { + int rc; + +# ifdef _DEBUG + /* + * If we are using compiling in debug mode, open a console window so + * we can see any printf's, etc... + * + * While we can detect if the program was run from the command-line - + * look at the CMDLINE environment variable, it will be "WIN" for + * programs started from the GUI - the shell seems to run all WIN32 + * applications in the background anyways... + */ + + AllocConsole(); + freopen("conin$", "r", stdin); + freopen("conout$", "w", stdout); + freopen("conout$", "w", stderr); +# endif /* _DEBUG */ + + /* Run the standard main entry point function... */ + rc = main(__argc, __argv); + +# ifdef _DEBUG + fclose(stdin); + fclose(stdout); + fclose(stderr); +# endif /* _DEBUG */ + + return rc; +} + +#elif defined(__hpux) +/* This code to prevent "empty translation unit" or similar warnings... */ +static void dummy(void) {} +#endif // WIN32 && !FL_DLL && !__GNUC__ + +/* + * End of "$Id: fl_call_main.c 5848 2007-05-20 16:18:31Z mike $". + */ + diff --git a/plugins/zynaddsubfx/fltk/src/fl_cmap.h b/plugins/zynaddsubfx/fltk/src/fl_cmap.h new file mode 100644 index 000000000..3b05ee7cf --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_cmap.h @@ -0,0 +1,256 @@ + 0x00000000, + 0xff000000, + 0x00ff0000, + 0xffff0000, + 0x0000ff00, + 0xff00ff00, + 0x00ffff00, + 0xffffff00, + 0x55555500, + 0xc6717100, + 0x71c67100, + 0x8e8e3800, + 0x7171c600, + 0x8e388e00, + 0x388e8e00, + 0x00008000, + 0xa8a89800, + 0xe8e8d800, + 0x68685800, + 0x98a8a800, + 0xd8e8e800, + 0x58686800, + 0x9c9ca800, + 0xdcdce800, + 0x5c5c6800, + 0x9ca89c00, + 0xdce8dc00, + 0x5c685c00, + 0x90909000, + 0xc0c0c000, + 0x50505000, + 0xa0a0a000, + 0x00000000, + 0x0d0d0d00, + 0x1a1a1a00, + 0x26262600, + 0x31313100, + 0x3d3d3d00, + 0x48484800, + 0x55555500, + 0x5f5f5f00, + 0x6a6a6a00, + 0x75757500, + 0x80808000, + 0x8a8a8a00, + 0x95959500, + 0xa0a0a000, + 0xaaaaaa00, + 0xb5b5b500, + 0xc0c0c000, + 0xcbcbcb00, + 0xd5d5d500, + 0xe0e0e000, + 0xeaeaea00, + 0xf5f5f500, + 0xffffff00, + 0x00000000, + 0x00240000, + 0x00480000, + 0x006d0000, + 0x00910000, + 0x00b60000, + 0x00da0000, + 0x00ff0000, + 0x3f000000, + 0x3f240000, + 0x3f480000, + 0x3f6d0000, + 0x3f910000, + 0x3fb60000, + 0x3fda0000, + 0x3fff0000, + 0x7f000000, + 0x7f240000, + 0x7f480000, + 0x7f6d0000, + 0x7f910000, + 0x7fb60000, + 0x7fda0000, + 0x7fff0000, + 0xbf000000, + 0xbf240000, + 0xbf480000, + 0xbf6d0000, + 0xbf910000, + 0xbfb60000, + 0xbfda0000, + 0xbfff0000, + 0xff000000, + 0xff240000, + 0xff480000, + 0xff6d0000, + 0xff910000, + 0xffb60000, + 0xffda0000, + 0xffff0000, + 0x00003f00, + 0x00243f00, + 0x00483f00, + 0x006d3f00, + 0x00913f00, + 0x00b63f00, + 0x00da3f00, + 0x00ff3f00, + 0x3f003f00, + 0x3f243f00, + 0x3f483f00, + 0x3f6d3f00, + 0x3f913f00, + 0x3fb63f00, + 0x3fda3f00, + 0x3fff3f00, + 0x7f003f00, + 0x7f243f00, + 0x7f483f00, + 0x7f6d3f00, + 0x7f913f00, + 0x7fb63f00, + 0x7fda3f00, + 0x7fff3f00, + 0xbf003f00, + 0xbf243f00, + 0xbf483f00, + 0xbf6d3f00, + 0xbf913f00, + 0xbfb63f00, + 0xbfda3f00, + 0xbfff3f00, + 0xff003f00, + 0xff243f00, + 0xff483f00, + 0xff6d3f00, + 0xff913f00, + 0xffb63f00, + 0xffda3f00, + 0xffff3f00, + 0x00007f00, + 0x00247f00, + 0x00487f00, + 0x006d7f00, + 0x00917f00, + 0x00b67f00, + 0x00da7f00, + 0x00ff7f00, + 0x3f007f00, + 0x3f247f00, + 0x3f487f00, + 0x3f6d7f00, + 0x3f917f00, + 0x3fb67f00, + 0x3fda7f00, + 0x3fff7f00, + 0x7f007f00, + 0x7f247f00, + 0x7f487f00, + 0x7f6d7f00, + 0x7f917f00, + 0x7fb67f00, + 0x7fda7f00, + 0x7fff7f00, + 0xbf007f00, + 0xbf247f00, + 0xbf487f00, + 0xbf6d7f00, + 0xbf917f00, + 0xbfb67f00, + 0xbfda7f00, + 0xbfff7f00, + 0xff007f00, + 0xff247f00, + 0xff487f00, + 0xff6d7f00, + 0xff917f00, + 0xffb67f00, + 0xffda7f00, + 0xffff7f00, + 0x0000bf00, + 0x0024bf00, + 0x0048bf00, + 0x006dbf00, + 0x0091bf00, + 0x00b6bf00, + 0x00dabf00, + 0x00ffbf00, + 0x3f00bf00, + 0x3f24bf00, + 0x3f48bf00, + 0x3f6dbf00, + 0x3f91bf00, + 0x3fb6bf00, + 0x3fdabf00, + 0x3fffbf00, + 0x7f00bf00, + 0x7f24bf00, + 0x7f48bf00, + 0x7f6dbf00, + 0x7f91bf00, + 0x7fb6bf00, + 0x7fdabf00, + 0x7fffbf00, + 0xbf00bf00, + 0xbf24bf00, + 0xbf48bf00, + 0xbf6dbf00, + 0xbf91bf00, + 0xbfb6bf00, + 0xbfdabf00, + 0xbfffbf00, + 0xff00bf00, + 0xff24bf00, + 0xff48bf00, + 0xff6dbf00, + 0xff91bf00, + 0xffb6bf00, + 0xffdabf00, + 0xffffbf00, + 0x0000ff00, + 0x0024ff00, + 0x0048ff00, + 0x006dff00, + 0x0091ff00, + 0x00b6ff00, + 0x00daff00, + 0x00ffff00, + 0x3f00ff00, + 0x3f24ff00, + 0x3f48ff00, + 0x3f6dff00, + 0x3f91ff00, + 0x3fb6ff00, + 0x3fdaff00, + 0x3fffff00, + 0x7f00ff00, + 0x7f24ff00, + 0x7f48ff00, + 0x7f6dff00, + 0x7f91ff00, + 0x7fb6ff00, + 0x7fdaff00, + 0x7fffff00, + 0xbf00ff00, + 0xbf24ff00, + 0xbf48ff00, + 0xbf6dff00, + 0xbf91ff00, + 0xbfb6ff00, + 0xbfdaff00, + 0xbfffff00, + 0xff00ff00, + 0xff24ff00, + 0xff48ff00, + 0xff6dff00, + 0xff91ff00, + 0xffb6ff00, + 0xffdaff00, + 0xffffff00 diff --git a/plugins/zynaddsubfx/fltk/src/fl_color.cxx b/plugins/zynaddsubfx/fltk/src/fl_color.cxx new file mode 100644 index 000000000..63d576ec7 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_color.cxx @@ -0,0 +1,389 @@ +// +// "$Id: fl_color.cxx 5835 2007-05-16 11:46:07Z matt $" +// +// Color functions for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Implementation of fl_color(i), fl_color(r,g,b). + +#ifdef WIN32 +# include "fl_color_win32.cxx" +#elif defined(__APPLE__) +# include "fl_color_mac.cxx" +#else + +// Also code to look at the X visual and figure out the best way to turn +// a color into a pixel value. + +// SGI compiler seems to have problems with unsigned char arguments +// being used to index arrays. So I always copy them to an integer +// before use. + +# include "Fl_XColor.H" +# include +# include +# include + +//////////////////////////////////////////////////////////////// +// figure_out_visual() calculates masks & shifts for generating +// pixels in true-color visuals: + +uchar fl_redmask, fl_greenmask, fl_bluemask; +int fl_redshift, fl_greenshift, fl_blueshift, fl_extrashift; +static uchar beenhere; + +static void figure_out_visual() { + beenhere = 1; + if (!fl_visual->red_mask || !fl_visual->green_mask || !fl_visual->blue_mask){ +# if USE_COLORMAP + fl_redmask = 0; + return; +# else + Fl::fatal("Requires true color visual"); +# endif + } + + // get the bit masks into a more useful form: + int i,j,m; + + for (i = 0, m = 1; m; i++, m<<=1) if (fl_visual->red_mask & m) break; + for (j = i; m; j++, m<<=1) if (!(fl_visual->red_mask & m)) break; + fl_redshift = j-8; + fl_redmask = (j-i >= 8) ? 0xFF : 0xFF-(255>>(j-i)); + + for (i = 0, m = 1; m; i++, m<<=1) if (fl_visual->green_mask & m) break; + for (j = i; m; j++, m<<=1) if (!(fl_visual->green_mask & m)) break; + fl_greenshift = j-8; + fl_greenmask = (j-i >= 8) ? 0xFF : 0xFF-(255>>(j-i)); + + for (i = 0, m = 1; m; i++, m<<=1) if (fl_visual->blue_mask & m) break; + for (j = i; m; j++, m<<=1) if (!(fl_visual->blue_mask & m)) break; + fl_blueshift = j-8; + fl_bluemask = (j-i >= 8) ? 0xFF : 0xFF-(255>>(j-i)); + + i = fl_redshift; + if (fl_greenshift < i) i = fl_greenshift; + if (fl_blueshift < i) i = fl_blueshift; + if (i < 0) { + fl_extrashift = -i; + fl_redshift -= i; fl_greenshift -= i; fl_blueshift -= i; + } else + fl_extrashift = 0; + +} + +static unsigned fl_cmap[256] = { +#include "fl_cmap.h" // this is a file produced by "cmap.cxx": +}; + +# if HAVE_OVERLAY +Fl_XColor fl_xmap[2][256]; +uchar fl_overlay; +Colormap fl_overlay_colormap; +XVisualInfo* fl_overlay_visual; +ulong fl_transparent_pixel; +# else +Fl_XColor fl_xmap[1][256]; +# define fl_overlay 0 +# endif + +//////////////////////////////////////////////////////////////// +// Get an rgb color. This is easy for a truecolor visual. For +// colormapped it picks the closest color out of the cube in the +// fltk colormap. However if this color cube entry has been +// requested before, you will get the earlier requested color, and +// even this may be approximated if the X colormap was full. + +ulong fl_xpixel(uchar r,uchar g,uchar b) { + if (!beenhere) figure_out_visual(); +# if USE_COLORMAP + if (!fl_redmask) { + // find closest entry in the colormap: + Fl_Color i = + fl_color_cube(r*FL_NUM_RED/256,g*FL_NUM_GREEN/256,b*FL_NUM_BLUE/256); + Fl_XColor &xmap = fl_xmap[fl_overlay][i]; + if (xmap.mapped) return xmap.pixel; + // if not black or white, change the entry to be an exact match: + if (i != FL_COLOR_CUBE && i != 0xFF) + fl_cmap[i] = (r<<24)|(g<<16)|(b<<8); + return fl_xpixel(i); // allocate an X color + } +# endif + return + (((r&fl_redmask) << fl_redshift)+ + ((g&fl_greenmask)<> fl_extrashift; +} + +void fl_color(uchar r,uchar g,uchar b) { + fl_color_ = fl_rgb_color(r, g, b); + XSetForeground(fl_display, fl_gc, fl_xpixel(r,g,b)); +} + +//////////////////////////////////////////////////////////////// +// Get a color out of the the fltk colormap. Again for truecolor +// visuals this is easy. For colormap this actually tries to allocate +// an X color, and does a least-squares match to find the closest +// color if X cannot allocate that color. + +// calculate what color is actually on the screen for a mask: +static inline uchar realcolor(uchar color, uchar mask) { +# if 0 + // accurate version if the display has linear gamma, but fl_draw_image + // works better with the simpler version on most screens... + uchar m = mask; + uchar result = color&m; + for (;;) { + while (m&mask) {m>>=1; color>>=1;} + if (!m) break; + mask = m; + result |= color&m; + } + return result; +# else + return (color&mask) | (~mask)&(mask>>1); +# endif +} + +ulong fl_xpixel(Fl_Color i) { + if (i & 0xffffff00) { + return fl_xpixel((i >> 24) & 255, (i >> 16) & 255, (i >> 8) & 255); + } + + Fl_XColor &xmap = fl_xmap[fl_overlay][i]; + if (xmap.mapped) return xmap.pixel; + + if (!beenhere) figure_out_visual(); + + uchar r,g,b; + {unsigned c = fl_cmap[i]; r=uchar(c>>24); g=uchar(c>>16); b=uchar(c>>8);} + +# if USE_COLORMAP + Colormap colormap = fl_colormap; +# if HAVE_OVERLAY + if (fl_overlay) colormap = fl_overlay_colormap; else +# endif + if (fl_redmask) { +# endif + // return color for a truecolor visual: + xmap.mapped = 2; // 2 prevents XFreeColor from being called + xmap.r = realcolor(r, fl_redmask); + xmap.g = realcolor(g, fl_greenmask); + xmap.b = realcolor(b, fl_bluemask); + return xmap.pixel = + (((r&fl_redmask) << fl_redshift)+ + ((g&fl_greenmask)<> fl_extrashift; +# if USE_COLORMAP + } +# if HAVE_OVERLAY + static XColor* ac[2]; + XColor*& allcolors = ac[fl_overlay]; + static int nc[2]; + int& numcolors = nc[fl_overlay]; +# else + static XColor *allcolors; + static int numcolors; +# endif + + // I don't try to allocate colors with XAllocColor once it fails + // with any color. It is possible that it will work, since a color + // may have been freed, but some servers are extremely slow and this + // avoids one round trip: + if (!numcolors) { // don't try after a failure + XColor xcol; + xcol.red = r<<8; xcol.green = g<<8; xcol.blue = b<<8; + if (XAllocColor(fl_display, colormap, &xcol)) { + xmap.mapped = 1; + xmap.r = xcol.red>>8; + xmap.g = xcol.green>>8; + xmap.b = xcol.blue>>8; + return xmap.pixel = xcol.pixel; + } + + // I only read the colormap once. Again this is due to the slowness + // of round-trips to the X server, even though other programs may alter + // the colormap after this and make decisions here wrong. +# if HAVE_OVERLAY + if (fl_overlay) numcolors = fl_overlay_visual->colormap_size; else +# endif + numcolors = fl_visual->colormap_size; + if (!allcolors) allcolors = new XColor[numcolors]; + for (int p = numcolors; p--;) allcolors[p].pixel = p; + XQueryColors(fl_display, colormap, allcolors, numcolors); + } + + // find least-squares match: + int mindist = 0x7FFFFFFF; + unsigned int bestmatch = 0; + for (unsigned int n = numcolors; n--;) { +# if HAVE_OVERLAY + if (fl_overlay && n == fl_transparent_pixel) continue; +# endif + XColor &a = allcolors[n]; + int d, t; + t = int(r)-int(a.red>>8); d = t*t; + t = int(g)-int(a.green>>8); d += t*t; + t = int(b)-int(a.blue>>8); d += t*t; + if (d <= mindist) {bestmatch = n; mindist = d;} + } + XColor &p = allcolors[bestmatch]; + + // It appears to "work" to not call this XAllocColor, which will + // avoid another round-trip to the server. But then X does not + // know that this program "owns" this value, and can (and will) + // change it when the program that did allocate it exits: + if (XAllocColor(fl_display, colormap, &p)) { + xmap.mapped = 1; + xmap.pixel = p.pixel; + } else { + // However, if that XAllocColor fails, I have to give up and + // assumme the pixel is ok for the duration of the program. This + // is due to bugs (?) in the Solaris X and some X terminals + // where XAllocColor *always* fails when the colormap is full, + // even if we ask for a color already in it... + xmap.mapped = 2; // 2 prevents XFreeColor from being called + xmap.pixel = bestmatch; + } + xmap.r = p.red>>8; + xmap.g = p.green>>8; + xmap.b = p.blue>>8; + return xmap.pixel; +# endif +} + +Fl_Color fl_color_; + +void fl_color(Fl_Color i) { + if (i & 0xffffff00) { + unsigned rgb = (unsigned)i; + fl_color((uchar)(rgb >> 24), (uchar)(rgb >> 16), (uchar)(rgb >> 8)); + } else { + fl_color_ = i; + XSetForeground(fl_display, fl_gc, fl_xpixel(i)); + } +} + +void Fl::free_color(Fl_Color i, int overlay) { +# if HAVE_OVERLAY +# else + if (overlay) return; +# endif + if (fl_xmap[overlay][i].mapped) { +# if USE_COLORMAP +# if HAVE_OVERLAY + Colormap colormap = overlay ? fl_overlay_colormap : fl_colormap; +# else + Colormap colormap = fl_colormap; +# endif + if (fl_xmap[overlay][i].mapped == 1) + XFreeColors(fl_display, colormap, &(fl_xmap[overlay][i].pixel), 1, 0); +# endif + fl_xmap[overlay][i].mapped = 0; + } +} + +void Fl::set_color(Fl_Color i, unsigned c) { + if (fl_cmap[i] != c) { + free_color(i,0); +# if HAVE_OVERLAY + free_color(i,1); +# endif + fl_cmap[i] = c; + } +} + +#endif // end of X-specific code + +unsigned Fl::get_color(Fl_Color i) { + if (i & 0xffffff00) return (i); + else return fl_cmap[i]; +} + +void Fl::set_color(Fl_Color i, uchar red, uchar green, uchar blue) { + Fl::set_color((Fl_Color)(i & 255), + ((unsigned)red<<24)+((unsigned)green<<16)+((unsigned)blue<<8)); +} + +void Fl::get_color(Fl_Color i, uchar &red, uchar &green, uchar &blue) { + unsigned c; + + if (i & 0xffffff00) c = (unsigned)i; + else c = fl_cmap[i]; + + red = uchar(c>>24); + green = uchar(c>>16); + blue = uchar(c>>8); +} + +Fl_Color fl_color_average(Fl_Color color1, Fl_Color color2, float weight) { + unsigned rgb1; + unsigned rgb2; + uchar r, g, b; + + if (color1 & 0xffffff00) rgb1 = color1; + else rgb1 = fl_cmap[color1 & 255]; + + if (color2 & 0xffffff00) rgb2 = color2; + else rgb2 = fl_cmap[color2 & 255]; + + r = (uchar)(((uchar)(rgb1>>24))*weight + ((uchar)(rgb2>>24))*(1-weight)); + g = (uchar)(((uchar)(rgb1>>16))*weight + ((uchar)(rgb2>>16))*(1-weight)); + b = (uchar)(((uchar)(rgb1>>8))*weight + ((uchar)(rgb2>>8))*(1-weight)); + + return fl_rgb_color(r, g, b); +} + +Fl_Color fl_inactive(Fl_Color c) { + return fl_color_average(c, FL_GRAY, .33f); +} + +Fl_Color fl_contrast(Fl_Color fg, Fl_Color bg) { + unsigned c1, c2; // RGB colors + int l1, l2; // Luminosities + + + // Get the RGB values for each color... + if (fg & 0xffffff00) c1 = (unsigned)fg; + else c1 = fl_cmap[fg]; + + if (bg & 0xffffff00) c2 = (unsigned)bg; + else c2 = fl_cmap[bg]; + + // Compute the luminosity... + l1 = ((c1 >> 24) * 30 + ((c1 >> 16) & 255) * 59 + ((c1 >> 8) & 255) * 11) / 100; + l2 = ((c2 >> 24) * 30 + ((c2 >> 16) & 255) * 59 + ((c2 >> 8) & 255) * 11) / 100; + + // Compare and return the contrasting color... + if ((l1 - l2) > 99) return fg; + else if ((l2 - l1) > 99) return fg; + else if (l2 > 127) return FL_BLACK; + else return FL_WHITE; +} + +// +// End of "$Id: fl_color.cxx 5835 2007-05-16 11:46:07Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_color_mac.cxx b/plugins/zynaddsubfx/fltk/src/fl_color_mac.cxx new file mode 100644 index 000000000..024528695 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_color_mac.cxx @@ -0,0 +1,114 @@ +// +// "$Id: fl_color_mac.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// MacOS color functions for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// The fltk "colormap". This allows ui colors to be stored in 8-bit +// locations, and provides a level of indirection so that global color +// changes can be made. Not to be confused with the X colormap, which +// I try to hide completely. + +// matt: Neither Quartz nor Quickdraw support colormaps in this implementation +// matt: Quartz support done + +#include +#include +#include +#include + +static unsigned fl_cmap[256] = { +#include "fl_cmap.h" // this is a file produced by "cmap.cxx": +}; + +// Translations to mac data structures: +Fl_XMap fl_xmap[256]; + +Fl_XMap* fl_current_xmap; + +Fl_Color fl_color_; + +void fl_color(Fl_Color i) { + fl_color_ = i; + int index; + uchar r, g, b; + if (i & 0xFFFFFF00) { + // translate rgb colors into color index + r = i>>24; + g = i>>16; + b = i>> 8; + } else { + // translate index into rgb: + index = i; + unsigned c = fl_cmap[i]; + r = c>>24; + g = c>>16; + b = c>> 8; + } +#ifdef __APPLE_QD__ + RGBColor rgb; + rgb.red = (r<<8)|r; + rgb.green = (g<<8)|g; + rgb.blue = (b<<8)|b; + RGBForeColor(&rgb); +#elif defined(__APPLE_QUARTZ__) + if (!fl_gc) return; // no context yet? We will assign the color later. + float fr = r/255.0f; + float fg = g/255.0f; + float fb = b/255.0f; + CGContextSetRGBFillColor(fl_gc, fr, fg, fb, 1.0f); + CGContextSetRGBStrokeColor(fl_gc, fr, fg, fb, 1.0f); +#else +# error : neither Quickdraw nor Quartz defined +#endif +} + +void fl_color(uchar r, uchar g, uchar b) { + fl_color_ = fl_rgb_color(r, g, b); +#ifdef __APPLE_QD__ + RGBColor rgb; + rgb.red = (r<<8)|r; + rgb.green = (g<<8)|g; + rgb.blue = (b<<8)|b; + RGBForeColor(&rgb); +#elif defined(__APPLE_QUARTZ__) + float fr = r/255.0f; + float fg = g/255.0f; + float fb = b/255.0f; + CGContextSetRGBFillColor(fl_gc, fr, fg, fb, 1.0f); + CGContextSetRGBStrokeColor(fl_gc, fr, fg, fb, 1.0f); +#else +# error : neither Quickdraw nor Quartz defined +#endif +} + +void Fl::set_color(Fl_Color i, unsigned c) { + if (fl_cmap[i] != c) { + fl_cmap[i] = c; + } +} + +// +// End of "$Id: fl_color_mac.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_color_win32.cxx b/plugins/zynaddsubfx/fltk/src/fl_color_win32.cxx new file mode 100644 index 000000000..315c39346 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_color_win32.cxx @@ -0,0 +1,254 @@ +// +// "$Id: fl_color_win32.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// WIN32 color functions for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// The fltk "colormap". This allows ui colors to be stored in 8-bit +// locations, and provides a level of indirection so that global color +// changes can be made. Not to be confused with the X colormap, which +// I try to hide completely. + +// SGI compiler seems to have problems with unsigned char arguments +// being used to index arrays. So I always copy them to an integer +// before use. + +#include +#include +#include +#include + +static unsigned fl_cmap[256] = { +#include "fl_cmap.h" // this is a file produced by "cmap.cxx": +}; + +// Translations to win32 data structures: +Fl_XMap fl_xmap[256]; + +Fl_XMap* fl_current_xmap; + +HPALETTE fl_palette; +static HGDIOBJ tmppen=0; +static HPEN savepen=0; + +void fl_cleanup_pens(void) { + for (int i=0; i<256; i++) { + if (fl_xmap[i].pen) DeleteObject(fl_xmap[i].pen); + } +} + +void fl_save_pen(void) { + if(!tmppen) tmppen = CreatePen(PS_SOLID, 1, 0); + savepen = (HPEN)SelectObject(fl_gc, tmppen); +} + +void fl_restore_pen(void) { + if (savepen) SelectObject(fl_gc, savepen); + DeleteObject(tmppen); + tmppen = 0; + savepen = 0; +} + +static void clear_xmap(Fl_XMap& xmap) { + if (xmap.pen) { + HGDIOBJ tmppen = GetStockObject(BLACK_PEN); + HGDIOBJ oldpen = SelectObject(fl_gc, tmppen); // Push out the current pen of the gc + if(oldpen != xmap.pen) SelectObject(fl_gc, oldpen); // Put it back if it is not the one we are about to delete + DeleteObject((HGDIOBJ)(xmap.pen)); + xmap.pen = 0; + xmap.brush = -1; + } +} + +static void set_xmap(Fl_XMap& xmap, COLORREF c) { + xmap.rgb = c; + if (xmap.pen) { + HGDIOBJ oldpen = SelectObject(fl_gc,GetStockObject(BLACK_PEN)); // replace current pen with safe one + if (oldpen != xmap.pen)SelectObject(fl_gc,oldpen); // if old one not xmap.pen, need to put it back + DeleteObject(xmap.pen); // delete pen + } + xmap.pen = CreatePen(PS_SOLID, 1, xmap.rgb); // get a pen into xmap.pen + xmap.brush = -1; +} + +Fl_Color fl_color_; + +void fl_color(Fl_Color i) { + if (i & 0xffffff00) { + unsigned rgb = (unsigned)i; + fl_color((uchar)(rgb >> 24), (uchar)(rgb >> 16), (uchar)(rgb >> 8)); + } else { + fl_color_ = i; + Fl_XMap &xmap = fl_xmap[i]; + if (!xmap.pen) { +#if USE_COLORMAP + if (fl_palette) { + set_xmap(xmap, PALETTEINDEX(i)); + } else { +#endif + unsigned c = fl_cmap[i]; + set_xmap(xmap, RGB(uchar(c>>24), uchar(c>>16), uchar(c>>8))); +#if USE_COLORMAP + } +#endif + } + fl_current_xmap = ⟼ + SelectObject(fl_gc, (HGDIOBJ)(xmap.pen)); + } +} + +void fl_color(uchar r, uchar g, uchar b) { + static Fl_XMap xmap; + COLORREF c = RGB(r,g,b); + fl_color_ = fl_rgb_color(r, g, b); + if (!xmap.pen || c != xmap.rgb) { + clear_xmap(xmap); + set_xmap(xmap, c); + } + fl_current_xmap = ⟼ + SelectObject(fl_gc, (HGDIOBJ)(xmap.pen)); +} + +HBRUSH fl_brush() { + return fl_brush_action(0); +} + +HBRUSH fl_brush_action(int action) { + Fl_XMap *xmap = fl_current_xmap; + // Wonko: we use some statistics to cache only a limited number + // of brushes: +#define FL_N_BRUSH 16 + static struct Fl_Brush { + HBRUSH brush; + unsigned short usage; + Fl_XMap* backref; + } brushes[FL_N_BRUSH]; + + if (action) { + SelectObject(fl_gc, GetStockObject(BLACK_BRUSH)); // Load stock object + for (int i=0; ibrush; // find the associated brush + if (i != -1) { // if the brush was allready allocated + if (brushes[i].brush == NULL) goto CREATE_BRUSH; + if ( (++brushes[i].usage) > 32000 ) { // keep a usage statistic + for (int j=0; j16000) + brushes[j].usage -= 16000; + else + brushes[j].usage = 0; + } + } + return brushes[i].brush; + } else { + int umin = 32000, imin = 0; + for (i=0; ibrush = -1; + } +CREATE_BRUSH: + brushes[i].brush = CreateSolidBrush(xmap->rgb); + brushes[i].usage = 0; + brushes[i].backref = xmap; + xmap->brush = i; + return brushes[i].brush; +} + +void Fl::free_color(Fl_Color i, int overlay) { + if (overlay) return; // do something about GL overlay? + clear_xmap(fl_xmap[i]); +} + +void Fl::set_color(Fl_Color i, unsigned c) { + if (fl_cmap[i] != c) { + clear_xmap(fl_xmap[i]); + fl_cmap[i] = c; + } +} + +#if USE_COLORMAP + +// 'fl_select_palette()' - Make a color palette for 8-bit displays if necessary +// Thanks to Michael Sweet @ Easy Software Products for this + +HPALETTE +fl_select_palette(void) +{ + static char beenhere; + if (!beenhere) { + beenhere = 1; + + //if (GetDeviceCaps(fl_gc, BITSPIXEL) > 8) return NULL; + int nColors = GetDeviceCaps(fl_gc, SIZEPALETTE); + if (nColors <= 0 || nColors > 256) return NULL; + // this will try to work on < 256 color screens, but will probably + // come out quite badly. + + // I lamely try to get this variable-sized object allocated on stack: + ulong foo[(sizeof(LOGPALETTE)+256*sizeof(PALETTEENTRY))/sizeof(ulong)+1]; + LOGPALETTE *pPal = (LOGPALETTE*)foo; + + pPal->palVersion = 0x300; + pPal->palNumEntries = nColors; + + // Build 256 colors from the standard FLTK colormap... + + for (int i = 0; i < nColors; i ++) { + pPal->palPalEntry[i].peRed = (fl_cmap[i] >> 24) & 255; + pPal->palPalEntry[i].peGreen = (fl_cmap[i] >> 16) & 255; + pPal->palPalEntry[i].peBlue = (fl_cmap[i] >> 8) & 255; + pPal->palPalEntry[i].peFlags = 0; + }; + + // Create the palette: + fl_palette = CreatePalette(pPal); + } + if (fl_palette) { + SelectPalette(fl_gc, fl_palette, FALSE); + RealizePalette(fl_gc); + } + return fl_palette; +} + +#endif + +// +// End of "$Id: fl_color_win32.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_cursor.cxx b/plugins/zynaddsubfx/fltk/src/fl_cursor.cxx new file mode 100644 index 000000000..73092d62b --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_cursor.cxx @@ -0,0 +1,335 @@ +// +// "$Id: fl_cursor.cxx 5654 2007-02-02 13:52:37Z matt $" +// +// Mouse cursor support for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Change the current cursor. +// Under X the cursor is attached to the X window. I tried to hide +// this and pretend that changing the cursor is a drawing function. +// This avoids a field in the Fl_Window, and I suspect is more +// portable to other systems. + +#include +#include +#include +#if !defined(WIN32) && !defined(__APPLE__) +# include +#endif +#include + +void fl_cursor(Fl_Cursor c, Fl_Color fg, Fl_Color bg) { + if (Fl::first_window()) Fl::first_window()->cursor(c,fg,bg); +} + +void Fl_Window::default_cursor(Fl_Cursor c, Fl_Color fg, Fl_Color bg) { +// if (c == FL_CURSOR_DEFAULT) c = FL_CURSOR_ARROW; + + cursor_default = c; + cursor_fg = fg; + cursor_bg = bg; + + cursor(c, fg, bg); +} + +#ifdef WIN32 + +# ifndef IDC_HAND +# define IDC_HAND MAKEINTRESOURCE(32649) +# endif // !IDC_HAND + +void Fl_Window::cursor(Fl_Cursor c, Fl_Color c1, Fl_Color c2) { + if (!shown()) return; + // the cursor must be set for the top level window, not for subwindows + Fl_Window *w = window(), *toplevel = this; + while (w) { toplevel = w; w = w->window(); } + if (toplevel != this) { toplevel->cursor(c, c1, c2); return; } + // now set the actual cursor + if (c == FL_CURSOR_DEFAULT) { + c = cursor_default; + } + if (c > FL_CURSOR_NESW) { + i->cursor = 0; + } else if (c == FL_CURSOR_DEFAULT) { + i->cursor = fl_default_cursor; + } else { + LPSTR n; + switch (c) { + case FL_CURSOR_ARROW: n = IDC_ARROW; break; + case FL_CURSOR_CROSS: n = IDC_CROSS; break; + case FL_CURSOR_WAIT: n = IDC_WAIT; break; + case FL_CURSOR_INSERT: n = IDC_IBEAM; break; + case FL_CURSOR_HELP: n = IDC_HELP; break; + case FL_CURSOR_HAND: { + OSVERSIONINFO osvi; + + // Get the OS version: Windows 98 and 2000 have a standard + // hand cursor. + memset(&osvi, 0, sizeof(OSVERSIONINFO)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&osvi); + + if (osvi.dwMajorVersion > 4 || + (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion > 0 && + osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)) n = IDC_HAND; + else n = IDC_UPARROW; + } break; + case FL_CURSOR_MOVE: n = IDC_SIZEALL; break; + case FL_CURSOR_N: + case FL_CURSOR_S: + case FL_CURSOR_NS: n = IDC_SIZENS; break; + case FL_CURSOR_NE: + case FL_CURSOR_SW: + case FL_CURSOR_NESW: n = IDC_SIZENESW; break; + case FL_CURSOR_E: + case FL_CURSOR_W: + case FL_CURSOR_WE: n = IDC_SIZEWE; break; + case FL_CURSOR_SE: + case FL_CURSOR_NW: + case FL_CURSOR_NWSE: n = IDC_SIZENWSE; break; + default: n = IDC_NO; break; + } + i->cursor = LoadCursor(NULL, n); + } + SetCursor(i->cursor); +} + +#elif defined(__APPLE__) + +#ifdef __BIG_ENDIAN__ +# define E(x) x +#elif defined __LITTLE_ENDIAN__ +// Don't worry. This will be resolved at compile time +# define E(x) (x>>8)|((x<<8)&0xff00) +#else +# error "Either __LITTLE_ENDIAN__ or __BIG_ENDIAN__ must be defined" +#endif + +static Cursor crsrHAND = +{ + { E(0x0600), E(0x0900), E(0x0900), E(0x0900), E(0x09C0), E(0x0938), E(0x6926), E(0x9805), + E(0x8801), E(0x4801), E(0x2002), E(0x2002), E(0x1004), E(0x0804), E(0x0408), E(0x0408) }, + { E(0x0600), E(0x0F00), E(0x0F00), E(0x0F00), E(0x0FC0), E(0x0FF8), E(0x6FFE), E(0xFFFF), + E(0xFFFF), E(0x7FFF), E(0x3FFE), E(0x3FFE), E(0x1FFC), E(0x0FFC), E(0x07F8), E(0x07F8) }, + { 1, 5 } // Hotspot: ( y, x ) +}, *crsrHANDptr = &crsrHAND; +static Cursor crsrHELP = +{ + { E(0x0000), E(0x4000), E(0x6000), E(0x7000), E(0x783C), E(0x7C7E), E(0x7E66), E(0x7F06), + E(0x7F8C), E(0x7C18), E(0x6C18), E(0x4600), E(0x0618), E(0x0318), E(0x0300), E(0x0000) }, + { E(0xC000), E(0xE000), E(0xF000), E(0xF83C), E(0xFC7E), E(0xFEFF), E(0xFFFF), E(0xFFFF), + E(0xFFFE), E(0xFFFC), E(0xFE3C), E(0xEF3C), E(0xCF3C), E(0x07BC), E(0x0798), E(0x0380) }, + { 1, 1 } +}, *crsrHELPptr = &crsrHELP; +static Cursor crsrMOVE = +{ + { E(0x0000), E(0x0180), E(0x03C0), E(0x07E0), E(0x07E0), E(0x1998), E(0x399C), E(0x7FFE), + E(0x7FFE), E(0x399C), E(0x1998), E(0x07E0), E(0x07E0), E(0x03C0), E(0x0180), E(0x0000) }, + { E(0x0180), E(0x03C0), E(0x07E0), E(0x0FF0), E(0x1FF8), E(0x3FFC), E(0x7FFE), E(0xFFFF), + E(0xFFFF), E(0x7FFE), E(0x3FFC), E(0x1FF8), E(0x0FF0), E(0x07E0), E(0x03C0), E(0x0180) }, + { 8, 8 } +}, *crsrMOVEptr = &crsrMOVE; +static Cursor crsrNS = +{ + { E(0x0000), E(0x0180), E(0x03C0), E(0x07E0), E(0x0FF0), E(0x0180), E(0x0180), E(0x0180), + E(0x0180), E(0x0180), E(0x0180), E(0x0FF0), E(0x07E0), E(0x03C0), E(0x0180), E(0x0000) }, + { E(0x0180), E(0x03C0), E(0x07E0), E(0x0FF0), E(0x1FF8), E(0x1FF8), E(0x03C0), E(0x03C0), + E(0x03C0), E(0x03C0), E(0x1FF8), E(0x1FF8), E(0x0FF0), E(0x07E0), E(0x03C0), E(0x0180) }, + { 8, 8 } +}, *crsrNSptr = &crsrNS; +static Cursor crsrWE = +{ + { E(0x0000), E(0x0000), E(0x0000), E(0x0000), E(0x0810), E(0x1818), E(0x381C), E(0x7FFE), + E(0x7FFE), E(0x381C), E(0x1818), E(0x0810), E(0x0000), E(0x0000), E(0x0000), E(0x0000) }, + { E(0x0000), E(0x0000), E(0x0000), E(0x0C30), E(0x1C38), E(0x3C3C), E(0x7FFE), E(0xFFFF), + E(0xFFFF), E(0x7FFE), E(0x3C3C), E(0x1C38), E(0x0C30), E(0x0000), E(0x0000), E(0x0000) }, + { 8, 8 } +}, *crsrWEptr = &crsrWE; +static Cursor crsrNWSE = +{ + { E(0x0000), E(0x7E00), E(0x7C00), E(0x7800), E(0x7C00), E(0x6E00), E(0x4710), E(0x03B0), + E(0x01F0), E(0x00F0), E(0x01F0), E(0x03F0), E(0x0000), E(0x0000), E(0x0000), E(0x0000) }, + { E(0xFF00), E(0xFF00), E(0xFE00), E(0xFC00), E(0xFE00), E(0xFF18), E(0xEFB8), E(0xC7F8), + E(0x03F8), E(0x01F8), E(0x03F8), E(0x07F8), E(0x07F8), E(0x0000), E(0x0000), E(0x0000) }, + { 8, 8 } +}, *crsrNWSEptr = &crsrNWSE; +static Cursor crsrNESW = +{ + { E(0x0000), E(0x03F0), E(0x01F0), E(0x00F0), E(0x01F0), E(0x03B0), E(0x4710), E(0x6E00), + E(0x7C00), E(0x7800), E(0x7C00), E(0x7E00), E(0x0000), E(0x0000), E(0x0000), E(0x0000) }, + { E(0x07F8), E(0x07F8), E(0x03F8), E(0x01F8), E(0x03F8), E(0xC7F8), E(0xEFB8), E(0xFF18), + E(0xFE00), E(0xFC00), E(0xFE00), E(0xFF00), E(0xFF00), E(0x0000), E(0x0000), E(0x0000) }, + { 8, 8 } +}, *crsrNESWptr = &crsrNESW; +static Cursor crsrNONE = +{ + { E(0x0000), E(0x0000), E(0x0000), E(0x0000), E(0x0000), E(0x0000), E(0x0000), E(0x0000), + E(0x0000), E(0x0000), E(0x0000), E(0x0000), E(0x0000), E(0x0000), E(0x0000), E(0x0000) }, + { E(0x0000), E(0x0000), E(0x0000), E(0x0000), E(0x0000), E(0x0000), E(0x0000), E(0x0000), + E(0x0000), E(0x0000), E(0x0000), E(0x0000), E(0x0000), E(0x0000), E(0x0000), E(0x0000) }, + { 0, 0 } +}, *crsrNONEptr = &crsrNONE; +static Cursor crsrARROW = +{ + { E(0x0000), E(0x4000), E(0x6000), E(0x7000), E(0x7800), E(0x7C00), E(0x7E00), E(0x7F00), + E(0x7F80), E(0x7C00), E(0x6C00), E(0x4600), E(0x0600), E(0x0300), E(0x0300), E(0x0000) }, + { E(0xC000), E(0xE000), E(0xF000), E(0xF800), E(0xFC00), E(0xFE00), E(0xFF00), E(0xFF80), + E(0xFFC0), E(0xFFC0), E(0xFE00), E(0xEF00), E(0xCF00), E(0x0780), E(0x0780), E(0x0380) }, + { 1, 1 } +}, *crsrARROWptr = &crsrARROW; + +#undef E + +void Fl_Window::cursor(Fl_Cursor c, Fl_Color, Fl_Color) { + if (c == FL_CURSOR_DEFAULT) { + c = cursor_default; + } + CursHandle icrsr = fl_default_cursor; + switch (c) { + case FL_CURSOR_CROSS: icrsr = GetCursor( crossCursor ); break; + case FL_CURSOR_WAIT: icrsr = GetCursor( watchCursor ); break; + case FL_CURSOR_INSERT: icrsr = GetCursor( iBeamCursor ); break; + case FL_CURSOR_N: + case FL_CURSOR_S: + case FL_CURSOR_NS: icrsr = &crsrNSptr; break; + case FL_CURSOR_HELP: icrsr = &crsrHELPptr; break; + case FL_CURSOR_HAND: icrsr = &crsrHANDptr; break; + case FL_CURSOR_MOVE: icrsr = &crsrMOVEptr; break; + case FL_CURSOR_NE: + case FL_CURSOR_SW: + case FL_CURSOR_NESW: icrsr = &crsrNESWptr; break; + case FL_CURSOR_E: + case FL_CURSOR_W: + case FL_CURSOR_WE: icrsr = &crsrWEptr; break; + case FL_CURSOR_SE: + case FL_CURSOR_NW: + case FL_CURSOR_NWSE: icrsr = &crsrNWSEptr; break; + case FL_CURSOR_NONE: icrsr = &crsrNONEptr; break; + case FL_CURSOR_ARROW: icrsr = &crsrARROWptr; break; + case FL_CURSOR_DEFAULT: + default: break; + } + SetCursor( *icrsr ); + if (i) { + i->cursor = icrsr; + } +} + +#else + +// I like the MSWindows resize cursors, so I duplicate them here: + +#define CURSORSIZE 16 +#define HOTXY 7 +static struct TableEntry { + uchar bits[CURSORSIZE*CURSORSIZE/8]; + uchar mask[CURSORSIZE*CURSORSIZE/8]; + Cursor cursor; +} table[] = { + {{ // FL_CURSOR_NS + 0x00, 0x00, 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0x80, 0x01, 0x80, 0x01, + 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, + 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01, 0x00, 0x00}, + { + 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f, 0xf0, 0x0f, 0xc0, 0x03, + 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xf0, 0x0f, + 0xf0, 0x0f, 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01}}, + {{ // FL_CURSOR_EW + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, + 0x0c, 0x30, 0xfe, 0x7f, 0xfe, 0x7f, 0x0c, 0x30, 0x08, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x1c, 0x38, + 0xfe, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0x1c, 0x38, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, + {{ // FL_CURSOR_NWSE + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x38, 0x00, 0x78, 0x00, + 0xe8, 0x00, 0xc0, 0x01, 0x80, 0x03, 0x00, 0x17, 0x00, 0x1e, 0x00, 0x1c, + 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + { + 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0x7c, 0x00, 0xfc, 0x00, + 0xfc, 0x01, 0xec, 0x03, 0xc0, 0x37, 0x80, 0x3f, 0x00, 0x3f, 0x00, 0x3e, + 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00}}, + {{ // FL_CURSOR_NESW + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x1c, 0x00, 0x1e, + 0x00, 0x17, 0x80, 0x03, 0xc0, 0x01, 0xe8, 0x00, 0x78, 0x00, 0x38, 0x00, + 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3e, 0x00, 0x3f, + 0x80, 0x3f, 0xc0, 0x37, 0xec, 0x03, 0xfc, 0x01, 0xfc, 0x00, 0x7c, 0x00, + 0xfc, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00}}, + {{0}, {0}} // FL_CURSOR_NONE & unknown +}; + +void Fl_Window::cursor(Fl_Cursor c, Fl_Color fg, Fl_Color bg) { + if (!shown()) return; + Cursor xc; + int deleteit = 0; + if (c == FL_CURSOR_DEFAULT) { + c = cursor_default; + fg = cursor_fg; + bg = cursor_bg; + } + + if (!c) { + xc = None; + } else { + if (c >= FL_CURSOR_NS) { + TableEntry *q = (c > FL_CURSOR_NESW) ? table+4 : table+(c-FL_CURSOR_NS); + if (!(q->cursor)) { + XColor dummy = { 0 }; + Pixmap p = XCreateBitmapFromData(fl_display, + RootWindow(fl_display, fl_screen), (const char*)(q->bits), + CURSORSIZE, CURSORSIZE); + Pixmap m = XCreateBitmapFromData(fl_display, + RootWindow(fl_display, fl_screen), (const char*)(q->mask), + CURSORSIZE, CURSORSIZE); + q->cursor = XCreatePixmapCursor(fl_display, p,m,&dummy, &dummy, + HOTXY, HOTXY); + XFreePixmap(fl_display, m); + XFreePixmap(fl_display, p); + } + xc = q->cursor; + } else { + xc = XCreateFontCursor(fl_display, (c-1)*2); + deleteit = 1; + } + XColor fgc; + uchar r,g,b; + Fl::get_color(fg,r,g,b); + fgc.red = r<<8; fgc.green = g<<8; fgc.blue = b<<8; + XColor bgc; + Fl::get_color(bg,r,g,b); + bgc.red = r<<8; bgc.green = g<<8; bgc.blue = b<<8; + XRecolorCursor(fl_display, xc, &fgc, &bgc); + } + XDefineCursor(fl_display, fl_xid(this), xc); + if (deleteit) XFreeCursor(fl_display, xc); +} + +#endif + +// +// End of "$Id: fl_cursor.cxx 5654 2007-02-02 13:52:37Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_curve.cxx b/plugins/zynaddsubfx/fltk/src/fl_curve.cxx new file mode 100644 index 000000000..112586d60 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_curve.cxx @@ -0,0 +1,106 @@ +// +// "$Id: fl_curve.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Bezier curve functions for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Utility for drawing Bezier curves, adding the points to +// the current fl_begin/fl_vertex/fl_end path. +// Incremental math implementation: +// I very much doubt this is optimal! From Foley/vanDam page 511. +// If anybody has a better algorithim, please send it! + +#include +#include + +void fl_curve(double X0, double Y0, + double X1, double Y1, + double X2, double Y2, + double X3, double Y3) { + + double x = fl_transform_x(X0,Y0); + double y = fl_transform_y(X0,Y0); + + // draw point 0: + fl_transformed_vertex(x,y); + + double x1 = fl_transform_x(X1,Y1); + double yy1 = fl_transform_y(X1,Y1); + double x2 = fl_transform_x(X2,Y2); + double y2 = fl_transform_y(X2,Y2); + double x3 = fl_transform_x(X3,Y3); + double y3 = fl_transform_y(X3,Y3); + + // find the area: + double a = fabs((x-x2)*(y3-yy1)-(y-y2)*(x3-x1)); + double b = fabs((x-x3)*(y2-yy1)-(y-y3)*(x2-x1)); + if (b > a) a = b; + + // use that to guess at the number of segments: + int n = int(sqrt(a)/4); + if (n > 1) { + if (n > 100) n = 100; // make huge curves not hang forever + + double e = 1.0/n; + + // calculate the coefficients of 3rd order equation: + double xa = (x3-3*x2+3*x1-x); + double xb = 3*(x2-2*x1+x); + double xc = 3*(x1-x); + // calculate the forward differences: + double dx1 = ((xa*e+xb)*e+xc)*e; + double dx3 = 6*xa*e*e*e; + double dx2 = dx3 + 2*xb*e*e; + + // calculate the coefficients of 3rd order equation: + double ya = (y3-3*y2+3*yy1-y); + double yb = 3*(y2-2*yy1+y); + double yc = 3*(yy1-y); + // calculate the forward differences: + double dy1 = ((ya*e+yb)*e+yc)*e; + double dy3 = 6*ya*e*e*e; + double dy2 = dy3 + 2*yb*e*e; + + // draw points 1 .. n-2: + for (int m=2; m +#include + +extern uchar* fl_gray_ramp(); + +static void fl_diamond_up_box(int x,int y,int w,int h,Fl_Color bgcolor) { + w &= -2; + h &= -2; + int x1 = x+w/2; + int y1 = y+h/2; + fl_color(bgcolor); fl_polygon(x+3, y1, x1,y+3, x+w-3,y1, x1,y+h-3); + uchar *g = fl_gray_ramp(); + fl_color(g['W']); fl_line(x+1, y1, x1, y+1, x+w-1, y1); + fl_color(g['U']); fl_line(x+2, y1, x1, y+2, x+w-2, y1); + fl_color(g['S']); fl_line(x+3, y1, x1, y+3, x+w-3, y1); + fl_color(g['P']); fl_line(x+3, y1, x1, y+h-3, x+w-3, y1); + fl_color(g['N']); fl_line(x+2, y1, x1, y+h-2, x+w-2, y1); + fl_color(g['H']); fl_line(x+1, y1, x1, y+h-1, x+w-1, y1); + fl_color(g['A']); fl_loop(x, y1, x1, y, x+w, y1, x1, y+h); +} + +static void fl_diamond_down_box(int x,int y,int w,int h,Fl_Color bgcolor) { + w &= -2; + h &= -2; + int x1 = x+w/2; + int y1 = y+h/2; + uchar *g = fl_gray_ramp(); + fl_color(g['P']); fl_line(x+0, y1, x1, y+0, x+w-0, y1); + fl_color(g['N']); fl_line(x+1, y1, x1, y+1, x+w-1, y1); + fl_color(g['H']); fl_line(x+2, y1, x1, y+2, x+w-2, y1); + fl_color(g['W']); fl_line(x+2, y1, x1, y+h-2, x+w-2, y1); + fl_color(g['U']); fl_line(x+1, y1, x1, y+h-1, x+w-1, y1); + fl_color(g['S']); fl_line(x+0, y1, x1, y+h-0, x+w-0, y1); + fl_color(bgcolor); fl_polygon(x+3, y1, x1,y+3, x+w-3,y1, x1,y+h-3); + fl_color(g['A']); fl_loop(x+3, y1, x1, y+3, x+w-3, y1, x1, y+h-3); +} + +extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*); +Fl_Boxtype fl_define_FL_DIAMOND_BOX() { + fl_internal_boxtype(_FL_DIAMOND_DOWN_BOX, fl_diamond_down_box); + fl_internal_boxtype(_FL_DIAMOND_UP_BOX,fl_diamond_up_box); + return _FL_DIAMOND_UP_BOX; +} + +// +// End of "$Id: fl_diamond_box.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_dnd.cxx b/plugins/zynaddsubfx/fltk/src/fl_dnd.cxx new file mode 100644 index 000000000..cff489856 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_dnd.cxx @@ -0,0 +1,38 @@ +// +// "$Id: fl_dnd.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Drag & Drop code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#ifdef WIN32 +# include "fl_dnd_win32.cxx" +#elif defined(__APPLE__) +# include "fl_dnd_mac.cxx" +#else +# include "fl_dnd_x.cxx" +#endif + +// +// End of "$Id: fl_dnd.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_dnd_mac.cxx b/plugins/zynaddsubfx/fltk/src/fl_dnd_mac.cxx new file mode 100644 index 000000000..39809c373 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_dnd_mac.cxx @@ -0,0 +1,90 @@ +// +// "$Id: fl_dnd_mac.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Drag & Drop code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to "fltk-bugs@fltk.org + +// This file contains win32-specific code for fltk which is always linked +// in. Search other files for "WIN32" or filenames ending in _win32.cxx +// for other system-specific code. + +#include +#include +#include +#include + +// warning: this function is only implemented in Quickdraw. The function +// below may not work If FLTK is compiled with Quartz enabled + +extern EventRef fl_os_event; +extern char *fl_selection_buffer; +extern int fl_selection_length; + + +/** + * drag and drop whatever is in the cut-copy-paste buffer + * - create a selection first using: + * Fl::copy(const char *stuff, int len, 0) + */ +int Fl::dnd() +{ + OSErr result; + DragReference dragRef; + result = NewDrag( &dragRef ); + if ( result != noErr ) return false; + + result = AddDragItemFlavor( dragRef, 1, 'TEXT', fl_selection_buffer, fl_selection_length, 0 ); + if ( result != noErr ) { DisposeDrag( dragRef ); return false; } + + Point mp; + GetMouse(&mp); + LocalToGlobal( &mp ); + RgnHandle region = NewRgn(); + SetRectRgn( region, mp.h-10, mp.v-10, mp.h+10, mp.v+10 ); + RgnHandle r2 = NewRgn(); + SetRectRgn( r2, mp.h-8, mp.v-8, mp.h+8, mp.v+8 ); + DiffRgn( region, r2, region ); + DisposeRgn( r2 ); + + EventRecord event; + ConvertEventRefToEventRecord( fl_os_event, &event ); + result = TrackDrag( dragRef, &event, region ); + + Fl_Widget *w = Fl::pushed(); + if ( w ) + { + int old_event = Fl::e_number; + w->handle(Fl::e_number = FL_RELEASE); + Fl::e_number = old_event; + Fl::pushed( 0 ); + } + + if ( result != noErr ) { DisposeRgn( region ); DisposeDrag( dragRef ); return false; } + + DisposeRgn( region ); + DisposeDrag( dragRef ); + return true; +} + + +// +// End of "$Id: fl_dnd_mac.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_dnd_win32.cxx b/plugins/zynaddsubfx/fltk/src/fl_dnd_win32.cxx new file mode 100644 index 000000000..3bd1868f2 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_dnd_win32.cxx @@ -0,0 +1,404 @@ +// +// "$Id: fl_dnd_win32.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Drag & Drop code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems to "fltk-bugs@fltk.org + +// This file contains win32-specific code for fltk which is always linked +// in. Search other files for "WIN32" or filenames ending in _win32.cxx +// for other system-specific code. + +#include +#include +#include +#include "flstring.h" +#include +#include +#include +#include +#if defined(__CYGWIN__) +#include +#include +#else +#include +#endif + +extern char *fl_selection_buffer[2]; +extern int fl_selection_length[2]; +extern int fl_selection_buffer_length[2]; +extern char fl_i_own_selection[2]; + +Fl_Window *fl_dnd_target_window = 0; + +// All of the following code requires GCC 3.x or a non-GNU compiler... +#if !defined(__GNUC__) || __GNUC__ >= 3 + +#include +#include + +/** + * subclass the IDropTarget to receive data from DnD operations + */ +class FLDropTarget : public IDropTarget +{ + DWORD m_cRefCount; + DWORD lastEffect; + int px, py; +public: + FLDropTarget() : m_cRefCount(0) { } // initialize + HRESULT STDMETHODCALLTYPE QueryInterface( REFIID riid, LPVOID *ppvObject ) { + if (IID_IUnknown==riid || IID_IDropTarget==riid) + { + *ppvObject=this; + ((LPUNKNOWN)*ppvObject)->AddRef(); + return S_OK; + } + *ppvObject = NULL; + return E_NOINTERFACE; + } + ULONG STDMETHODCALLTYPE AddRef() { return ++m_cRefCount; } + ULONG STDMETHODCALLTYPE Release() { + long nTemp; + nTemp = --m_cRefCount; + if(nTemp==0) + delete this; + return nTemp; + } + HRESULT STDMETHODCALLTYPE DragEnter( IDataObject *pDataObj, DWORD /*grfKeyState*/, POINTL pt, DWORD *pdwEffect) { + if( !pDataObj ) return E_INVALIDARG; + // set e_modifiers here from grfKeyState, set e_x and e_root_x + // check if FLTK handles this drag and return if it can't (i.e. BMP drag without filename) + POINT ppt; + Fl::e_x_root = ppt.x = pt.x; + Fl::e_y_root = ppt.y = pt.y; + HWND hWnd = WindowFromPoint( ppt ); + Fl_Window *target = fl_find( hWnd ); + if (target) { + Fl::e_x = Fl::e_x_root-target->x(); + Fl::e_y = Fl::e_y_root-target->y(); + } + fl_dnd_target_window = target; + px = pt.x; py = pt.y; + if (fillCurrentDragData(pDataObj)) { + // FLTK has no mechanism yet for the different drop effects, so we allow move and copy + if ( target && Fl::handle( FL_DND_ENTER, target ) ) + *pdwEffect = DROPEFFECT_MOVE|DROPEFFECT_COPY; //|DROPEFFECT_LINK; + else + *pdwEffect = DROPEFFECT_NONE; + } else { + *pdwEffect = DROPEFFECT_NONE; + } + lastEffect = *pdwEffect; + return S_OK; + } + HRESULT STDMETHODCALLTYPE DragOver( DWORD /*grfKeyState*/, POINTL pt, DWORD *pdwEffect) { + if ( px==pt.x && py==pt.y ) + { + *pdwEffect = lastEffect; + return S_OK; + } + if ( !fl_dnd_target_window ) + { + *pdwEffect = lastEffect = DROPEFFECT_NONE; + return S_OK; + } + // set e_modifiers here from grfKeyState, set e_x and e_root_x + Fl::e_x_root = pt.x; + Fl::e_y_root = pt.y; + if (fl_dnd_target_window) { + Fl::e_x = Fl::e_x_root-fl_dnd_target_window->x(); + Fl::e_y = Fl::e_y_root-fl_dnd_target_window->y(); + } + if (fillCurrentDragData(0)) { + // Fl_Group will change DND_DRAG into DND_ENTER and DND_LEAVE if needed + if ( Fl::handle( FL_DND_DRAG, fl_dnd_target_window ) ) + *pdwEffect = DROPEFFECT_MOVE|DROPEFFECT_COPY; //|DROPEFFECT_LINK; + else + *pdwEffect = DROPEFFECT_NONE; + } else { + *pdwEffect = DROPEFFECT_NONE; + } + px = pt.x; py = pt.y; + lastEffect = *pdwEffect; + return S_OK; + } + HRESULT STDMETHODCALLTYPE DragLeave() { + if ( fl_dnd_target_window && fillCurrentDragData(0)) + { + Fl::handle( FL_DND_LEAVE, fl_dnd_target_window ); + fl_dnd_target_window = 0; + clearCurrentDragData(); + } + return S_OK; + } + HRESULT STDMETHODCALLTYPE Drop( IDataObject *data, DWORD /*grfKeyState*/, POINTL pt, DWORD* /*pdwEffect*/) { + if ( !fl_dnd_target_window ) + return S_OK; + Fl_Window *target = fl_dnd_target_window; + fl_dnd_target_window = 0; + Fl::e_x_root = pt.x; + Fl::e_y_root = pt.y; + if (target) { + Fl::e_x = Fl::e_x_root-target->x(); + Fl::e_y = Fl::e_y_root-target->y(); + } + // tell FLTK that the user released an object on this widget + if ( !Fl::handle( FL_DND_RELEASE, target ) ) + return S_OK; + + Fl_Widget *w = target; + while (w->parent()) w = w->window(); + HWND hwnd = fl_xid( (Fl_Window*)w ); + if (fillCurrentDragData(data)) { + int old_event = Fl::e_number; + Fl::belowmouse()->handle(Fl::e_number = FL_PASTE); // e_text will be invalid after this call + Fl::e_number = old_event; + SetForegroundWindow( hwnd ); + clearCurrentDragData(); + return S_OK; + } + return S_OK; + } +private: + + static IDataObject *currDragRef; + static char *currDragData; + static int currDragSize; + static char currDragResult; + + static void clearCurrentDragData() { + currDragRef = 0; + if (currDragData) free(currDragData); + currDragData = 0; + currDragSize = 0; + currDragResult = 0; + } + static char fillCurrentDragData(IDataObject *data) { + // shortcut through this whole procedure if there is no fresh data + if (!data) + return currDragResult; + // shortcut through this whole procedure if this is still the same drag event + // (* this is safe, because 'currDragRef' is cleared on Leave and Drop events) + if (data==currDragRef) + return currDragResult; + + // clear currDrag* for a new drag event + clearCurrentDragData(); + + // fill currDrag* with ASCII data, if available + FORMATETC fmt = { 0 }; + STGMEDIUM medium = { 0 }; + fmt.tymed = TYMED_HGLOBAL; + fmt.dwAspect = DVASPECT_CONTENT; + fmt.lindex = -1; + fmt.cfFormat = CF_TEXT; + // if it is ASCII text, return a copy of it + if ( data->GetData( &fmt, &medium )==S_OK ) + { + void *stuff = GlobalLock( medium.hGlobal ); + Fl::e_length = strlen((char*)stuff); + Fl::e_text = strdup((char*)stuff); + GlobalUnlock( medium.hGlobal ); + ReleaseStgMedium( &medium ); + currDragResult = 1; + return currDragResult; + } + // else fill currDrag* with filenames, if possible + memset(&fmt, 0, sizeof(fmt)); + fmt.tymed = TYMED_HGLOBAL; + fmt.dwAspect = DVASPECT_CONTENT; + fmt.lindex = -1; + fmt.cfFormat = CF_HDROP; + // if it is a pathname list, send an FL_PASTE with a \n seperated list of filepaths + if ( data->GetData( &fmt, &medium )==S_OK ) + { + HDROP hdrop = (HDROP)medium.hGlobal; + int i, n, nn = 0, nf = DragQueryFile( hdrop, (UINT)-1, 0, 0 ); + for ( i=0; iAddRef(); + return S_OK; + } + *ppvObject = NULL; + return E_NOINTERFACE; + } + ULONG STDMETHODCALLTYPE AddRef() { return ++m_cRefCount; } + ULONG STDMETHODCALLTYPE Release() { + long nTemp; + nTemp = --m_cRefCount; + if(nTemp==0) + delete this; + return nTemp; + } + STDMETHODIMP GiveFeedback( ulong ) { return DRAGDROP_S_USEDEFAULTCURSORS; } + STDMETHODIMP QueryContinueDrag( BOOL esc, DWORD keyState ) { + if ( esc ) + return DRAGDROP_S_CANCEL; + if ( !(keyState & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON)) ) + return DRAGDROP_S_DROP; + return S_OK; + } +}; + +/** + * this is the actual object that FLTK can drop somewhere + * - the implementation is minimal, but it should work with all decent Win32 drop targets + */ +class FLDataObject : public IDataObject +{ + DWORD m_cRefCount; +public: + FLDataObject() { m_cRefCount = 1; } + HRESULT STDMETHODCALLTYPE QueryInterface( REFIID riid, LPVOID *ppvObject ) { + if (IID_IUnknown==riid || IID_IDataObject==riid) + { + *ppvObject=this; + ((LPUNKNOWN)*ppvObject)->AddRef(); + return S_OK; + } + *ppvObject = NULL; + return E_NOINTERFACE; + } + ULONG STDMETHODCALLTYPE AddRef() { return ++m_cRefCount; } + ULONG STDMETHODCALLTYPE Release() { + long nTemp; + nTemp = --m_cRefCount; + if(nTemp==0) + delete this; + return nTemp; + } + // GetData currently allows ASCII text through Global Memory only + HRESULT STDMETHODCALLTYPE GetData( FORMATETC *pformatetcIn, STGMEDIUM *pmedium ) { + if ((pformatetcIn->dwAspect & DVASPECT_CONTENT) && + (pformatetcIn->tymed & TYMED_HGLOBAL) && + (pformatetcIn->cfFormat == CF_TEXT)) + { + HGLOBAL gh = GlobalAlloc( GHND, fl_selection_length[0]+1 ); + char *pMem = (char*)GlobalLock( gh ); + memmove( pMem, fl_selection_buffer[0], fl_selection_length[0] ); + pMem[ fl_selection_length[0] ] = 0; + pmedium->tymed = TYMED_HGLOBAL; + pmedium->hGlobal = gh; + pmedium->pUnkForRelease = NULL; + GlobalUnlock( gh ); + return S_OK; + } + return DV_E_FORMATETC; + } + HRESULT STDMETHODCALLTYPE QueryGetData( FORMATETC *pformatetc ) + { + if ((pformatetc->dwAspect & DVASPECT_CONTENT) && + (pformatetc->tymed & TYMED_HGLOBAL) && + (pformatetc->cfFormat == CF_TEXT)) + return S_OK; + return DV_E_FORMATETC; + } + // all the following methods are not really needed for a DnD object + HRESULT STDMETHODCALLTYPE GetDataHere( FORMATETC* /*pformatetcIn*/, STGMEDIUM* /*pmedium*/) { return E_NOTIMPL; } + HRESULT STDMETHODCALLTYPE GetCanonicalFormatEtc( FORMATETC* /*in*/, FORMATETC* /*out*/) { return E_NOTIMPL; } + HRESULT STDMETHODCALLTYPE SetData( FORMATETC* /*pformatetc*/, STGMEDIUM* /*pmedium*/, BOOL /*fRelease*/) { return E_NOTIMPL; } + HRESULT STDMETHODCALLTYPE EnumFormatEtc( DWORD /*dir*/, IEnumFORMATETC** /*ppenumFormatEtc*/) { return E_NOTIMPL; } + HRESULT STDMETHODCALLTYPE DAdvise( FORMATETC* /*pformatetc*/, DWORD /*advf*/, + IAdviseSink* /*pAdvSink*/, DWORD* /*pdwConnection*/) { return E_NOTIMPL; } + HRESULT STDMETHODCALLTYPE DUnadvise( DWORD /*dwConnection*/) { return E_NOTIMPL; } + HRESULT STDMETHODCALLTYPE EnumDAdvise( IEnumSTATDATA** /*ppenumAdvise*/) { return E_NOTIMPL; } +}; + + +/** + * drag and drop whatever is in the cut-copy-paste buffer + * - create a selection first using: + * Fl::copy(const char *stuff, int len, 0) + */ +int Fl::dnd() +{ + DWORD dropEffect; + ReleaseCapture(); + + FLDataObject *fdo = new FLDataObject; + fdo->AddRef(); + FLDropSource *fds = new FLDropSource; + fds->AddRef(); + + HRESULT ret = DoDragDrop( fdo, fds, DROPEFFECT_MOVE|DROPEFFECT_LINK|DROPEFFECT_COPY, &dropEffect ); + + fdo->Release(); + fds->Release(); + + Fl_Widget *w = Fl::pushed(); + if ( w ) + { + int old_event = Fl::e_number; + w->handle(Fl::e_number = FL_RELEASE); + Fl::e_number = old_event; + Fl::pushed( 0 ); + } + if ( ret==DRAGDROP_S_DROP ) return 1; // or DD_S_CANCEL + return 0; +} +#else +int Fl::dnd() +{ + // Always indicate DnD failed when using GCC < 3... + return 1; +} +#endif // !__GNUC__ || __GNUC__ >= 3 + + +// +// End of "$Id: fl_dnd_win32.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_dnd_x.cxx b/plugins/zynaddsubfx/fltk/src/fl_dnd_x.cxx new file mode 100644 index 000000000..6a30f2f81 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_dnd_x.cxx @@ -0,0 +1,201 @@ +// +// "$Id: fl_dnd_x.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Drag & Drop code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2006 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include "flstring.h" + + +extern Atom fl_XdndAware; +extern Atom fl_XdndSelection; +extern Atom fl_XdndEnter; +extern Atom fl_XdndTypeList; +extern Atom fl_XdndPosition; +extern Atom fl_XdndLeave; +extern Atom fl_XdndDrop; +extern Atom fl_XdndStatus; +extern Atom fl_XdndActionCopy; +extern Atom fl_XdndFinished; +//extern Atom fl_XdndProxy; +extern Atom fl_XdndURIList; + +extern char fl_i_own_selection[2]; +extern char *fl_selection_buffer[2]; + +extern void fl_sendClientMessage(Window window, Atom message, + unsigned long d0, + unsigned long d1=0, + unsigned long d2=0, + unsigned long d3=0, + unsigned long d4=0); + +// return version # of Xdnd this window supports. Also change the +// window to the proxy if it uses a proxy: +static int dnd_aware(Window& window) { + Atom actual; int format; unsigned long count, remaining; + unsigned char *data = 0; + XGetWindowProperty(fl_display, window, fl_XdndAware, + 0, 4, False, XA_ATOM, + &actual, &format, + &count, &remaining, &data); + if (actual == XA_ATOM && format==32 && count && data) + return int(*(Atom*)data); + return 0; +} + +static int grabfunc(int event) { + if (event == FL_RELEASE) Fl::pushed(0); + return 0; +} + +extern int (*fl_local_grab)(int); // in Fl.cxx + +// send an event to an fltk window belonging to this program: +static int local_handle(int event, Fl_Window* window) { + fl_local_grab = 0; + Fl::e_x = Fl::e_x_root-window->x(); + Fl::e_y = Fl::e_y_root-window->y(); + int ret = Fl::handle(event,window); + fl_local_grab = grabfunc; + return ret; +} + +int Fl::dnd() { + Fl_Window *source_fl_win = Fl::first_window(); + Fl::first_window()->cursor((Fl_Cursor)21); + Window source_window = fl_xid(Fl::first_window()); + fl_local_grab = grabfunc; + Window target_window = 0; + Fl_Window* local_window = 0; + int dndversion = 4; int dest_x, dest_y; + XSetSelectionOwner(fl_display, fl_XdndSelection, fl_message_window, fl_event_time); + + while (Fl::pushed()) { + + // figure out what window we are pointing at: + Window new_window = 0; int new_version = 0; + Fl_Window* new_local_window = 0; + for (Window child = RootWindow(fl_display, fl_screen);;) { + Window root; unsigned int junk3; + XQueryPointer(fl_display, child, &root, &child, + &e_x_root, &e_y_root, &dest_x, &dest_y, &junk3); + if (!child) { + if (!new_window && (new_version = dnd_aware(root))) new_window = root; + break; + } + new_window = child; + if ((new_local_window = fl_find(child))) break; + if ((new_version = dnd_aware(new_window))) break; + } + + if (new_window != target_window) { + if (local_window) { + local_handle(FL_DND_LEAVE, local_window); + } else if (dndversion) { + fl_sendClientMessage(target_window, fl_XdndLeave, source_window); + } + dndversion = new_version; + target_window = new_window; + local_window = new_local_window; + if (local_window) { + local_handle(FL_DND_ENTER, local_window); + } else if (dndversion) { + // Send an X-DND message to the target window. In order to + // support dragging of files/URLs as well as arbitrary text, + // we look at the selection buffer - if the buffer starts + // with a common URI scheme, does not contain spaces, and + // contains at least one CR LF, then we flag the data as + // both a URI list (MIME media type "text/uri-list") and + // plain text. Otherwise, we just say it is plain text. + if ((!strncmp(fl_selection_buffer[0], "file:///", 8) || + !strncmp(fl_selection_buffer[0], "ftp://", 6) || + !strncmp(fl_selection_buffer[0], "http://", 7) || + !strncmp(fl_selection_buffer[0], "https://", 8) || + !strncmp(fl_selection_buffer[0], "ipp://", 6) || + !strncmp(fl_selection_buffer[0], "ldap:", 5) || + !strncmp(fl_selection_buffer[0], "mailto:", 7) || + !strncmp(fl_selection_buffer[0], "news:", 5) || + !strncmp(fl_selection_buffer[0], "smb://", 6)) && + !strchr(fl_selection_buffer[0], ' ') && + strstr(fl_selection_buffer[0], "\r\n")) { + // Send file/URI list... + fl_sendClientMessage(target_window, fl_XdndEnter, source_window, + dndversion<<24, fl_XdndURIList, XA_STRING, 0); + } else { + // Send plain text... + fl_sendClientMessage(target_window, fl_XdndEnter, source_window, + dndversion<<24, XA_STRING, 0, 0); + } + } + } + if (local_window) { + local_handle(FL_DND_DRAG, local_window); + } else if (dndversion) { + fl_sendClientMessage(target_window, fl_XdndPosition, source_window, + 0, (e_x_root<<16)|e_y_root, fl_event_time, + fl_XdndActionCopy); + } + Fl::wait(); + } + + if (local_window) { + fl_i_own_selection[0] = 1; + if (local_handle(FL_DND_RELEASE, local_window)) paste(*belowmouse(), 0); + } else if (dndversion) { + fl_sendClientMessage(target_window, fl_XdndDrop, source_window, + 0, fl_event_time); + } else if (target_window) { + // fake a drop by clicking the middle mouse button: + XButtonEvent msg; + msg.type = ButtonPress; + msg.window = target_window; + msg.root = RootWindow(fl_display, fl_screen); + msg.subwindow = 0; + msg.time = fl_event_time+1; + msg.x = dest_x; + msg.y = dest_y; + msg.x_root = Fl::e_x_root; + msg.y_root = Fl::e_y_root; + msg.state = 0x0; + msg.button = Button2; + XSendEvent(fl_display, target_window, False, 0L, (XEvent*)&msg); + msg.time++; + msg.state = 0x200; + msg.type = ButtonRelease; + XSendEvent(fl_display, target_window, False, 0L, (XEvent*)&msg); + } + + fl_local_grab = 0; + source_fl_win->cursor(FL_CURSOR_DEFAULT); + return 1; +} + + +// +// End of "$Id: fl_dnd_x.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_draw.cxx b/plugins/zynaddsubfx/fltk/src/fl_draw.cxx new file mode 100644 index 000000000..0365dcfdd --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_draw.cxx @@ -0,0 +1,336 @@ +// +// "$Id: fl_draw.cxx 5565 2006-12-21 19:39:26Z mike $" +// +// Label drawing code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Implementation of fl_draw(const char*,int,int,int,int,Fl_Align) +// Used to draw all the labels and text, this routine: +// Word wraps the labels to fit into their bounding box. +// Breaks them into lines at the newlines. +// Expands all unprintable characters to ^X or \nnn notation +// Aligns them against the inside of the box. + +#define min(a,b) ((a)<(b)?(a):(b)) +#include +#include + +#include "flstring.h" +#include +#include + +#define MAXBUF 1024 + +char fl_draw_shortcut; // set by fl_labeltypes.cxx + +static char* underline_at; + +// Copy p to buf, replacing unprintable characters with ^X and \nnn +// Stop at a newline or if MAXBUF characters written to buffer. +// Also word-wrap if width exceeds maxw. +// Returns a pointer to the start of the next line of caharcters. +// Sets n to the number of characters put into the buffer. +// Sets width to the width of the string in the current font. + +static const char* +expand(const char* from, char* buf, double maxw, int& n, double &width, + int wrap, int draw_symbols) { + char* o = buf; + char* e = buf+(MAXBUF-4); + underline_at = 0; + char* word_end = o; + const char* word_start = from; + double w = 0; + + const char* p = from; + for (;; p++) { + + int c = *p & 255; + + if (!c || c == ' ' || c == '\n') { + // test for word-wrap: + if (word_start < p && wrap) { + double newwidth = w + fl_width(word_end, o-word_end); + if (word_end > buf && newwidth > maxw) { // break before this word + o = word_end; + p = word_start; + break; + } + word_end = o; + w = newwidth; + } + if (!c) break; + else if (c == '\n') {p++; break;} + word_start = p+1; + } + + if (o > e) break; // don't overflow buffer + + if (c == '\t') { + for (c = (o-buf)%8; c<8 && o (str + 1) && p[-1] != '@') { + strlcpy(symbol[1], p, sizeof(symbol[1])); + symwidth[1] = min(w,h); + } + } + + symtotal = symwidth[0] + symwidth[1]; + + for (p = str, lines=0; p;) { + e = expand(p, buf, w - symtotal, buflen, width, align&FL_ALIGN_WRAP, + draw_symbols); + lines++; + if (!*e || (*e == '@' && e[1] != '@' && draw_symbols)) break; + p = e; + } + + if ((symwidth[0] || symwidth[1]) && lines) { + if (symwidth[0]) symwidth[0] = lines * fl_height(); + if (symwidth[1]) symwidth[1] = lines * fl_height(); + } + + symtotal = symwidth[0] + symwidth[1]; + + // figure out vertical position of the first line: + int xpos; + int ypos; + int height = fl_height(); + int imgh = img ? img->h() : 0; + + symoffset = 0; + + if (align & FL_ALIGN_BOTTOM) ypos = y+h-(lines-1)*height-imgh; + else if (align & FL_ALIGN_TOP) ypos = y+height; + else ypos = y+(h-lines*height-imgh)/2+height; + + // draw the image unless the "text over image" alignment flag is set... + if (img && !(align & FL_ALIGN_TEXT_OVER_IMAGE)) { + if (img->w() > symoffset) symoffset = img->w(); + + if (align & FL_ALIGN_LEFT) xpos = x + symwidth[0]; + else if (align & FL_ALIGN_RIGHT) xpos = x + w - img->w() - symwidth[1]; + else xpos = x + (w - img->w() - symtotal) / 2 + symwidth[0]; + + img->draw(xpos, ypos - height); + ypos += img->h(); + } + + // now draw all the lines: + if (str) { + int desc = fl_descent(); + for (p=str; ; ypos += height) { + if (lines>1) e = expand(p, buf, w - symtotal, buflen, width, + align&FL_ALIGN_WRAP, draw_symbols); + else e = ""; + + if (width > symoffset) symoffset = (int)(width + 0.5); + + if (align & FL_ALIGN_LEFT) xpos = x + symwidth[0]; + else if (align & FL_ALIGN_RIGHT) xpos = x + w - (int)(width + .5) - symwidth[1]; + else xpos = x + (w - (int)(width + .5) - symtotal) / 2 + symwidth[0]; + + callthis(buf,buflen,xpos,ypos-desc); + + if (underline_at && underline_at >= buf && underline_at < (buf + buflen)) + callthis("_",1,xpos+int(fl_width(buf,underline_at-buf)),ypos-desc); + + if (!*e || (*e == '@' && e[1] != '@')) break; + p = e; + } + } + + // draw the image if the "text over image" alignment flag is set... + if (img && (align & FL_ALIGN_TEXT_OVER_IMAGE)) { + if (img->w() > symoffset) symoffset = img->w(); + + if (align & FL_ALIGN_LEFT) xpos = x + symwidth[0]; + else if (align & FL_ALIGN_RIGHT) xpos = x + w - img->w() - symwidth[1]; + else xpos = x + (w - img->w() - symtotal) / 2 + symwidth[0]; + + img->draw(xpos, ypos); + } + + // draw the symbols, if any... + if (symwidth[0]) { + // draw to the left + if (align & FL_ALIGN_LEFT) xpos = x; + else if (align & FL_ALIGN_RIGHT) xpos = x + w - symtotal - symoffset; + else xpos = x + (w - symoffset - symtotal) / 2; + + if (align & FL_ALIGN_BOTTOM) ypos = y + h - symwidth[0]; + else if (align & FL_ALIGN_TOP) ypos = y; + else ypos = y + (h - symwidth[0]) / 2; + + fl_draw_symbol(symbol[0], xpos, ypos, symwidth[0], symwidth[0], fl_color()); + } + + if (symwidth[1]) { + // draw to the right + if (align & FL_ALIGN_LEFT) xpos = x + symoffset + symwidth[0]; + else if (align & FL_ALIGN_RIGHT) xpos = x + w - symwidth[1]; + else xpos = x + (w - symoffset - symtotal) / 2 + symoffset + symwidth[0]; + + if (align & FL_ALIGN_BOTTOM) ypos = y + h - symwidth[1]; + else if (align & FL_ALIGN_TOP) ypos = y; + else ypos = y + (h - symwidth[1]) / 2; + + fl_draw_symbol(symbol[1], xpos, ypos, symwidth[1], symwidth[1], fl_color()); + } +} + +void fl_draw( + const char* str, // the (multi-line) string + int x, int y, int w, int h, // bounding box + Fl_Align align, + Fl_Image* img, + int draw_symbols) { + if ((!str || !*str) && !img) return; + if (w && h && !fl_not_clipped(x, y, w, h) && (align & FL_ALIGN_INSIDE)) return; + if (align & FL_ALIGN_CLIP) fl_clip(x, y, w, h); + fl_draw(str, x, y, w, h, align, fl_draw, img, draw_symbols); + if (align & FL_ALIGN_CLIP) fl_pop_clip(); +} + +void fl_measure(const char* str, int& w, int& h, int draw_symbols) { + if (!str || !*str) {w = 0; h = 0; return;} + h = fl_height(); + const char* p; + const char* e; + char buf[MAXBUF]; + int buflen; + int lines; + double width; + int W = 0; + char symbol[2][255], *symptr; + int symwidth[2], symtotal; + + // count how many lines and put the last one into the buffer: + symbol[0][0] = '\0'; + symwidth[0] = 0; + + symbol[1][0] = '\0'; + symwidth[1] = 0; + + if (draw_symbols) { + if (str && str[0] == '@' && str[1] && str[1] != '@') { + // Start with a symbol... + for (symptr = symbol[0]; + *str && !isspace(*str) && symptr < (symbol[0] + sizeof(symbol[0]) - 1); + *symptr++ = *str++); + *symptr = '\0'; + if (isspace(*str)) str++; + symwidth[0] = h; + } + + if (str && (p = strrchr(str, '@')) != NULL && p > (str + 1) && p[-1]!='@') { + strlcpy(symbol[1], p, sizeof(symbol[1])); + symwidth[1] = h; + } + } + + symtotal = symwidth[0] + symwidth[1]; + + for (p = str, lines=0; p;) { + e = expand(p, buf, w - symtotal, buflen, width, w != 0, draw_symbols); + if ((int)ceil(width) > W) W = (int)ceil(width); + lines++; + if (!*e || (*e == '@' && draw_symbols)) break; + p = e; + } + + if ((symwidth[0] || symwidth[1]) && lines) { + if (symwidth[0]) symwidth[0] = lines * fl_height(); + if (symwidth[1]) symwidth[1] = lines * fl_height(); + } + + symtotal = symwidth[0] + symwidth[1]; + + w = W + symtotal; + h = lines*h; +} + +// +// End of "$Id: fl_draw.cxx 5565 2006-12-21 19:39:26Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_draw_image.cxx b/plugins/zynaddsubfx/fltk/src/fl_draw_image.cxx new file mode 100644 index 000000000..a75b340a7 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_draw_image.cxx @@ -0,0 +1,576 @@ +// +// "$Id: fl_draw_image.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Image drawing routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// I hope a simple and portable method of drawing color and monochrome +// images. To keep this simple, only a single storage type is +// supported: 8 bit unsigned data, byte order RGB, and pixels are +// stored packed into rows with the origin at the top-left. It is +// possible to alter the size of pixels with the "delta" argument, to +// add alpha or other information per pixel. It is also possible to +// change the origin and direction of the image data by messing with +// the "delta" and "linedelta", making them negative, though this may +// defeat some of the shortcuts in translating the image for X. + +#ifdef WIN32 +# include "fl_draw_image_win32.cxx" +#elif defined(__APPLE__) +# include "fl_draw_image_mac.cxx" +#else + +// A list of assumptions made about the X display: + +// bits_per_pixel must be one of 8, 16, 24, 32. + +// scanline_pad must be a power of 2 and greater or equal to 8. + +// PsuedoColor visuals must have 8 bits_per_pixel (although the depth +// may be less than 8). This is the only limitation that affects any +// modern X displays, you can't use 12 or 16 bit colormaps. + +// The mask bits in TrueColor visuals for each color are +// contiguous and have at least one bit of each color. This +// is not checked for. + +// For 24 and 32 bit visuals there must be at least 8 bits of each color. + +//////////////////////////////////////////////////////////////// + +# include +# include +# include +# include "Fl_XColor.H" +# include "flstring.h" + +static XImage xi; // template used to pass info to X +static int bytes_per_pixel; +static int scanline_add; +static int scanline_mask; + +static void (*converter)(const uchar *from, uchar *to, int w, int delta); +static void (*mono_converter)(const uchar *from, uchar *to, int w, int delta); + +static int dir; // direction-alternator +static int ri,gi,bi; // saved error-diffusion value + +# if USE_COLORMAP +//////////////////////////////////////////////////////////////// +// 8-bit converter with error diffusion + +static void color8_converter(const uchar *from, uchar *to, int w, int delta) { + int r=ri, g=gi, b=bi; + int d, td; + if (dir) { + dir = 0; + from = from+(w-1)*delta; + to = to+(w-1); + d = -delta; + td = -1; + } else { + dir = 1; + d = delta; + td = 1; + } + for (; w--; from += d, to += td) { + r += from[0]; if (r < 0) r = 0; else if (r>255) r = 255; + g += from[1]; if (g < 0) g = 0; else if (g>255) g = 255; + b += from[2]; if (b < 0) b = 0; else if (b>255) b = 255; + Fl_Color i = fl_color_cube(r*FL_NUM_RED/256,g*FL_NUM_GREEN/256,b*FL_NUM_BLUE/256); + Fl_XColor& xmap = fl_xmap[0][i]; + if (!xmap.mapped) {if (!fl_redmask) fl_xpixel(r,g,b); else fl_xpixel(i);} + r -= xmap.r; + g -= xmap.g; + b -= xmap.b; + *to = uchar(xmap.pixel); + } + ri = r; gi = g; bi = b; +} + +static void mono8_converter(const uchar *from, uchar *to, int w, int delta) { + int r=ri, g=gi, b=bi; + int d, td; + if (dir) { + dir = 0; + from = from+(w-1)*delta; + to = to+(w-1); + d = -delta; + td = -1; + } else { + dir = 1; + d = delta; + td = 1; + } + for (; w--; from += d, to += td) { + r += from[0]; if (r < 0) r = 0; else if (r>255) r = 255; + g += from[0]; if (g < 0) g = 0; else if (g>255) g = 255; + b += from[0]; if (b < 0) b = 0; else if (b>255) b = 255; + Fl_Color i = fl_color_cube(r*FL_NUM_RED/256,g*FL_NUM_GREEN/256,b*FL_NUM_BLUE/256); + Fl_XColor& xmap = fl_xmap[0][i]; + if (!xmap.mapped) {if (!fl_redmask) fl_xpixel(r,g,b); else fl_xpixel(i);} + r -= xmap.r; + g -= xmap.g; + b -= xmap.b; + *to = uchar(xmap.pixel); + } + ri = r; gi = g; bi = b; +} + +# endif + +//////////////////////////////////////////////////////////////// +// 16 bit TrueColor converters with error diffusion +// Cray computers have no 16-bit type, so we use character pointers +// (which may be slow) + +# ifdef U16 +# define OUTTYPE U16 +# define OUTSIZE 1 +# define OUTASSIGN(v) *t = v +# else +# define OUTTYPE uchar +# define OUTSIZE 2 +# define OUTASSIGN(v) int tt=v; t[0] = uchar(tt>>8); t[1] = uchar(tt) +# endif + +static void color16_converter(const uchar *from, uchar *to, int w, int delta) { + OUTTYPE *t = (OUTTYPE *)to; + int d, td; + if (dir) { + dir = 0; + from = from+(w-1)*delta; + t = t+(w-1)*OUTSIZE; + d = -delta; + td = -OUTSIZE; + } else { + dir = 1; + d = delta; + td = OUTSIZE; + } + int r=ri, g=gi, b=bi; + for (; w--; from += d, t += td) { + r = (r&~fl_redmask) +from[0]; if (r>255) r = 255; + g = (g&~fl_greenmask)+from[1]; if (g>255) g = 255; + b = (b&~fl_bluemask) +from[2]; if (b>255) b = 255; + OUTASSIGN(( + ((r&fl_redmask)<> fl_extrashift); + } + ri = r; gi = g; bi = b; +} + +static void mono16_converter(const uchar *from,uchar *to,int w, int delta) { + OUTTYPE *t = (OUTTYPE *)to; + int d, td; + if (dir) { + dir = 0; + from = from+(w-1)*delta; + t = t+(w-1)*OUTSIZE; + d = -delta; + td = -OUTSIZE; + } else { + dir = 1; + d = delta; + td = OUTSIZE; + } + uchar mask = fl_redmask & fl_greenmask & fl_bluemask; + int r=ri; + for (; w--; from += d, t += td) { + r = (r&~mask) + *from; if (r > 255) r = 255; + uchar m = r&mask; + OUTASSIGN(( + (m<> fl_extrashift); + } + ri = r; +} + +// special-case the 5r6g5b layout used by XFree86: + +static void c565_converter(const uchar *from, uchar *to, int w, int delta) { + OUTTYPE *t = (OUTTYPE *)to; + int d, td; + if (dir) { + dir = 0; + from = from+(w-1)*delta; + t = t+(w-1)*OUTSIZE; + d = -delta; + td = -OUTSIZE; + } else { + dir = 1; + d = delta; + td = OUTSIZE; + } + int r=ri, g=gi, b=bi; + for (; w--; from += d, t += td) { + r = (r&7)+from[0]; if (r>255) r = 255; + g = (g&3)+from[1]; if (g>255) g = 255; + b = (b&7)+from[2]; if (b>255) b = 255; + OUTASSIGN(((r&0xf8)<<8) + ((g&0xfc)<<3) + (b>>3)); + } + ri = r; gi = g; bi = b; +} + +static void m565_converter(const uchar *from,uchar *to,int w, int delta) { + OUTTYPE *t = (OUTTYPE *)to; + int d, td; + if (dir) { + dir = 0; + from = from+(w-1)*delta; + t = t+(w-1)*OUTSIZE; + d = -delta; + td = -OUTSIZE; + } else { + dir = 1; + d = delta; + td = OUTSIZE; + } + int r=ri; + for (; w--; from += d, t += td) { + r = (r&7) + *from; if (r > 255) r = 255; + OUTASSIGN((r>>3) * 0x841); + } + ri = r; +} + +//////////////////////////////////////////////////////////////// +// 24bit TrueColor converters: + +static void rgb_converter(const uchar *from, uchar *to, int w, int delta) { + int d = delta-3; + for (; w--; from += d) { + *to++ = *from++; + *to++ = *from++; + *to++ = *from++; + } +} + +static void bgr_converter(const uchar *from, uchar *to, int w, int delta) { + for (; w--; from += delta) { + uchar r = from[0]; + uchar g = from[1]; + *to++ = from[2]; + *to++ = g; + *to++ = r; + } +} + +static void rrr_converter(const uchar *from, uchar *to, int w, int delta) { + for (; w--; from += delta) { + *to++ = *from; + *to++ = *from; + *to++ = *from; + } +} + +//////////////////////////////////////////////////////////////// +// 32bit TrueColor converters on a 32 or 64-bit machine: + +# ifdef U64 +# define STORETYPE U64 +# if WORDS_BIGENDIAN +# define INNARDS32(f) \ + U64 *t = (U64*)to; \ + int w1 = (w+1)/2; \ + for (; w1--; from += delta) {U64 i = f; from += delta; *t++ = (i<<32)|(f);} +# else +# define INNARDS32(f) \ + U64 *t = (U64*)to; \ + int w1 = (w+1)/2; \ + for (; w1--; from += delta) {U64 i=f; from+= delta; *t++ = ((U64)(f)<<32)|i;} +# endif +# else +# define STORETYPE U32 +# define INNARDS32(f) \ + U32 *t = (U32*)to; for (; w--; from += delta) *t++ = f +# endif + +static void rgbx_converter(const uchar *from, uchar *to, int w, int delta) { + INNARDS32((unsigned(from[0])<<24)+(from[1]<<16)+(from[2]<<8)); +} + +static void xbgr_converter(const uchar *from, uchar *to, int w, int delta) { + INNARDS32((from[0])+(from[1]<<8)+(from[2]<<16)); +} + +static void xrgb_converter(const uchar *from, uchar *to, int w, int delta) { + INNARDS32((from[0]<<16)+(from[1]<<8)+(from[2])); +} + +static void bgrx_converter(const uchar *from, uchar *to, int w, int delta) { + INNARDS32((from[0]<<8)+(from[1]<<16)+(unsigned(from[2])<<24)); +} + +static void rrrx_converter(const uchar *from, uchar *to, int w, int delta) { + INNARDS32(unsigned(*from) * 0x1010100U); +} + +static void xrrr_converter(const uchar *from, uchar *to, int w, int delta) { + INNARDS32(*from * 0x10101U); +} + +static void +color32_converter(const uchar *from, uchar *to, int w, int delta) { + INNARDS32( + (from[0]<depth == fl_visual->depth) break; + xi.format = ZPixmap; + xi.byte_order = ImageByteOrder(fl_display); +//i.bitmap_unit = 8; +//i.bitmap_bit_order = MSBFirst; +//i.bitmap_pad = 8; + xi.depth = fl_visual->depth; + xi.bits_per_pixel = pfv->bits_per_pixel; + + if (xi.bits_per_pixel & 7) bytes_per_pixel = 0; // produce fatal error + else bytes_per_pixel = xi.bits_per_pixel/8; + + unsigned int n = pfv->scanline_pad/8; + if (pfv->scanline_pad & 7 || (n&(n-1))) + Fl::fatal("Can't do scanline_pad of %d",pfv->scanline_pad); + if (n < sizeof(STORETYPE)) n = sizeof(STORETYPE); + scanline_add = n-1; + scanline_mask = -n; + +# if USE_COLORMAP + if (bytes_per_pixel == 1) { + converter = color8_converter; + mono_converter = mono8_converter; + return; + } + if (!fl_visual->red_mask) + Fl::fatal("Can't do %d bits_per_pixel colormap",xi.bits_per_pixel); +# endif + + // otherwise it is a TrueColor visual: + + int rs = fl_redshift; + int gs = fl_greenshift; + int bs = fl_blueshift; + + switch (bytes_per_pixel) { + + case 2: + // All 16-bit TrueColor visuals are supported on any machine with + // 24 or more bits per integer. +# ifdef U16 + xi.byte_order = WORDS_BIGENDIAN; +# else + xi.byte_order = 1; +# endif + if (rs == 11 && gs == 6 && bs == 0 && fl_extrashift == 3) { + converter = c565_converter; + mono_converter = m565_converter; + } else { + converter = color16_converter; + mono_converter = mono16_converter; + } + break; + + case 3: + if (xi.byte_order) {rs = 16-rs; gs = 16-gs; bs = 16-bs;} + if (rs == 0 && gs == 8 && bs == 16) { + converter = rgb_converter; + mono_converter = rrr_converter; + } else if (rs == 16 && gs == 8 && bs == 0) { + converter = bgr_converter; + mono_converter = rrr_converter; + } else { + Fl::fatal("Can't do arbitrary 24bit color"); + } + break; + + case 4: + if ((xi.byte_order!=0) != WORDS_BIGENDIAN) + {rs = 24-rs; gs = 24-gs; bs = 24-bs;} + if (rs == 0 && gs == 8 && bs == 16) { + converter = xbgr_converter; + mono_converter = xrrr_converter; + } else if (rs == 24 && gs == 16 && bs == 8) { + converter = rgbx_converter; + mono_converter = rrrx_converter; + } else if (rs == 8 && gs == 16 && bs == 24) { + converter = bgrx_converter; + mono_converter = rrrx_converter; + } else if (rs == 16 && gs == 8 && bs == 0) { + converter = xrgb_converter; + mono_converter = xrrr_converter; + } else { + xi.byte_order = WORDS_BIGENDIAN; + converter = color32_converter; + mono_converter = mono32_converter; + } + break; + + default: + Fl::fatal("Can't do %d bits_per_pixel",xi.bits_per_pixel); + } + +} + +# define MAXBUFFER 0x40000 // 256k + +static void innards(const uchar *buf, int X, int Y, int W, int H, + int delta, int linedelta, int mono, + Fl_Draw_Image_Cb cb, void* userdata) +{ + if (!linedelta) linedelta = W*delta; + + int dx, dy, w, h; + fl_clip_box(X,Y,W,H,dx,dy,w,h); + if (w<=0 || h<=0) return; + dx -= X; + dy -= Y; + + if (!bytes_per_pixel) figure_out_visual(); + xi.width = w; + xi.height = h; + + void (*conv)(const uchar *from, uchar *to, int w, int delta) = converter; + if (mono) conv = mono_converter; + + // See if the data is already in the right format. Unfortunately + // some 32-bit x servers (XFree86) care about the unknown 8 bits + // and they must be zero. I can't confirm this for user-supplied + // data, so the 32-bit shortcut is disabled... + // This can set bytes_per_line negative if image is bottom-to-top + // I tested it on Linux, but it may fail on other Xlib implementations: + if (buf && ( +# if 0 // set this to 1 to allow 32-bit shortcut + delta == 4 && +# if WORDS_BIGENDIAN + conv == rgbx_converter +# else + conv == xbgr_converter +# endif + || +# endif + conv == rgb_converter && delta==3 + ) && !(linedelta&scanline_add)) { + xi.data = (char *)(buf+delta*dx+linedelta*dy); + xi.bytes_per_line = linedelta; + + } else { + int linesize = ((w*bytes_per_pixel+scanline_add)&scanline_mask)/sizeof(STORETYPE); + int blocking = h; + static STORETYPE *buffer; // our storage, always word aligned + static long buffer_size; + {int size = linesize*h; + if (size > MAXBUFFER) { + size = MAXBUFFER; + blocking = MAXBUFFER/linesize; + } + if (size > buffer_size) { + delete[] buffer; + buffer_size = size; + buffer = new STORETYPE[size]; + }} + xi.data = (char *)buffer; + xi.bytes_per_line = linesize*sizeof(STORETYPE); + if (buf) { + buf += delta*dx+linedelta*dy; + for (int j=0; j-3),0,0); +} +void fl_draw_image(Fl_Draw_Image_Cb cb, void* data, + int x, int y, int w, int h,int d) { + innards(0,x,y,w,h,d,0,(d<3&&d>-3),cb,data); +} +void fl_draw_image_mono(const uchar* buf, int x, int y, int w, int h, int d, int l){ + innards(buf,x,y,w,h,d,l,1,0,0); +} +void fl_draw_image_mono(Fl_Draw_Image_Cb cb, void* data, + int x, int y, int w, int h,int d) { + innards(0,x,y,w,h,d,0,1,cb,data); +} + +void fl_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b) { + if (fl_visual->depth > 16) { + fl_color(r,g,b); + fl_rectf(x,y,w,h); + } else { + uchar c[3]; + c[0] = r; c[1] = g; c[2] = b; + innards(c,x,y,w,h,0,0,0,0,0); + } +} + +#endif + +// +// End of "$Id: fl_draw_image.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_draw_image_mac.cxx b/plugins/zynaddsubfx/fltk/src/fl_draw_image_mac.cxx new file mode 100644 index 000000000..a31374fad --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_draw_image_mac.cxx @@ -0,0 +1,274 @@ +// +// "$Id: fl_draw_image_mac.cxx 5614 2007-01-18 15:25:09Z matt $" +// +// MacOS image drawing code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +//////////////////////////////////////////////////////////////// + +#include +#include +#include +#include + +#define MAXBUFFER 0x40000 // 256k + +/** + * draw an image based on the input parameters + * + * buf: image source data + * X, Y: position (in buffer?!) + * W, H: size of picture (in pixel?) + * delta: distance from pixel to pixel in buf in bytes + * linedelta: distance from line to line in buf in bytes + * mono: if set, pixel is one byte - if zero, pixel is 3 byte + * cb: callback to copy image data into (RGB?) buffer + * buf: pointer to first byte in image source + * x, y: position in buffer + * w: width (in bytes?) + * dst: destination buffer + * userdata: ? + */ +static void innards(const uchar *buf, int X, int Y, int W, int H, + int delta, int linedelta, int mono, + Fl_Draw_Image_Cb cb, void* userdata) +{ + if (!linedelta) linedelta = W*delta; + +#ifdef __APPLE_QD__ + // theoretically, if the current GPort permits, we could write + // directly into it, avoiding the temporary GWorld. For now I + // will go the safe way... . + char direct = 0; + GWorldPtr gw; + Rect bounds; + bounds.left=0; bounds.right=W; bounds.top=0; bounds.bottom=H; + QDErr err = NewGWorld( &gw, 32, &bounds, 0L, 0L, useTempMem ); + if (err==noErr && gw) { + PixMapHandle pm = GetGWorldPixMap( gw ); + if ( pm ) { + LockPixels( pm ); + if ( *pm ) { + uchar *base = (uchar*)GetPixBaseAddr( pm ); + if ( base ) { + PixMapPtr pmp = *pm; + // make absolutely sure that we can use a direct memory write to + // create the pixmap! + if ( pmp->pixelType == 16 || pmp->pixelSize == 32 || pmp->cmpCount == 3 || pmp->cmpSize == 8 ) { + int rowBytes = pmp->rowBytes & 0x3fff; + if ( cb ) + { + uchar *tmpBuf = new uchar[ W*delta ]; + if ( mono ) delta -= 1; else delta -= 3; + for ( int i=0; i-3),0,0); +} +void fl_draw_image(Fl_Draw_Image_Cb cb, void* data, + int x, int y, int w, int h,int d) { + innards(0,x,y,w,h,d,0,(d<3&&d>-3),cb,data); +} +void fl_draw_image_mono(const uchar* buf, int x, int y, int w, int h, int d, int l){ + innards(buf,x,y,w,h,d,l,1,0,0); +} +void fl_draw_image_mono(Fl_Draw_Image_Cb cb, void* data, + int x, int y, int w, int h,int d) { + innards(0,x,y,w,h,d,0,1,cb,data); +} + +void fl_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b) { + fl_color(r,g,b); + fl_rectf(x,y,w,h); +} + +// +// End of "$Id: fl_draw_image_mac.cxx 5614 2007-01-18 15:25:09Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_draw_image_win32.cxx b/plugins/zynaddsubfx/fltk/src/fl_draw_image_win32.cxx new file mode 100644 index 000000000..543b03525 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_draw_image_win32.cxx @@ -0,0 +1,315 @@ +// +// "$Id: fl_draw_image_win32.cxx 5436 2006-09-16 16:02:00Z matt $" +// +// WIN32 image drawing code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// I hope a simple and portable method of drawing color and monochrome +// images. To keep this simple, only a single storage type is +// supported: 8 bit unsigned data, byte order RGB, and pixels are +// stored packed into rows with the origin at the top-left. It is +// possible to alter the size of pixels with the "delta" argument, to +// add alpha or other information per pixel. It is also possible to +// change the origin and direction of the image data by messing with +// the "delta" and "linedelta", making them negative, though this may +// defeat some of the shortcuts in translating the image for X. + +// Unbelievably (since it conflicts with how most PC software works) +// Micro$oft picked a bottom-up and BGR storage format for their +// DIB images. I'm pretty certain there is a way around this, but +// I can't find any other than the brute-force method of drawing +// each line as a seperate image. This may also need to be done +// if the delta is any amount other than 1, 3, or 4. + +//////////////////////////////////////////////////////////////// + +#include +#include +#include +#include + +#define MAXBUFFER 0x40000 // 256k + +#if USE_COLORMAP + +// error-diffusion dither into the FLTK colormap +static void dither(uchar* to, const uchar* from, int w, int delta) { + static int ri, gi, bi, dir; + int r=ri, g=gi, b=bi; + int d, td; + if (dir) { + dir = 0; + from = from+(w-1)*delta; + to = to+(w-1); + d = -delta; + td = -1; + } else { + dir = 1; + d = delta; + td = 1; + } + for (; w--; from += d, to += td) { + r += from[0]; if (r < 0) r = 0; else if (r>255) r = 255; + int rr = r*FL_NUM_RED/256; + r -= rr*255/(FL_NUM_RED-1); + g += from[1]; if (g < 0) g = 0; else if (g>255) g = 255; + int gg = g*FL_NUM_GREEN/256; + g -= gg*255/(FL_NUM_GREEN-1); + b += from[2]; if (b < 0) b = 0; else if (b>255) b = 255; + int bb = b*FL_NUM_BLUE/256; + b -= bb*255/(FL_NUM_BLUE-1); + *to = uchar(FL_COLOR_CUBE+(bb*FL_NUM_RED+rr)*FL_NUM_GREEN+gg); + } + ri = r; gi = g; bi = b; +} + +// error-diffusion dither into the FLTK colormap +static void monodither(uchar* to, const uchar* from, int w, int delta) { + static int ri,dir; + int r=ri; + int d, td; + if (dir) { + dir = 0; + from = from+(w-1)*delta; + to = to+(w-1); + d = -delta; + td = -1; + } else { + dir = 1; + d = delta; + td = 1; + } + for (; w--; from += d, to += td) { + r += *from; if (r < 0) r = 0; else if (r>255) r = 255; + int rr = r*FL_NUM_GRAY/256; + r -= rr*255/(FL_NUM_GRAY-1); + *to = uchar(FL_GRAY_RAMP+rr); + } + ri = r; +} + +#endif // USE_COLORMAP + +static void innards(const uchar *buf, int X, int Y, int W, int H, + int delta, int linedelta, int depth, + Fl_Draw_Image_Cb cb, void* userdata) +{ +#if USE_COLORMAP + char indexed = (fl_palette != 0); +#endif + + if (depth==0) depth = 3; + if (indexed || !fl_can_do_alpha_blending()) + depth = (depth-1)|1; + + if (!linedelta) linedelta = W*delta; + + int x, y, w, h; + fl_clip_box(X,Y,W,H,x,y,w,h); + if (w<=0 || h<=0) return; + if (buf) buf += (x-X)*delta + (y-Y)*linedelta; + + static U32 bmibuffer[256+12]; + BITMAPINFO &bmi = *((BITMAPINFO*)bmibuffer); + if (!bmi.bmiHeader.biSize) { + bmi.bmiHeader.biSize = sizeof(bmi)-4; // does it use this to determine type? + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biCompression = BI_RGB; + bmi.bmiHeader.biXPelsPerMeter = 0; + bmi.bmiHeader.biYPelsPerMeter = 0; + bmi.bmiHeader.biClrUsed = 0; + bmi.bmiHeader.biClrImportant = 0; + } +#if USE_COLORMAP + if (indexed) { + for (short i=0; i<256; i++) { + *((short*)(bmi.bmiColors)+i) = i; + } + } else +#endif + if (depth<3) { + for (int i=0; i<256; i++) { + bmi.bmiColors[i].rgbBlue = (uchar)i; + bmi.bmiColors[i].rgbGreen = (uchar)i; + bmi.bmiColors[i].rgbRed = (uchar)i; + bmi.bmiColors[i].rgbReserved = (uchar)i; + } + } + bmi.bmiHeader.biWidth = w; +#if USE_COLORMAP + bmi.bmiHeader.biBitCount = indexed ? 8 : depth*8; + int pixelsize = indexed ? 1 : depth; +#else + bmi.bmiHeader.biBitCount = depth*8; + int pixelsize = depth; +#endif + int linesize = (pixelsize*w+3)&~3; + + static U32* buffer; + int blocking = h; + {int size = linesize*h; + if (size > MAXBUFFER) { + size = MAXBUFFER; + blocking = MAXBUFFER/linesize; + } + static long buffer_size; + if (size > buffer_size) { + delete[] buffer; + buffer_size = size; + buffer = new U32[(size+3)/4]; + }} + bmi.bmiHeader.biHeight = blocking; + static U32* line_buffer; + if (!buf) { + int size = W*delta; + static int line_buf_size; + if (size > line_buf_size) { + delete[] line_buffer; + line_buf_size = size; + line_buffer = new U32[(size+3)/4]; + } + } + for (int j=0; j>8; + to[1] = (from[1]*a)>>8; + to[2] = (r*a)>>8; + to[3] = from[3]; + } + break; + } + } + } + SetDIBitsToDevice(fl_gc, x, y+j-k, w, k, 0, 0, 0, k, + (LPSTR)((uchar*)buffer+(blocking-k)*linesize), + &bmi, +#if USE_COLORMAP + indexed ? DIB_PAL_COLORS : DIB_RGB_COLORS +#else + DIB_RGB_COLORS +#endif + ); + } +} + +static int fl_abs(int v) { return v<0 ? -v : v; } + +void fl_draw_image(const uchar* buf, int x, int y, int w, int h, int d, int l){ + if (fl_abs(d)&FL_IMAGE_WITH_ALPHA) { + d ^= FL_IMAGE_WITH_ALPHA; + innards(buf,x,y,w,h,d,l,fl_abs(d),0,0); + } else { + innards(buf,x,y,w,h,d,l,(d<3&&d>-3),0,0); + } +} + +void fl_draw_image(Fl_Draw_Image_Cb cb, void* data, + int x, int y, int w, int h,int d) { + if (fl_abs(d)&FL_IMAGE_WITH_ALPHA) { + d ^= FL_IMAGE_WITH_ALPHA; + innards(0,x,y,w,h,d,0,(d<3&&d>-3),cb,data); + } else { + innards(0,x,y,w,h,d,0,(d<3&&d>-3),cb,data); + } +} + +void fl_draw_image_mono(const uchar* buf, int x, int y, int w, int h, int d, int l){ + if (fl_abs(d)&FL_IMAGE_WITH_ALPHA) { + d ^= FL_IMAGE_WITH_ALPHA; + innards(buf,x,y,w,h,d,l,1,0,0); + } else { + innards(buf,x,y,w,h,d,l,1,0,0); + } +} + +void fl_draw_image_mono(Fl_Draw_Image_Cb cb, void* data, + int x, int y, int w, int h,int d) { + if (fl_abs(d)&FL_IMAGE_WITH_ALPHA) { + d ^= FL_IMAGE_WITH_ALPHA; + innards(0,x,y,w,h,d,0,1,cb,data); + } else { + innards(0,x,y,w,h,d,0,1,cb,data); + } +} + +void fl_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b) { +#if USE_COLORMAP + // use the error diffusion dithering code to produce a much nicer block: + if (fl_palette) { + uchar c[3]; + c[0] = r; c[1] = g; c[2] = b; + innards(c,x,y,w,h,0,0,0,0,0); + return; + } +#endif + fl_color(r,g,b); + fl_rectf(x,y,w,h); +} + +// +// End of "$Id: fl_draw_image_win32.cxx 5436 2006-09-16 16:02:00Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_draw_pixmap.cxx b/plugins/zynaddsubfx/fltk/src/fl_draw_pixmap.cxx new file mode 100644 index 000000000..ee4b84798 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_draw_pixmap.cxx @@ -0,0 +1,340 @@ +// +// "$Id: fl_draw_pixmap.cxx 6026 2008-02-14 18:17:06Z matt $" +// +// Pixmap drawing code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Implemented without using the xpm library (which I can't use because +// it interferes with the color cube used by fl_draw_image). +// Current implementation is cheap and slow, and works best on a full-color +// display. Transparency is not handled, and colors are dithered to +// the color cube. Color index is achieved by adding the id +// characters together! Also mallocs a lot of temporary memory! +// Notice that there is no pixmap file interface. This is on purpose, +// as I want to discourage programs that require support files to work. +// All data needed by a program ui should be compiled in!!! + +#include +#include +#include +#include +#include "flstring.h" + +static int ncolors, chars_per_pixel; + +int fl_measure_pixmap(/*const*/ char* const* data, int &w, int &h) { + return fl_measure_pixmap((const char*const*)data,w,h); +} + +int fl_measure_pixmap(const char * const *data, int &w, int &h) { + int i = sscanf(data[0],"%d%d%d%d",&w,&h,&ncolors,&chars_per_pixel); + if (i<4 || w<=0 || h<=0 || + chars_per_pixel!=1 && chars_per_pixel!=2) return w=0; + return 1; +} + +#ifdef U64 + +// The callback from fl_draw_image to get a row of data passes this: +struct pixmap_data { + int w, h; + const uchar*const* data; + union { + U64 colors[256]; + U64* byte1[256]; + }; +}; + +// callback for 1 byte per pixel: +static void cb1(void*v, int x, int y, int w, uchar* buf) { + pixmap_data& d = *(pixmap_data*)v; + const uchar* p = d.data[y]+x; + U64* q = (U64*)buf; + for (int X=w; X>0; X-=2, p += 2) { + if (X>1) { +# if WORDS_BIGENDIAN + *q++ = (d.colors[p[0]]<<32) | d.colors[p[1]]; +# else + *q++ = (d.colors[p[1]]<<32) | d.colors[p[0]]; +# endif + } else { +# if WORDS_BIGENDIAN + *q++ = d.colors[p[0]]<<32; +# else + *q++ = d.colors[p[0]]; +# endif + } + } +} + +// callback for 2 bytes per pixel: +static void cb2(void*v, int x, int y, int w, uchar* buf) { + pixmap_data& d = *(pixmap_data*)v; + const uchar* p = d.data[y]+2*x; + U64* q = (U64*)buf; + for (int X=w; X>0; X-=2) { + U64* colors = d.byte1[*p++]; + int index = *p++; + if (X>1) { + U64* colors1 = d.byte1[*p++]; + int index1 = *p++; +# if WORDS_BIGENDIAN + *q++ = (colors[index]<<32) | colors1[index1]; +# else + *q++ = (colors1[index1]<<32) | colors[index]; +# endif + } else { +# if WORDS_BIGENDIAN + *q++ = colors[index]<<32; +# else + *q++ = colors[index]; +# endif + } + } +} + +#else // U32 + +// The callback from fl_draw_image to get a row of data passes this: +struct pixmap_data { + int w, h; + const uchar*const* data; + union { + U32 colors[256]; + U32* byte1[256]; + }; +}; + +# ifndef __APPLE_QUARTZ__ + +// callback for 1 byte per pixel: +static void cb1(void*v, int x, int y, int w, uchar* buf) { + pixmap_data& d = *(pixmap_data*)v; + const uchar* p = d.data[y]+x; + U32* q = (U32*)buf; + for (int X=w; X--;) *q++ = d.colors[*p++]; +} + +// callback for 2 bytes per pixel: +static void cb2(void*v, int x, int y, int w, uchar* buf) { + pixmap_data& d = *(pixmap_data*)v; + const uchar* p = d.data[y]+2*x; + U32* q = (U32*)buf; + for (int X=w; X--;) { + U32* colors = d.byte1[*p++]; + *q++ = colors[*p++]; + } +} + +# endif // !__APPLE_QUARTZ__ + +#endif // U64 else U32 + +uchar **fl_mask_bitmap; // if non-zero, create bitmap and store pointer here + +int fl_draw_pixmap(/*const*/ char* const* data, int x,int y,Fl_Color bg) { + return fl_draw_pixmap((const char*const*)data,x,y,bg); +} + +int fl_draw_pixmap(const char*const* di, int x, int y, Fl_Color bg) { + pixmap_data d; + if (!fl_measure_pixmap(di, d.w, d.h)) return 0; + const uchar*const* data = (const uchar*const*)(di+1); + int transparent_index = -1; + + if (ncolors < 0) { // FLTK (non standard) compressed colormap + ncolors = -ncolors; + const uchar *p = *data++; + // if first color is ' ' it is transparent (put it later to make + // it not be transparent): + if (*p == ' ') { + uchar* c = (uchar*)&d.colors[(int)' ']; +#ifdef U64 + *(U64*)c = 0; +# if WORDS_BIGENDIAN + c += 4; +# endif +#endif + transparent_index = ' '; + Fl::get_color(bg, c[0], c[1], c[2]); c[3] = 0; + p += 4; + ncolors--; + } + // read all the rest of the colors: + for (int i=0; i < ncolors; i++) { + uchar* c = (uchar*)&d.colors[*p++]; +#ifdef U64 + *(U64*)c = 0; +# if WORDS_BIGENDIAN + c += 4; +# endif +#endif + *c++ = *p++; + *c++ = *p++; + *c++ = *p++; +#ifdef __APPLE_QUARTZ__ + *c = 255; +#else + *c = 0; +#endif + } + } else { // normal XPM colormap with names + if (chars_per_pixel>1) memset(d.byte1, 0, sizeof(d.byte1)); + for (int i=0; i1) { +#ifdef U64 + U64* colors = d.byte1[ind]; + if (!colors) colors = d.byte1[ind] = new U64[256]; +#else + U32* colors = d.byte1[ind]; + if (!colors) colors = d.byte1[ind] = new U32[256]; +#endif + c = (uchar*)&colors[*p]; + ind = (ind<<8)|*p++; + } else { + c = (uchar *)&d.colors[ind]; + } + // look for "c word", or last word if none: + const uchar *previous_word = p; + for (;;) { + while (*p && isspace(*p)) p++; + uchar what = *p++; + while (*p && !isspace(*p)) p++; + while (*p && isspace(*p)) p++; + if (!*p) {p = previous_word; break;} + if (what == 'c') break; + previous_word = p; + while (*p && !isspace(*p)) p++; + } +#ifdef U64 + *(U64*)c = 0; +# if WORDS_BIGENDIAN + c += 4; +# endif +#endif +#ifdef __APPLE_QUARTZ__ + c[3] = 255; +#endif + if (!fl_parse_color((const char*)p, c[0], c[1], c[2])) { + // assume "None" or "#transparent" for any errors + // "bg" should be transparent... + Fl::get_color(bg, c[0], c[1], c[2]); +#ifdef __APPLE_QUARTZ__ + c[3] = 0; +#endif + transparent_index = ind; + } + } + } + d.data = data; + +#ifndef __APPLE_QUARTZ__ + + // build the mask bitmap used by Fl_Pixmap: + if (fl_mask_bitmap && transparent_index >= 0) { + int W = (d.w+7)/8; + uchar* bitmap = new uchar[W * d.h]; + *fl_mask_bitmap = bitmap; + for (int Y = 0; Y < d.h; Y++) { + const uchar* p = data[Y]; + if (chars_per_pixel <= 1) { + int dw = d.w; + for (int X = 0; X < W; X++) { + uchar b = (dw-->0 && *p++ != transparent_index); + if (dw-->0 && *p++ != transparent_index) b |= 2; + if (dw-->0 && *p++ != transparent_index) b |= 4; + if (dw-->0 && *p++ != transparent_index) b |= 8; + if (dw-->0 && *p++ != transparent_index) b |= 16; + if (dw-->0 && *p++ != transparent_index) b |= 32; + if (dw-->0 && *p++ != transparent_index) b |= 64; + if (dw-->0 && *p++ != transparent_index) b |= 128; + *bitmap++ = b; + } + } else { + uchar b = 0, bit = 1; + for (int X = 0; X < d.w; X++) { + int ind = *p++; + ind = (ind<<8) | (*p++); + if (ind != transparent_index) b |= bit; + + if (bit < 128) bit <<= 1; + else { + *bitmap++ = b; + b = 0; + bit = 1; + } + } + + if (bit > 1) *bitmap++ = b; + } + } + } + + fl_draw_image(chars_per_pixel==1 ? cb1 : cb2, &d, x, y, d.w, d.h, 4); + +#else // __APPLE_QUARTZ__ + + bool transparent = (transparent_index>=0); + transparent = true; + U32 *array = new U32[d.w * d.h], *q = array; + for (int Y = 0; Y < d.h; Y++) { + const uchar* p = data[Y]; + if (chars_per_pixel <= 1) { + for (int X = 0; X < d.w; X++) { + *q++ = d.colors[*p++]; + } + } else { + for (int X = 0; X < d.w; X++) { + U32* colors = d.byte1[*p++]; + *q++ = colors[*p++]; + } + } + } + CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB(); + CGDataProviderRef src = CGDataProviderCreateWithData( 0L, array, d.w * d.h * 4, 0L); + CGImageRef img = CGImageCreate(d.w, d.h, 8, 4*8, 4*d.w, + lut, transparent?kCGImageAlphaLast:kCGImageAlphaNoneSkipLast, + src, 0L, false, kCGRenderingIntentDefault); + CGColorSpaceRelease(lut); + CGDataProviderRelease(src); + CGRect rect = { { x, y} , { d.w, d.h } }; + Fl_X::q_begin_image(rect, 0, 0, d.w, d.h); + CGContextDrawImage(fl_gc, rect, img); + Fl_X::q_end_image(); + CGImageRelease(img); + delete array; + +#endif // !__APPLE_QUARTZ__ + + if (chars_per_pixel > 1) for (int i = 0; i < 256; i++) delete[] d.byte1[i]; + return 1; +} + +// +// End of "$Id: fl_draw_pixmap.cxx 6026 2008-02-14 18:17:06Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_encoding_latin1.cxx b/plugins/zynaddsubfx/fltk/src/fl_encoding_latin1.cxx new file mode 100644 index 000000000..1e61f4bf2 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_encoding_latin1.cxx @@ -0,0 +1,137 @@ +// +// "$Id: fl_encoding_latin1.cxx 5408 2006-09-04 18:46:28Z matt $" +// +// Convert MSWindows-1252 (Latin-1) encoded text to the local encoding. +// +// Copyright 1998-2006 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include "flstring.h" + +#ifdef __APPLE__ + +// These function assume a western code page. If you need to support +// scripts that are not part of this code page, you might want to +// take a look at FLTK2, which uses utf8 for text encoding. +// +// By keeping these conversion tables in their own module, they will not +// be statically linked (by a smart linker) unless actually used. +// +// On MS-Windows, nothing need to be converted. We simply return the +// original pointer. +// +// Most X11 implementations seem to default to Latin-1 as a code since it +// is a superset of ISO 8859-1, the original wetsern codepage on X11. +// +// Apple's OS X however renders text in MacRoman for western settings. The +// lookup tables below will convert all common character codes and replace +// unknown characters with an upsidedown question mark. + +// This table converts MSWindows-1252/Latin 1 into MacRoman encoding +static uchar latin2roman[128] = { +0xdb, 0xc0, 0xe2, 0xc4, 0xe3, 0xc9, 0xa0, 0xe0, 0xf6, 0xe4, 0xc0, 0xdc, 0xce, 0xc0, 0xc0, 0xc0, +0xc0, 0xd4, 0xd5, 0xd2, 0xd3, 0xa5, 0xd0, 0xd1, 0xf7, 0xaa, 0xc0, 0xdd, 0xcf, 0xc0, 0xc0, 0xd9, +0xca, 0xc1, 0xa2, 0xa3, 0xc0, 0xb4, 0xc0, 0xa4, 0xac, 0xa9, 0xbb, 0xc7, 0xc2, 0xc0, 0xa8, 0xf8, +0xa1, 0xb1, 0xc0, 0xc0, 0xab, 0xb5, 0xa6, 0xe1, 0xfc, 0xc0, 0xbc, 0xc8, 0xc0, 0xc0, 0xc0, 0xc0, +0xcb, 0xe7, 0xe5, 0xcc, 0x80, 0x81, 0xae, 0x82, 0xe9, 0x83, 0xe6, 0xe8, 0xed, 0xea, 0xeb, 0xec, +0xc0, 0x84, 0xf1, 0xee, 0xef, 0xcd, 0x85, 0xc0, 0xaf, 0xf4, 0xf2, 0xf3, 0x86, 0xc0, 0xc0, 0xa7, +0x88, 0x87, 0x89, 0x8b, 0x8a, 0x8c, 0xbe, 0x8d, 0x8f, 0x8e, 0x90, 0x91, 0x93, 0x92, 0x94, 0x95, +0xc0, 0x96, 0x98, 0x97, 0x99, 0x9b, 0x9a, 0xd6, 0xbf, 0x9d, 0x9c, 0x9e, 0x9f, 0xc0, 0xc0, 0xd8 +}; + +// This table converts MacRoman into MSWindows-1252/Latin 1 +static uchar roman2latin[128] = { +0xc4, 0xc5, 0xc7, 0xc9, 0xd1, 0xd6, 0xdc, 0xe1, 0xe0, 0xe2, 0xe4, 0xe3, 0xe5, 0xe7, 0xe9, 0xe8, +0xea, 0xeb, 0xed, 0xec, 0xee, 0xef, 0xf1, 0xf3, 0xf2, 0xf4, 0xf6, 0xf5, 0xfa, 0xf9, 0xfb, 0xfc, +0x86, 0xb0, 0xa2, 0xa3, 0xa7, 0x95, 0xb6, 0xdf, 0xae, 0xa9, 0x99, 0xb4, 0xa8, 0xbf, 0xc6, 0xd8, +0xbf, 0xb1, 0xbf, 0xbf, 0xa5, 0xb5, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xaa, 0xba, 0xbf, 0xe6, 0xf8, +0xbf, 0xa1, 0xac, 0xbf, 0x83, 0xbf, 0xbf, 0xab, 0xbb, 0x85, 0xa0, 0xc0, 0xc3, 0xd5, 0x8c, 0x9c, +0x96, 0x97, 0x93, 0x94, 0x91, 0x92, 0xf7, 0xbf, 0xff, 0x9f, 0xbf, 0x80, 0x8b, 0x9b, 0xbf, 0xbf, +0x87, 0xb7, 0x82, 0x84, 0x89, 0xc2, 0xca, 0xc1, 0xcb, 0xc8, 0xcd, 0xce, 0xcf, 0xcc, 0xd3, 0xd4, +0xbf, 0xd2, 0xda, 0xdb, 0xd9, 0xbf, 0x88, 0x98, 0xaf, 0xbf, 0xbf, 0xbf, 0xb8, 0xbf, 0xbf, 0xbf +}; + +static char *buf = 0; +static int n_buf = 0; + +const char *fl_latin1_to_local(const char *t, int n) +{ + if (n==-1) n = strlen(t); + if (n<=n_buf) { + n_buf = (n + 257) & 0x7fffff00; + if (buf) free(buf); + buf = (char*)malloc(n_buf); + } + const uchar *src = (const uchar*)t; + uchar *dst = (uchar*)buf; + for ( ; n>0; n--) { + uchar c = *src++; + if (c>127) + *dst = latin2roman[c-128]; + else + *dst = c; + } + //*dst = 0; // this would be wrong! + return buf; +} + +const char *fl_local_to_latin1(const char *t, int n) +{ + if (n==-1) n = strlen(t); + if (n<=n_buf) { + n_buf = (n + 257) & 0x7fffff00; + if (buf) free(buf); + buf = (char*)malloc(n_buf); + } + const uchar *src = (const uchar*)t; + uchar *dst = (uchar*)buf; + for ( ; n>0; n--) { + uchar c = *src++; + if (c>127) + *dst++ = roman2latin[c-128]; + else + *dst++ = c; + } + //*dst = 0; // this would be wrong + return buf; +} + +#else + +const char *fl_latin1_to_local(const char *t, int) +{ + return t; +} + +const char *fl_local_to_latin1(const char *t, int) +{ + return t; +} + +#endif + +// +// End of "$Id: fl_encoding_latin1.cxx 5408 2006-09-04 18:46:28Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_encoding_mac_roman.cxx b/plugins/zynaddsubfx/fltk/src/fl_encoding_mac_roman.cxx new file mode 100644 index 000000000..23acdc626 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_encoding_mac_roman.cxx @@ -0,0 +1,134 @@ +// +// "$Id: fl_encoding_mac_roman.cxx 5913 2007-06-18 13:03:39Z matt $" +// +// Convert Mac Roman encoded text to the local encoding. +// +// Copyright 1998-2006 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include "flstring.h" + +// These function assume a western code page. If you need to support +// scripts that are not part of this code page, you might want to +// take a look at FLTK2, which uses utf8 for text encoding. +// +// By keeping these conversion tables in their own module, they will not +// be statically linked (by a smart linker) unless actually used. +// +// On Mac OS X, nothing need to be converted. We simply return the +// original pointer. +// +// MSWindows and X11 render text in ISO or Latin-1 for western settings. The +// lookup tables below will convert all common character codes and replace +// unknown characters with an upsidedown question mark. + +#ifdef __APPLE__ + +const char *fl_mac_roman_to_local(const char *t, int) +{ + return t; +} + +const char *fl_local_to_mac_roman(const char *t, int) +{ + return t; +} + +#else + +// This table converts MSWindows-1252/Latin 1 into MacRoman encoding +static uchar latin2roman[128] = { +0xdb, 0xc0, 0xe2, 0xc4, 0xe3, 0xc9, 0xa0, 0xe0, 0xf6, 0xe4, 0xc0, 0xdc, 0xce, 0xc0, 0xc0, 0xc0, +0xc0, 0xd4, 0xd5, 0xd2, 0xd3, 0xa5, 0xd0, 0xd1, 0xf7, 0xaa, 0xc0, 0xdd, 0xcf, 0xc0, 0xc0, 0xd9, +0xca, 0xc1, 0xa2, 0xa3, 0xc0, 0xb4, 0xc0, 0xa4, 0xac, 0xa9, 0xbb, 0xc7, 0xc2, 0xc0, 0xa8, 0xf8, +0xa1, 0xb1, 0xc0, 0xc0, 0xab, 0xb5, 0xa6, 0xe1, 0xfc, 0xc0, 0xbc, 0xc8, 0xc0, 0xc0, 0xc0, 0xc0, +0xcb, 0xe7, 0xe5, 0xcc, 0x80, 0x81, 0xae, 0x82, 0xe9, 0x83, 0xe6, 0xe8, 0xed, 0xea, 0xeb, 0xec, +0xc0, 0x84, 0xf1, 0xee, 0xef, 0xcd, 0x85, 0xc0, 0xaf, 0xf4, 0xf2, 0xf3, 0x86, 0xc0, 0xc0, 0xa7, +0x88, 0x87, 0x89, 0x8b, 0x8a, 0x8c, 0xbe, 0x8d, 0x8f, 0x8e, 0x90, 0x91, 0x93, 0x92, 0x94, 0x95, +0xc0, 0x96, 0x98, 0x97, 0x99, 0x9b, 0x9a, 0xd6, 0xbf, 0x9d, 0x9c, 0x9e, 0x9f, 0xc0, 0xc0, 0xd8 +}; + +// This table converts MacRoman into MSWindows-1252/Latin 1 +static uchar roman2latin[128] = { +0xc4, 0xc5, 0xc7, 0xc9, 0xd1, 0xd6, 0xdc, 0xe1, 0xe0, 0xe2, 0xe4, 0xe3, 0xe5, 0xe7, 0xe9, 0xe8, +0xea, 0xeb, 0xed, 0xec, 0xee, 0xef, 0xf1, 0xf3, 0xf2, 0xf4, 0xf6, 0xf5, 0xfa, 0xf9, 0xfb, 0xfc, +0x86, 0xb0, 0xa2, 0xa3, 0xa7, 0x95, 0xb6, 0xdf, 0xae, 0xa9, 0x99, 0xb4, 0xa8, 0xbf, 0xc6, 0xd8, +0xbf, 0xb1, 0xbf, 0xbf, 0xa5, 0xb5, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xaa, 0xba, 0xbf, 0xe6, 0xf8, +0xbf, 0xa1, 0xac, 0xbf, 0x83, 0xbf, 0xbf, 0xab, 0xbb, 0x85, 0xa0, 0xc0, 0xc3, 0xd5, 0x8c, 0x9c, +0x96, 0x97, 0x93, 0x94, 0x91, 0x92, 0xf7, 0xbf, 0xff, 0x9f, 0xbf, 0x80, 0x8b, 0x9b, 0xbf, 0xbf, +0x87, 0xb7, 0x82, 0x84, 0x89, 0xc2, 0xca, 0xc1, 0xcb, 0xc8, 0xcd, 0xce, 0xcf, 0xcc, 0xd3, 0xd4, +0xbf, 0xd2, 0xda, 0xdb, 0xd9, 0xbf, 0x88, 0x98, 0xaf, 0xbf, 0xbf, 0xbf, 0xb8, 0xbf, 0xbf, 0xbf +}; + +static char *buf = 0; +static int n_buf = 0; + +const char *fl_local_to_mac_roman(const char *t, int n) +{ + if (n==-1) n = strlen(t); + if (n<=n_buf) { + n_buf = (n + 257) & 0x7fffff00; + if (buf) free(buf); + buf = (char*)malloc(n_buf); + } + const uchar *src = (const uchar*)t; + uchar *dst = (uchar*)buf; + for ( ; n>0; n--) { + uchar c = *src; + if (c>127) + *dst = latin2roman[c-128]; + else + *dst = c; + } + //*dst = 0; // this would be wrong! + return buf; +} + +const char *fl_mac_roman_to_local(const char *t, int n) +{ + if (n==-1) n = strlen(t); + if (n<=n_buf) { + n_buf = (n + 257) & 0x7fffff00; + if (buf) free(buf); + buf = (char*)malloc(n_buf); + } + const uchar *src = (const uchar*)t; + uchar *dst = (uchar*)buf; + for ( ; n>0; n--) { + uchar c = *src++; + if (c>127) + *dst++ = roman2latin[c-128]; + else + *dst++ = c; + } + //*dst = 0; // this would be wrong + return buf; +} + +#endif + +// +// End of "$Id: fl_encoding_mac_roman.cxx 5913 2007-06-18 13:03:39Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_engraved_label.cxx b/plugins/zynaddsubfx/fltk/src/fl_engraved_label.cxx new file mode 100644 index 000000000..0fe4a0f86 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_engraved_label.cxx @@ -0,0 +1,93 @@ +// +// "$Id: fl_engraved_label.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Engraved label drawing routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Drawing code for XForms style engraved & embossed labels + +#include +#include +#include + +// data[] is dx, dy, color triples + +static void innards( + const Fl_Label* o, int X, int Y, int W, int H, Fl_Align align, + int data[][3], int n) +{ + Fl_Align a1 = align; + if (a1 & FL_ALIGN_CLIP) { + fl_clip(X, Y, W, H); a1 = (Fl_Align)(a1&~FL_ALIGN_CLIP);} + fl_font((Fl_Font)o->font, o->size); + for (int i = 0; i < n; i++) { + fl_color((Fl_Color)(i < n-1 ? data[i][2] : o->color)); + fl_draw(o->value, X+data[i][0], Y+data[i][1], W, H, a1); + } + if (align & FL_ALIGN_CLIP) fl_pop_clip(); +} + +static void fl_shadow_label( + const Fl_Label* o, int X, int Y, int W, int H, Fl_Align align) +{ + static int data[2][3] = {{2,2,FL_DARK3},{0,0,0}}; + innards(o, X, Y, W, H, align, data, 2); +} + +static void fl_engraved_label( + const Fl_Label* o, int X, int Y, int W, int H, Fl_Align align) +{ + static int data[7][3] = { + {1,0,FL_LIGHT3},{1,1,FL_LIGHT3},{0,1,FL_LIGHT3}, + {-1,0,FL_DARK3},{-1,-1,FL_DARK3},{0,-1,FL_DARK3}, + {0,0,0}}; + innards(o, X, Y, W, H, align, data, 7); +} + +static void fl_embossed_label( + const Fl_Label* o, int X, int Y, int W, int H, Fl_Align align) +{ + static int data[7][3] = { + {-1,0,FL_LIGHT3},{-1,-1,FL_LIGHT3},{0,-1,FL_LIGHT3}, + {1,0,FL_DARK3},{1,1,FL_DARK3},{0,1,FL_DARK3}, + {0,0,0}}; + innards(o, X, Y, W, H, align, data, 7); +} + +Fl_Labeltype fl_define_FL_SHADOW_LABEL() { + Fl::set_labeltype(_FL_SHADOW_LABEL, fl_shadow_label, 0); + return _FL_SHADOW_LABEL; +} +Fl_Labeltype fl_define_FL_ENGRAVED_LABEL() { + Fl::set_labeltype(_FL_ENGRAVED_LABEL, fl_engraved_label, 0); + return _FL_ENGRAVED_LABEL; +} +Fl_Labeltype fl_define_FL_EMBOSSED_LABEL() { + Fl::set_labeltype(_FL_EMBOSSED_LABEL, fl_embossed_label, 0); + return _FL_EMBOSSED_LABEL; +} + +// +// End of "$Id: fl_engraved_label.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_file_dir.cxx b/plugins/zynaddsubfx/fltk/src/fl_file_dir.cxx new file mode 100644 index 000000000..ff23c2296 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_file_dir.cxx @@ -0,0 +1,178 @@ +// +// "$Id: fl_file_dir.cxx 5417 2006-09-05 09:57:41Z matt $" +// +// File chooser widget for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include "flstring.h" +#include +#include +#include + + +static Fl_File_Chooser *fc = (Fl_File_Chooser *)0; +static void (*current_callback)(const char*) = 0; +static const char *current_label = fl_ok; + + +// Do a file chooser callback... +static void callback(Fl_File_Chooser *, void*) { + if (current_callback && fc->value()) + (*current_callback)(fc->value()); +} + + +// Set the file chooser callback +void fl_file_chooser_callback(void (*cb)(const char*)) { + current_callback = cb; +} + + +// Set the "OK" button label +void fl_file_chooser_ok_label(const char *l) { + if (l) current_label = l; + else current_label = fl_ok; +} + + +// +// 'fl_file_chooser()' - Show a file chooser dialog and get a filename. +// + +char * // O - Filename or NULL +fl_file_chooser(const char *message, // I - Message in titlebar + const char *pat, // I - Filename pattern + const char *fname, // I - Initial filename selection + int relative) { // I - 0 for absolute path + static char retname[1024]; // Returned filename + + if (!fc) { + if (!fname || !*fname) fname = "."; + + fc = new Fl_File_Chooser(fname, pat, Fl_File_Chooser::CREATE, message); + fc->callback(callback, 0); + } else { + fc->type(Fl_File_Chooser::CREATE); + // see, if we use the same pattern between calls + char same_pattern = 0; + const char *fcf = fc->filter(); + if ( fcf && pat && strcmp(fcf, pat)==0) + same_pattern = 1; + else if ( (fcf==0L || *fcf==0) && (pat==0L || *pat==0) ) + same_pattern = 1; + // now set the pattern to the new pattern (even if they are the same) + fc->filter(pat); + fc->label(message); + + if (!fname) { // null pointer reuses same filename if pattern didn't change + if (!same_pattern && fc->value()) { + // if pattern is different, remove name but leave old directory: + strlcpy(retname, fc->value(), sizeof(retname)); + + char *p = strrchr(retname, '/'); + + if (p) { + // If the filename is "/foo", then the directory will be "/", not + // ""... + if (p == retname) + retname[1] = '\0'; + else + *p = '\0'; + } + // Set the directory... + fc->value(retname); + } else { + // re-use the previously selected name + } + } else if (!*fname) { // empty filename reuses directory with empty name + const char *fcv = fc->value(); + if (fcv) + strlcpy(retname, fc->value(), sizeof(retname)); + else + *retname = 0; + const char *n = fl_filename_name(retname); + if (n) *((char*)n) = 0; + fc->value(""); + fc->directory(retname); + } else { + fc->value(fname); + } + } + + fc->ok_label(current_label); + fc->show(); + + while (fc->shown()) + Fl::wait(); + + if (fc->value() && relative) { + fl_filename_relative(retname, sizeof(retname), fc->value()); + + return retname; + } else if (fc->value()) return (char *)fc->value(); + else return 0; +} + + +// +// 'fl_dir_chooser()' - Show a file chooser dialog and get a directory. +// + +char * // O - Directory or NULL +fl_dir_chooser(const char *message, // I - Message for titlebar + const char *fname, // I - Initial directory name + int relative) // I - 0 for absolute +{ + static char retname[1024]; // Returned directory name + + if (!fc) { + if (!fname || !*fname) fname = "."; + + fc = new Fl_File_Chooser(fname, "*", Fl_File_Chooser::CREATE | + Fl_File_Chooser::DIRECTORY, message); + fc->callback(callback, 0); + } else { + fc->type(Fl_File_Chooser::CREATE | Fl_File_Chooser::DIRECTORY); + fc->filter("*"); + if (fname && *fname) fc->value(fname); + fc->label(message); + } + + fc->show(); + + while (fc->shown()) + Fl::wait(); + + if (fc->value() && relative) { + fl_filename_relative(retname, sizeof(retname), fc->value()); + + return retname; + } else if (fc->value()) return (char *)fc->value(); + else return 0; +} + + +// +// End of "$Id: fl_file_dir.cxx 5417 2006-09-05 09:57:41Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_font.cxx b/plugins/zynaddsubfx/fltk/src/fl_font.cxx new file mode 100644 index 000000000..a2f5fdde1 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_font.cxx @@ -0,0 +1,60 @@ +// +// "$Id: fl_font.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Font selection code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Select fonts from the FLTK font table. +#include "flstring.h" +#include +#include +#include +#include "Fl_Font.H" + +#include +#include + +#ifdef WIN32 +# include "fl_font_win32.cxx" +#elif defined(__APPLE__) +# include "fl_font_mac.cxx" +#elif USE_XFT +# include "fl_font_xft.cxx" +#else +# include "fl_font_x.cxx" +#endif // WIN32 + + +double fl_width(const char* c) { + if (c) return fl_width(c, strlen(c)); + else return 0.0f; +} + +void fl_draw(const char* str, int x, int y) { + fl_draw(str, strlen(str), x, y); +} + +// +// End of "$Id: fl_font.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_font_mac.cxx b/plugins/zynaddsubfx/fltk/src/fl_font_mac.cxx new file mode 100644 index 000000000..b83c77fdc --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_font_mac.cxx @@ -0,0 +1,379 @@ +// +// "$Id: fl_font_mac.cxx 5651 2007-02-01 20:13:57Z matt $" +// +// MacOS font selection routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include + +Fl_FontSize::Fl_FontSize(const char* name, int Size) { + next = 0; +# if HAVE_GL + listbase = 0; +# endif +#ifdef __APPLE_QD__ + knowMetrics = 0; + switch (*name++) { + case 'I': face = italic; break; + case 'P': face = italic | bold; break; + case 'B': face = bold; break; + default: face = 0; break; + } + unsigned char fn[80]; + fn[0] = strlen(name); strcpy((char*)(fn+1), name); + GetFNum(fn, &font); + size = Size; + FMInput fIn = { font, size, face, 0, 0, { 1, 1}, { 1, 1} }; + FMOutput *fOut = FMSwapFont(&fIn); + ascent = fOut->ascent; //: the following three lines give only temporary aproimations + descent = fOut->descent; + for (int i=0; i<256; i++) width[i] = fOut->widMax; + minsize = maxsize = size; +#elif defined(__APPLE_QUARTZ__) + knowWidths = 0; + // OpenGL needs those for its font handling + q_name = strdup(name); + size = Size; + OSStatus err; + // fill our structure with a few default values + ascent = Size*3/4; + descent = Size-ascent; + q_width = Size*2/3; + minsize = maxsize = Size; + // now use ATS to get the actual Glyph size information + CFStringRef cfname = CFStringCreateWithCString(0L, name, kCFStringEncodingASCII); + ATSFontRef font = ATSFontFindFromName(cfname, kATSOptionFlagsDefault); + if (font) { + ATSFontMetrics m = { 0 }; + ATSFontGetHorizontalMetrics(font, kATSOptionFlagsDefault, &m); + if (m.avgAdvanceWidth) q_width = int(m.avgAdvanceWidth*Size); + // playing with the offsets a little to make standard sizes fit + if (m.ascent) ascent = int(m.ascent*Size-0.5f); + if (m.descent) descent = -int(m.descent*Size-1.5f); + } + CFRelease(cfname); + // now we allocate everything needed to render text in this font later + // get us the default layout and style + err = ATSUCreateTextLayout(&layout); + UniChar mTxt[2] = { 65, 0 }; + err = ATSUSetTextPointerLocation(layout, mTxt, kATSUFromTextBeginning, 1, 1); + err = ATSUCreateStyle(&style); + err = ATSUSetRunStyle(layout, style, kATSUFromTextBeginning, kATSUToTextEnd); + // now set the actual font, size and attributes. We also set the font matrix to + // render our font up-side-down, so when rendered through our inverted CGContext, + // text will appear normal again. + Fixed fsize = IntToFixed(Size); + ATSUFontID fontID = FMGetFontFromATSFontRef(font); + static CGAffineTransform font_mx = { 1, 0, 0, -1, 0, 0 }; + ATSUAttributeTag sTag[] = { kATSUFontTag, kATSUSizeTag, kATSUFontMatrixTag }; + ByteCount sBytes[] = { sizeof(ATSUFontID), sizeof(Fixed), sizeof(CGAffineTransform) }; + ATSUAttributeValuePtr sAttr[] = { &fontID, &fsize, &font_mx }; + err = ATSUSetAttributes(style, 3, sTag, sBytes, sAttr); + // next, make sure that Quartz will only render at integer coordinates + ATSLineLayoutOptions llo = kATSLineUseDeviceMetrics|kATSLineDisableAllLayoutOperations; + ATSUAttributeTag aTag[] = { kATSULineLayoutOptionsTag }; + ByteCount aBytes[] = { sizeof(ATSLineLayoutOptions) }; + ATSUAttributeValuePtr aAttr[] = { &llo }; + err = ATSUSetLineControls (layout, kATSUFromTextBeginning, 1, aTag, aBytes, aAttr); + // now we are finally ready to measure some letter to get the bounding box + Fixed bBefore, bAfter, bAscent, bDescent; + err = ATSUGetUnjustifiedBounds(layout, kATSUFromTextBeginning, 1, &bBefore, &bAfter, &bAscent, &bDescent); + // Requesting a certain height font on Mac does not guarantee that ascent+descent + // equal the requested height. fl_height will reflect the actual height that we got. + // The font "Apple Chancery" is a pretty extreme example of overlapping letters. + float fa = -FixedToFloat(bAscent), fd = -FixedToFloat(bDescent); + if (fa>0.0f && fd>0.0f) { + //float f = Size/(fa+fd); + ascent = fa; //int(fa*f+0.5f); + descent = fd; //Size - ascent; + } + int w = FixedToInt(bAfter); + if (w) + q_width = FixedToInt(bAfter); +#endif +} + +Fl_FontSize* fl_fontsize = 0L; + +Fl_FontSize::~Fl_FontSize() { +/* +#if HAVE_GL + // ++ todo: remove OpenGL font alocations +// Delete list created by gl_draw(). This is not done by this code +// as it will link in GL unnecessarily. There should be some kind +// of "free" routine pointer, or a subclass? +// if (listbase) { +// int base = font->min_char_or_byte2; +// int size = font->max_char_or_byte2-base+1; +// int base = 0; int size = 256; +// glDeleteLists(listbase+base,size); +// } +#endif + */ + if (this == fl_fontsize) fl_fontsize = 0; +#ifdef __APPLE_QUARTZ__ + ATSUDisposeTextLayout(layout); + ATSUDisposeStyle(style); +#endif +} + +//////////////////////////////////////////////////////////////// + +static Fl_Fontdesc built_in_table[] = { +#ifdef __APPLE_QD__ +{" Arial"}, +{"BArial"}, +{"IArial"}, +{"PArial"}, +{" Courier New"}, +{"BCourier New"}, +{"ICourier New"}, +{"PCourier New"}, +{" Times New Roman"}, +{"BTimes New Roman"}, +{"ITimes New Roman"}, +{"PTimes New Roman"}, +{" Symbol"}, +{" Chicago"}, +{"BChicago"}, +{" Webdings"}, +#elif defined(__APPLE_QUARTZ__) +{"Arial"}, +{"Arial Bold"}, +{"Arial Italic"}, +{"Arial Bold Italic"}, +{"Courier New"}, +{"Courier New Bold"}, +{"Courier New Italic"}, +{"Courier New Bold Italic"}, +{"Times New Roman"}, +{"Times New Roman Bold"}, +{"Times New Roman Italic"}, +{"Times New Roman Bold Italic"}, +{"Symbol"}, +{"Monaco"}, +{"Andale Mono"}, // there is no bold Monaco font on standard Mac +{"Webdings"}, +#endif +}; + +#ifdef __APPLE_QUARTZ__ +static UniChar utf16lut[128] = { + 0x00c4, 0x00c5, 0x00c7, 0x00c9, 0x00d1, 0x00d6, 0x00dc, 0x00e1, + 0x00e0, 0x00e2, 0x00e4, 0x00e3, 0x00e5, 0x00e7, 0x00e9, 0x00e8, + 0x00ea, 0x00eb, 0x00ed, 0x00ec, 0x00ee, 0x00ef, 0x00f1, 0x00f3, + 0x00f2, 0x00f4, 0x00f6, 0x00f5, 0x00fa, 0x00f9, 0x00fb, 0x00fc, + 0x2020, 0x00b0, 0x00a2, 0x00a3, 0x00a7, 0x2022, 0x00b6, 0x00df, + 0x00ae, 0x00a9, 0x2122, 0x00b4, 0x00a8, 0x2260, 0x00c6, 0x00d8, + 0x221e, 0x00b1, 0x2264, 0x2265, 0x00a5, 0x00b5, 0x2202, 0x2211, + 0x220f, 0x03c0, 0x222b, 0x00aa, 0x00ba, 0x03a9, 0x00e6, 0x00f8, + 0x00bf, 0x00a1, 0x00ac, 0x221a, 0x0192, 0x2248, 0x2206, 0x00ab, + 0x00bb, 0x2026, 0x00a0, 0x00c0, 0x00c3, 0x00d5, 0x0152, 0x0153, + 0x2013, 0x2014, 0x201c, 0x201d, 0x2018, 0x2019, 0x00f7, 0x25ca, + 0x00ff, 0x0178, 0x2044, 0x20ac, 0x2039, 0x203a, 0xfb01, 0xfb02, + 0x2021, 0x00b7, 0x201a, 0x201e, 0x2030, 0x00c2, 0x00ca, 0x00c1, + 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x00d3, 0x00d4, + 0xf8ff, 0x00d2, 0x00da, 0x00db, 0x00d9, 0x0131, 0x02c6, 0x02dc, + 0x00af, 0x02d8, 0x02d9, 0x02da, 0x00b8, 0x02dd, 0x02db, 0x02c7, +}; +static UniChar *utf16buf = 0; +static int utf16len = 0; +UniChar *fl_macToUtf16(const char *txt, int len) +{ + if ((len+1)>utf16len) { + utf16len = len+100; + free(utf16buf); + utf16buf = (UniChar*)malloc((utf16len+1)*sizeof(UniChar)); + } + int i; + unsigned char c; + const unsigned char *src = (unsigned char const*)txt; + UniChar *dst = utf16buf; + for (i=0; ifont); //: select font into current QuickDraw GC + TextFace(fl_fontsize->face); + TextSize(fl_fontsize->size); + if (!fl_fontsize->knowMetrics) { //: get the true metrics for the currnet GC + //: (fails on multiple monitors with different dpi's!) + FontInfo fi; GetFontInfo(&fi); + fl_fontsize->ascent = fi.ascent; + fl_fontsize->descent = fi.descent; + FMetricRec mr; FontMetrics(&mr); + short *f = (short*)*mr.wTabHandle; //: get the char size table + for (int i=0; i<256; i++) fl_fontsize->width[i] = f[2*i]; + fl_fontsize->knowMetrics = 1; + } +#elif defined(__APPLE_QUARTZ__) + // we will use fl_fontsize later to access the required style and layout +#else +# error : need to defined either Quartz or Quickdraw +#endif +} + +static Fl_FontSize* find(int fnum, int size) { + Fl_Fontdesc* s = fl_fonts+fnum; + if (!s->name) s = fl_fonts; // use 0 if fnum undefined + Fl_FontSize* f; + for (f = s->first; f; f = f->next) + if (f->minsize <= size && f->maxsize >= size) return f; + f = new Fl_FontSize(s->name, size); + f->next = s->first; + s->first = f; + return f; +} + +//////////////////////////////////////////////////////////////// +// Public interface: + +int fl_font_ = 0; +int fl_size_ = 0; + +void fl_font(int fnum, int size) { + if (fnum==-1) { + fl_font_ = 0; + fl_size_ = 0; + return; + } + fl_font_ = fnum; + fl_size_ = size; + fl_font(find(fnum, size)); +} + +int fl_height() { + if (fl_fontsize) return fl_fontsize->ascent+fl_fontsize->descent; + else return -1; +} + +int fl_descent() { + if (fl_fontsize) return fl_fontsize->descent; + else return -1; +} + +double fl_width(const char* txt, int n) { +#ifdef __APPLE_QD__ + return (double)TextWidth( txt, 0, n ); +#else + if (!fl_fontsize) { + fl_font(0, 12); // avoid a crash! + if (!fl_fontsize) + return 8*n; // user must select a font first! + } + if (!fl_fontsize->knowWidths) { + if (!fl_gc) { + Fl_Window *w = Fl::first_window(); + if (w) w->make_current(); + if (!fl_gc) { + if (fl_fontsize) return fl_fontsize->q_width*n; + return 8*n; + // We fall back to some internal QuickDraw port. + // The result should be the same. + } + } + char buf[2]; + for (int i=0; i<256; i++) { + OSStatus err; + buf[0] = (char)i; + // convert to UTF-16 first + UniChar *uniStr = fl_macToUtf16(buf, 1); + // now collect our ATSU resources + ATSUTextLayout layout = fl_fontsize->layout; + // activate the current GC + ByteCount iSize = sizeof(CGContextRef); + ATSUAttributeTag iTag = kATSUCGContextTag; + ATSUAttributeValuePtr iValuePtr=&fl_gc; + ATSUSetLayoutControls(layout, 1, &iTag, &iSize, &iValuePtr); + // now measure the bounding box + err = ATSUSetTextPointerLocation(layout, uniStr, kATSUFromTextBeginning, 1, 1); + Fixed bBefore, bAfter, bAscent, bDescent; + err = ATSUGetUnjustifiedBounds(layout, kATSUFromTextBeginning, 1, &bBefore, &bAfter, &bAscent, &bDescent); + fl_fontsize->width[i] = FixedToInt(bAfter); + } + fl_fontsize->knowWidths = 1; + } + int len = 0; + const char *src = txt; + for (int j=0; jwidth[c]; + } + return len; +#endif +} + +double fl_width(uchar c) { + return fl_width((const char*)(&c), 1); +} + +void fl_draw(const char *str, int n, float x, float y); + +void fl_draw(const char* str, int n, int x, int y) { +#ifdef __APPLE_QD__ + MoveTo(x, y); + DrawText((const char *)str, 0, n); +#elif defined(__APPLE_QUARTZ__) + fl_draw(str, n, (float)x-0.0f, (float)y-0.5f); +#else +# error : neither Quartz no Quickdraw chosen +#endif +} + +void fl_draw(const char *str, int n, float x, float y) { +#ifdef __APPLE_QD__ + fl_draw(str, n, (int)x, (int)y); +#elif defined(__APPLE_QUARTZ__) + OSStatus err; + // convert to UTF-16 first + UniChar *uniStr = fl_macToUtf16(str, n); + // now collect our ATSU resources + ATSUTextLayout layout = fl_fontsize->layout; + + ByteCount iSize = sizeof(CGContextRef); + ATSUAttributeTag iTag = kATSUCGContextTag; + ATSUAttributeValuePtr iValuePtr=&fl_gc; + ATSUSetLayoutControls(layout, 1, &iTag, &iSize, &iValuePtr); + + err = ATSUSetTextPointerLocation(layout, uniStr, kATSUFromTextBeginning, n, n); + err = ATSUDrawText(layout, kATSUFromTextBeginning, n, FloatToFixed(x), FloatToFixed(y)); +#else +# error : neither Quartz no Quickdraw chosen +#endif +} + +// +// End of "$Id: fl_font_mac.cxx 5651 2007-02-01 20:13:57Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_font_win32.cxx b/plugins/zynaddsubfx/fltk/src/fl_font_win32.cxx new file mode 100644 index 000000000..ee7d60096 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_font_win32.cxx @@ -0,0 +1,173 @@ +// +// "$Id: fl_font_win32.cxx 5420 2006-09-05 11:16:15Z matt $" +// +// WIN32 font selection routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +Fl_FontSize::Fl_FontSize(const char* name, int size) { + int weight = FW_NORMAL; + int italic = 0; + switch (*name++) { + case 'I': italic = 1; break; + case 'P': italic = 1; + case 'B': weight = FW_BOLD; break; + case ' ': break; + default: name--; + } + fid = CreateFont( + -size, // negative makes it use "char size" + 0, // logical average character width + 0, // angle of escapement + 0, // base-line orientation angle + weight, + italic, + FALSE, // underline attribute flag + FALSE, // strikeout attribute flag + DEFAULT_CHARSET, // character set identifier + OUT_DEFAULT_PRECIS, // output precision + CLIP_DEFAULT_PRECIS,// clipping precision + DEFAULT_QUALITY, // output quality + DEFAULT_PITCH, // pitch and family + name // pointer to typeface name string + ); + if (!fl_gc) fl_GetDC(0); + SelectObject(fl_gc, fid); + GetTextMetrics(fl_gc, &metr); +// BOOL ret = GetCharWidthFloat(fl_gc, metr.tmFirstChar, metr.tmLastChar, font->width+metr.tmFirstChar); +// ...would be the right call, but is not implemented into Window95! (WinNT?) + GetCharWidth(fl_gc, 0, 255, width); +#if HAVE_GL + listbase = 0; +#endif + minsize = maxsize = size; +} + +Fl_FontSize* fl_fontsize; + +Fl_FontSize::~Fl_FontSize() { +#if HAVE_GL +// Delete list created by gl_draw(). This is not done by this code +// as it will link in GL unnecessarily. There should be some kind +// of "free" routine pointer, or a subclass? +// if (listbase) { +// int base = font->min_char_or_byte2; +// int size = font->max_char_or_byte2-base+1; +// int base = 0; int size = 256; +// glDeleteLists(listbase+base,size); +// } +#endif + if (this == fl_fontsize) fl_fontsize = 0; + DeleteObject(fid); +} + +//////////////////////////////////////////////////////////////// + +// WARNING: if you add to this table, you must redefine FL_FREE_FONT +// in Enumerations.H & recompile!! +static Fl_Fontdesc built_in_table[] = { +{" Arial"}, +{"BArial"}, +{"IArial"}, +{"PArial"}, +{" Courier New"}, +{"BCourier New"}, +{"ICourier New"}, +{"PCourier New"}, +{" Times New Roman"}, +{"BTimes New Roman"}, +{"ITimes New Roman"}, +{"PTimes New Roman"}, +{" Symbol"}, +{" Terminal"}, +{"BTerminal"}, +{" Wingdings"}, +}; + +Fl_Fontdesc* fl_fonts = built_in_table; + +static Fl_FontSize* find(int fnum, int size) { + Fl_Fontdesc* s = fl_fonts+fnum; + if (!s->name) s = fl_fonts; // use 0 if fnum undefined + Fl_FontSize* f; + for (f = s->first; f; f = f->next) + if (f->minsize <= size && f->maxsize >= size) return f; + f = new Fl_FontSize(s->name, size); + f->next = s->first; + s->first = f; + return f; +} + +//////////////////////////////////////////////////////////////// +// Public interface: + +int fl_font_ = 0; +int fl_size_ = 0; +//static HDC font_gc; + +void fl_font(int fnum, int size) { + if (fnum==-1) { // just make sure that we will load a new font next time + fl_font_ = 0; fl_size_ = 0; + return; + } + if (fnum == fl_font_ && size == fl_size_) return; + fl_font_ = fnum; fl_size_ = size; + fl_fontsize = find(fnum, size); +} + +int fl_height() { + if (fl_fontsize) return (fl_fontsize->metr.tmAscent + fl_fontsize->metr.tmDescent); + else return -1; +} + +int fl_descent() { + if (fl_fontsize) return fl_fontsize->metr.tmDescent; + else return -1; +} + +double fl_width(const char* c, int n) { + if (!fl_fontsize) return -1.0; + double w = 0.0; + while (n--) w += fl_fontsize->width[uchar(*c++)]; + return w; +} + +double fl_width(uchar c) { + if (fl_fontsize) return fl_fontsize->width[c]; + else return -1.0; +} + +void fl_draw(const char* str, int n, int x, int y) { + COLORREF oldColor = SetTextColor(fl_gc, fl_RGB()); + if (fl_fontsize) SelectObject(fl_gc, fl_fontsize->fid); + TextOut(fl_gc, x, y, str, n); + SetTextColor(fl_gc, oldColor); +} + +void fl_draw(const char* str, int n, float x, float y) { + fl_draw(str, n, (int)x, (int)y); +} + +// +// End of "$Id: fl_font_win32.cxx 5420 2006-09-05 11:16:15Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_font_x.cxx b/plugins/zynaddsubfx/fltk/src/fl_font_x.cxx new file mode 100644 index 000000000..5701c45f6 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_font_x.cxx @@ -0,0 +1,271 @@ +// +// "$Id: fl_font_x.cxx 5421 2006-09-05 11:26:41Z matt $" +// +// Standard X11 font selection code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +Fl_FontSize::Fl_FontSize(const char* name) { + font = XLoadQueryFont(fl_display, name); + if (!font) { + Fl::warning("bad font: %s", name); + font = XLoadQueryFont(fl_display, "fixed"); // if fixed fails we crash + } +# if HAVE_GL + listbase = 0; +# endif +} + +Fl_FontSize* fl_fontsize; + +Fl_FontSize::~Fl_FontSize() { +# if HAVE_GL +// Delete list created by gl_draw(). This is not done by this code +// as it will link in GL unnecessarily. There should be some kind +// of "free" routine pointer, or a subclass? +// if (listbase) { +// int base = font->min_char_or_byte2; +// int size = font->max_char_or_byte2-base+1; +// int base = 0; int size = 256; +// glDeleteLists(listbase+base,size); +// } +# endif + if (this == fl_fontsize) fl_fontsize = 0; + XFreeFont(fl_display, font); +} + +//////////////////////////////////////////////////////////////// + +// WARNING: if you add to this table, you must redefine FL_FREE_FONT +// in Enumerations.H & recompile!! +static Fl_Fontdesc built_in_table[] = { +{"-*-helvetica-medium-r-normal--*"}, +{"-*-helvetica-bold-r-normal--*"}, +{"-*-helvetica-medium-o-normal--*"}, +{"-*-helvetica-bold-o-normal--*"}, +{"-*-courier-medium-r-normal--*"}, +{"-*-courier-bold-r-normal--*"}, +{"-*-courier-medium-o-normal--*"}, +{"-*-courier-bold-o-normal--*"}, +{"-*-times-medium-r-normal--*"}, +{"-*-times-bold-r-normal--*"}, +{"-*-times-medium-i-normal--*"}, +{"-*-times-bold-i-normal--*"}, +{"-*-symbol-*"}, +{"-*-lucidatypewriter-medium-r-normal-sans-*"}, +{"-*-lucidatypewriter-bold-r-normal-sans-*"}, +{"-*-*zapf dingbats-*"} +}; + +Fl_Fontdesc* fl_fonts = built_in_table; + +#define MAXSIZE 32767 + +// return dash number N, or pointer to ending null if none: +const char* fl_font_word(const char* p, int n) { + while (*p) {if (*p=='-') {if (!--n) break;} p++;} + return p; +} + +// return a pointer to a number we think is "point size": +char* fl_find_fontsize(char* name) { + char* c = name; + // for standard x font names, try after 7th dash: + if (*c == '-') { + c = (char*)fl_font_word(c,7); + if (*c++ && isdigit(*c)) return c; + return 0; // malformed x font name? + } + char* r = 0; + // find last set of digits: + for (c++;* c; c++) + if (isdigit(*c) && !isdigit(*(c-1))) r = c; + return r; +} + +const char* fl_encoding = "iso8859-1"; + +// return true if this matches fl_encoding: +int fl_correct_encoding(const char* name) { + if (*name != '-') return 0; + const char* c = fl_font_word(name,13); + return (*c++ && !strcmp(c,fl_encoding)); +} + +// locate or create an Fl_FontSize for a given Fl_Fontdesc and size: +static Fl_FontSize* find(int fnum, int size) { + Fl_Fontdesc* s = fl_fonts+fnum; + if (!s->name) s = fl_fonts; // use font 0 if still undefined + Fl_FontSize* f; + for (f = s->first; f; f = f->next) + if (f->minsize <= size && f->maxsize >= size) return f; + fl_open_display(); + if (!s->xlist) { + s->xlist = XListFonts(fl_display, s->name, 100, &(s->n)); + if (!s->xlist) { // use fixed if no matching font... + s->first = new Fl_FontSize("fixed"); + s->first->minsize = 0; + s->first->maxsize = 32767; + return s->first; + } + } + // search for largest <= font size: + char* name = s->xlist[0]; int ptsize = 0; // best one found so far + int matchedlength = 32767; + char namebuffer[1024]; // holds scalable font name + int found_encoding = 0; + int m = s->n; if (m<0) m = -m; + for (int n=0; n < m; n++) { + + char* thisname = s->xlist[n]; + if (fl_correct_encoding(thisname)) { + if (!found_encoding) ptsize = 0; // force it to choose this + found_encoding = 1; + } else { + if (found_encoding) continue; + } + char* c = fl_find_fontsize(thisname); + int thissize = c ? atoi(c) : MAXSIZE; + int thislength = strlen(thisname); + if (thissize == size && thislength < matchedlength) { + // exact match, use it: + name = thisname; + ptsize = size; + matchedlength = thislength; + } else if (!thissize && ptsize!=size) { + // whoa! A scalable font! Use unless exact match found: + int l = c-thisname; + memcpy(namebuffer,thisname,l); + l += sprintf(namebuffer+l,"%d",size); + while (*c == '0') c++; + strcpy(namebuffer+l,c); + name = namebuffer; + ptsize = size; + } else if (!ptsize || // no fonts yet + thissize < ptsize && ptsize > size || // current font too big + thissize > ptsize && thissize <= size // current too small + ) { + name = thisname; ptsize = thissize; + matchedlength = thislength; + } + } + + if (ptsize != size) { // see if we already found this unscalable font: + for (f = s->first; f; f = f->next) { + if (f->minsize <= ptsize && f->maxsize >= ptsize) { + if (f->minsize > size) f->minsize = size; + if (f->maxsize < size) f->maxsize = size; + return f; + } + } + } + + // okay, we definately have some name, make the font: + f = new Fl_FontSize(name); + if (ptsize < size) {f->minsize = ptsize; f->maxsize = size;} + else {f->minsize = size; f->maxsize = ptsize;} + f->next = s->first; + s->first = f; + return f; + +} + +//////////////////////////////////////////////////////////////// +// Public interface: + +int fl_font_ = 0; +int fl_size_ = 0; +#if USE_XFT != 1 +XFontStruct* fl_xfont = 0; +#endif +void *fl_xftfont = 0; +static GC font_gc; + +void fl_font(int fnum, int size) { + if (fnum==-1) { + fl_font_ = 0; fl_size_ = 0; + return; + } + if (fnum == fl_font_ && size == fl_size_) return; + fl_font_ = fnum; fl_size_ = size; + Fl_FontSize* f = find(fnum, size); + if (f != fl_fontsize) { + fl_fontsize = f; + fl_xfont = f->font; + font_gc = 0; + } +} + +int fl_height() { + if (fl_xfont) return (fl_xfont->ascent + fl_xfont->descent); + else return -1; +} + +int fl_descent() { + if (fl_xfont) return fl_xfont->descent; + else return -1; +} + +double fl_width(const char* c, int n) { + if (!fl_xfont) return -1.0; + XCharStruct* p = fl_xfont->per_char; + if (!p) return n*fl_xfont->min_bounds.width; + int a = fl_xfont->min_char_or_byte2; + int b = fl_xfont->max_char_or_byte2 - a; + int w = 0; + while (n--) { + int x = *(uchar*)c++ - a; + if (x >= 0 && x <= b) w += p[x].width; + else w += fl_xfont->min_bounds.width; + } + return w; +} + +double fl_width(uchar c) { + if (!fl_xfont) return -1; + XCharStruct* p = fl_xfont->per_char; + if (p) { + int a = fl_xfont->min_char_or_byte2; + int b = fl_xfont->max_char_or_byte2 - a; + int x = c-a; + if (x >= 0 && x <= b) return p[x].width; + } + return fl_xfont->min_bounds.width; +} + +void fl_draw(const char* str, int n, int x, int y) { + if (font_gc != fl_gc) { + if (!fl_xfont) fl_font(FL_HELVETICA, 14); + font_gc = fl_gc; + XSetFont(fl_display, fl_gc, fl_xfont->fid); + } + XDrawString(fl_display, fl_window, fl_gc, x, y, str, n); +} + +void fl_draw(const char* str, int n, float x, float y) { + fl_draw(str, n, (int)x, (int)y); +} + +// +// End of "$Id: fl_font_x.cxx 5421 2006-09-05 11:26:41Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_font_xft.cxx b/plugins/zynaddsubfx/fltk/src/fl_font_xft.cxx new file mode 100644 index 000000000..318662d7c --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_font_xft.cxx @@ -0,0 +1,451 @@ +// +// "$Id: fl_font_xft.cxx 5999 2007-12-15 17:35:57Z mike $" +// +// Xft font code for the Fast Light Tool Kit (FLTK). +// +// Copyright 2001-2007 Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// +// Draw fonts using Keith Packard's Xft library to provide anti- +// aliased text. Yow! +// +// Many thanks to Carl for making the original version of this. +// +// This font code only requires libXft to work. Contrary to popular +// belief there is no need to have FreeType, or the Xrender extension +// available to use this code. You will just get normal Xlib fonts +// (Xft calls them "core" fonts) The Xft algorithms for choosing +// these is about as good as the FLTK ones (I hope to fix it so it is +// exactly as good...), plus it can cache it's results and share them +// between programs, so using this should be a win in all cases. Also +// it should be obvious by comparing this file and fl_font_x.cxx that +// it is a lot easier to program with Xft than with Xlib. +// +// Also, Xft supports UTF-8 text rendering directly, which will allow +// us to support UTF-8 on all platforms more easily. +// +// To actually get antialiasing you need the following: +// +// 1. You have XFree86 4 +// 2. You have the XRender extension +// 3. Your X device driver supports the render extension +// 4. You have libXft +// 5. Your libXft has FreeType2 support compiled in +// 6. You have the FreeType2 library +// +// Distributions that have XFree86 4.0.3 or later should have all of this... +// +// Unlike some other Xft packages, I tried to keep this simple and not +// to work around the current problems in Xft by making the "patterns" +// complicated. I belive doing this defeats our ability to improve Xft +// itself. You should edit the ~/.xftconfig file to "fix" things, there +// are several web pages of information on how to do this. +// + +#include + +// The predefined fonts that FLTK has: +static Fl_Fontdesc built_in_table[] = { +{" sans"}, +{"Bsans"}, +{"Isans"}, +{"Psans"}, +{" mono"}, +{"Bmono"}, +{"Imono"}, +{"Pmono"}, +{" serif"}, +{"Bserif"}, +{"Iserif"}, +{"Pserif"}, +{" symbol"}, +{" screen"}, +{"Bscreen"}, +{" dingbats"}, +}; + +Fl_Fontdesc* fl_fonts = built_in_table; + +#define current_font (fl_fontsize->font) + +int fl_font_ = 0; +int fl_size_ = 0; +#if USE_XFT +Fl_XFont_On_Demand fl_xfont; +#else +FL_EXPORT XFontStruct* fl_xfont; +#endif +void *fl_xftfont = 0; +const char* fl_encoding_ = "iso8859-1"; +Fl_FontSize* fl_fontsize = 0; + +void fl_font(int fnum, int size) { + if (fnum==-1) { // special case to stop font caching + fl_font_ = 0; fl_size_ = 0; + return; + } + if (fnum == fl_font_ && size == fl_size_ + && fl_fontsize + && !strcasecmp(fl_fontsize->encoding, fl_encoding_)) + return; + fl_font_ = fnum; fl_size_ = size; + Fl_Fontdesc *font = fl_fonts + fnum; + Fl_FontSize* f; + // search the fontsizes we have generated already + for (f = font->first; f; f = f->next) { + if (f->size == size && !strcasecmp(f->encoding, fl_encoding_)) + break; + } + if (!f) { + f = new Fl_FontSize(font->name); + f->next = font->first; + font->first = f; + } + fl_fontsize = f; +#if XFT_MAJOR < 2 + fl_xfont = f->font->u.core.font; +#else + fl_xfont = NULL; // invalidate +#endif // XFT_MAJOR < 2 + fl_xftfont = (void*)f->font; +} + +static XftFont* fontopen(const char* name, bool core) { + // Check: does it look like we have been passed an old-school XLFD fontname? + bool is_xlfd = false; + int hyphen_count = 0; + int comma_count = 0; + unsigned len = strlen(name); + if (len > 512) len = 512; // ensure we are not passed an unbounded font name + for(unsigned idx = 0; idx < len; idx++) { + if(name[idx] == '-') hyphen_count++; // check for XLFD hyphens + if(name[idx] == ',') comma_count++; // are there multiple names? + } + if(hyphen_count >= 14) is_xlfd = true; // Not a robust check, but good enough? + + fl_open_display(); + + if(!is_xlfd) { // Not an XLFD - open as a XFT style name + XftFont *the_font; // the font we will return; + XftPattern *fnt_pat = XftPatternCreate(); // the pattern we will use for matching + int slant = XFT_SLANT_ROMAN; + int weight = XFT_WEIGHT_MEDIUM; + + /* This "converts" FLTK-style font names back into "regular" names, extracting + * the BOLD and ITALIC codes as it does so - all FLTK font names are prefixed + * by 'I' (italic) 'B' (bold) 'P' (bold italic) or ' ' (regular) modifiers. + * This gives a fairly limited font selection ability, but is retained for + * compatability reasons. If you really need a more complex choice, you are best + * calling Fl::set_fonts(*) then selecting the font by font-index rather than by + * name anyway. Probably. + * If you want to load a font who's name does actually begin with I, B or P, you + * MUST use a leading space OR simply use lowercase for the name... + */ + /* This may be efficient, but it is non-obvious. */ + switch (*name++) { + case 'I': slant = XFT_SLANT_ITALIC; break; // italic + case 'P': slant = XFT_SLANT_ITALIC; // bold-italic (falls-through) + case 'B': weight = XFT_WEIGHT_BOLD; break; // bold + case ' ': break; // regular + default: name--; // no prefix, restore name + } + + if(comma_count) { // multiple comma-spearated names were passed + char *local_name = strdup(name); // duplicate the full name so we can edit the copy + char *curr = local_name; // points to first name in string + char *nxt; // next name in string + do { + nxt = strchr(curr, ','); // find comma seperator + if (nxt) { + *nxt = 0; // terminate first name + nxt++; // first char of next name + } + + // Add the current name to the match pattern + XftPatternAddString(fnt_pat, XFT_FAMILY, curr); + + if(nxt) curr = nxt; // move onto next name (if it exists) + // Now do a cut-down version of the FLTK name conversion. + // NOTE: we only use the slant and weight of the first name, + // subsequent names we ignore this for... But we still need to do the check. + switch (*curr++) { + case 'I': break; // italic + case 'P': // bold-italic (falls-through) + case 'B': break; // bold + case ' ': break; // regular + default: curr--; // no prefix, restore name + } + + comma_count--; // decrement name sections count + } while (comma_count >= 0); + free(local_name); // release our local copy of font names + } + else { // single name was passed - add it directly + XftPatternAddString(fnt_pat, XFT_FAMILY, name); + } + + // Construct a match pattern for the font we want... + XftPatternAddInteger(fnt_pat, XFT_WEIGHT, weight); + XftPatternAddInteger(fnt_pat, XFT_SLANT, slant); + XftPatternAddDouble (fnt_pat, XFT_PIXEL_SIZE, (double)fl_size_); + XftPatternAddString (fnt_pat, XFT_ENCODING, fl_encoding_); + if (core) { + XftPatternAddBool(fnt_pat, XFT_CORE, FcTrue); + XftPatternAddBool(fnt_pat, XFT_RENDER, FcFalse); + } + + XftPattern *match_pat; // the best available match on the system + XftResult match_result; // the result of our matching attempt + // query the system to find a match for this font + match_pat = XftFontMatch(fl_display, fl_screen, fnt_pat, &match_result); + // open the matched font + the_font = XftFontOpenPattern(fl_display, match_pat); + // Tidy up the resources we allocated + XftPatternDestroy(fnt_pat); +// XftPatternDestroy(match_pat); // FontConfig will destroy this resource for us. We must not! + return the_font; + } + else { // We were passed a font name in XLFD format + char *local_name = strdup(name); + if(comma_count) { // This means we were passed multiple XLFD's + char *pc = strchr(local_name, ','); + *pc = 0; // terminate the XLFD at the first comma + } + XftFont *the_font = XftFontOpenXlfd(fl_display, fl_screen, local_name); + free(local_name); + return the_font; + } +} // end of fontopen + +Fl_FontSize::Fl_FontSize(const char* name) { + encoding = fl_encoding_; + size = fl_size_; +#if HAVE_GL + listbase = 0; +#endif // HAVE_GL + font = fontopen(name, false); +} + +Fl_FontSize::~Fl_FontSize() { + if (this == fl_fontsize) fl_fontsize = 0; +// XftFontClose(fl_display, font); +} + +int fl_height() { + if (current_font) return current_font->ascent + current_font->descent; + else return -1; +} + +int fl_descent() { + if (current_font) return current_font->descent; + else return -1; +} + +double fl_width(const char *str, int n) { + if (!current_font) return -1.0; + XGlyphInfo i; + XftTextExtents8(fl_display, current_font, (XftChar8 *)str, n, &i); + return i.xOff; +} + +double fl_width(uchar c) { + return fl_width((const char *)(&c), 1); +} + +#if HAVE_GL +/* This code is used by opengl to get a bitmapped font. The original XFT-1 code + * used XFT's "core" fonts methods to load an XFT font that was actually a + * X-bitmap font, that could then be readily used with GL. + * But XFT-2 does not provide that ability, and there is no easy method to use + * an XFT font directly with GL. So... +*/ + +# if XFT_MAJOR > 1 +// This function attempts, on XFT2 systems, to find a suitable "core" Xfont +// for GL to use, since we dont have an XglUseXftFont(...) function. +// There's probably a better way to do this. I can't believe it is this hard... +// Anyway... This code attempts to make an XLFD out of the fltk-style font +// name it is passed, then tries to load that font. Surprisingly, this quite +// often works - boxes that have XFT generally also have a fontserver that +// can serve TTF and other fonts to X, and so the font name that fltk makes +// from the XFT name often also "exists" as an "core" X font... +// If this code fails to load the requested font, it falls back through a +// series of tried 'n tested alternatives, ultimately resorting to what the +// original fltk code did. +// NOTE: +// On my test boxes (FC6, FC7) this works well for the fltk "built-in" font names. +static XFontStruct* load_xfont_for_xft2(void) { + XFontStruct* xgl_font = 0; + int size = fl_size_; + const char *weight = "medium"; // no specifc weight requested - accept any + char slant = 'r'; // regular non-italic by default + char xlfd[128]; // we will put our synthetic XLFD in here + char *pc = strdup(fl_fonts[fl_font_].name); // what font were we asked for? + const char *name = pc; // keep a handle to the original name to free later + // Parse the "fltk-name" of the font + switch (*name++) { + case 'I': slant = 'i'; break; // italic + case 'P': slant = 'i'; // bold-italic (falls-through) + case 'B': weight = "bold"; break; // bold + case ' ': break; // regular + default: name--; // no prefix, restore name + } + + // map generic Xft names to customary XLFD faces + if (!strcmp(name, "sans")) { + name = "helvetica"; + } else if (!strcmp(name, "mono")) { + name = "courier"; + } else if (!strcmp(name, "serif")) { + name = "times"; + } else if (!strcmp(name, "screen")) { + name = "lucidatypewriter"; + } else if (!strcmp(name, "dingbats")) { + name = "zapf dingbats"; + } + + // first, we do a query with no prefered size, to see if the font exists at all + snprintf(xlfd, 128, "-*-*%s*-%s-%c-*--*-*-*-*-*-*-*-*", name, weight, slant); // make up xlfd style name + xgl_font = XLoadQueryFont(fl_display, xlfd); + if(xgl_font) { // the face exists, but can we get it in a suitable size? + XFreeFont(fl_display, xgl_font); // release the non-sized version + snprintf(xlfd, 128, "-*-*%s*-%s-%c-*--*-%d-*-*-*-*-*-*", name, weight, slant, (size*10)); + xgl_font = XLoadQueryFont(fl_display, xlfd); // attempt to load the font at the right size + } + free(pc); // release our copy of the font name + + // if we have nothing loaded, try a generic proportional font + if(!xgl_font) { + snprintf(xlfd, 128, "-*-helvetica-*-%c-*--*-%d-*-*-*-*-*-*", slant, (size*10)); + xgl_font = XLoadQueryFont(fl_display, xlfd); + } + // If that still didn't work, try this instead + if(!xgl_font) { + snprintf(xlfd, 128, "-*-courier-medium-%c-*--*-%d-*-*-*-*-*-*", slant, (size*10)); + xgl_font = XLoadQueryFont(fl_display, xlfd); + } + // Last chance fallback - this usually loads something... + if (!xgl_font) xgl_font = XLoadQueryFont(fl_display, "fixed"); + + return xgl_font; +} // end of load_xfont_for_xft2 +# endif + +XFontStruct* fl_xxfont() { +# if XFT_MAJOR > 1 + // kludge! XFT 2 and later does not provide core fonts for us to use with GL + // try to load a bitmap X font instead + static XFontStruct* xgl_font = 0; + static int glsize = 0; + static int glfont = -1; + // Do we need to load a new font? + if ((!xgl_font) || (glsize != fl_size_) || (glfont != fl_font_)) { + if (xgl_font) XFreeFont(fl_display, xgl_font); // font already loaded, free it + glsize = fl_size_; // record current font size + glfont = fl_font_; // and face + // create a dummy XLFD for some font of the appropriate size... + xgl_font = load_xfont_for_xft2(); + } + return xgl_font; +# else // XFT-1 provides a means to load a "core" font directly + if (current_font->core) return current_font->u.core.font; // is the current font a "core" font? If so, use it. + static XftFont* xftfont; + if (xftfont) XftFontClose (fl_display, xftfont); + xftfont = fontopen(fl_fonts[fl_font_].name, true); // else request XFT to load a suitable "core" font instead. + return xftfont->u.core.font; +# endif // XFT_MAJOR > 1 +} +#endif // HAVE_GL + +#if USE_OVERLAY +// Currently Xft does not work with colormapped visuals, so this probably +// does not work unless you have a true-color overlay. +extern bool fl_overlay; +extern Colormap fl_overlay_colormap; +extern XVisualInfo* fl_overlay_visual; +#endif + +// For some reason Xft produces errors if you destroy a window whose id +// still exists in an XftDraw structure. It would be nice if this is not +// true, a lot of junk is needed to try to stop this: + +static XftDraw* draw; +static Window draw_window; +#if USE_OVERLAY +static XftDraw* draw_overlay; +static Window draw_overlay_window; +#endif + +void fl_destroy_xft_draw(Window id) { + if (id == draw_window) + XftDrawChange(draw, draw_window = fl_message_window); +#if USE_OVERLAY + if (id == draw_overlay_window) + XftDrawChange(draw_overlay, draw_overlay_window = fl_message_window); +#endif +} + +void fl_draw(const char *str, int n, int x, int y) { + if ( !current_font ) { + fl_font(FL_HELVETICA, 14); + } +#if USE_OVERLAY + XftDraw*& draw = fl_overlay ? draw_overlay : ::draw; + if (fl_overlay) { + if (!draw) + draw = XftDrawCreate(fl_display, draw_overlay_window = fl_window, + fl_overlay_visual->visual, fl_overlay_colormap); + else //if (draw_overlay_window != fl_window) + XftDrawChange(draw, draw_overlay_window = fl_window); + } else +#endif + if (!draw) + draw = XftDrawCreate(fl_display, draw_window = fl_window, + fl_visual->visual, fl_colormap); + else //if (draw_window != fl_window) + XftDrawChange(draw, draw_window = fl_window); + + Region region = fl_clip_region(); + if (region && XEmptyRegion(region)) return; + XftDrawSetClip(draw, region); + + // Use fltk's color allocator, copy the results to match what + // XftCollorAllocValue returns: + XftColor color; + color.pixel = fl_xpixel(fl_color_); + uchar r,g,b; Fl::get_color(fl_color_, r,g,b); + color.color.red = ((int)r)*0x101; + color.color.green = ((int)g)*0x101; + color.color.blue = ((int)b)*0x101; + color.color.alpha = 0xffff; + + XftDrawString8(draw, &color, current_font, x, y, (XftChar8 *)str, n); +} + +void fl_draw(const char* str, int n, float x, float y) { + fl_draw(str, n, (int)x, (int)y); +} + +// +// End of "$Id: fl_font_xft.cxx 5999 2007-12-15 17:35:57Z mike $" +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_gtk.cxx b/plugins/zynaddsubfx/fltk/src/fl_gtk.cxx new file mode 100644 index 000000000..989414201 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_gtk.cxx @@ -0,0 +1,304 @@ +// +// "$Id: fl_gtk.cxx 5721 2007-02-27 19:23:24Z matt $" +// +// "GTK" drawing routines for the Fast Light Tool Kit (FLTK). +// +// These box types provide a GTK+ look, based on Red Hat's Bluecurve +// theme... +// +// Copyright 2006 by Michael Sweet. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Box drawing code for an obscure box type. +// These box types are in seperate files so they are not linked +// in if not used. + +#include +#include + +extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*); + + +static void gtk_color(Fl_Color c) { + if (Fl::draw_box_active()) fl_color(c); + else fl_color(fl_inactive(c)); +} + + +static void gtk_up_frame(int x, int y, int w, int h, Fl_Color c) { + gtk_color(fl_color_average(FL_WHITE, c, 0.5)); + fl_xyline(x + 2, y + 1, x + w - 3); + fl_yxline(x + 1, y + 2, y + h - 3); + + gtk_color(fl_color_average(FL_BLACK, c, 0.5)); + fl_begin_loop(); + fl_vertex(x, y + 2); + fl_vertex(x + 2, y); + fl_vertex(x + w - 3, y); + fl_vertex(x + w - 1, y + 2); + fl_vertex(x + w - 1, y + h - 3); + fl_vertex(x + w - 3, y + h - 1); + fl_vertex(x + 2, y + h - 1); + fl_vertex(x, y + h - 3); + fl_end_loop(); +} + + +static void gtk_up_box(int x, int y, int w, int h, Fl_Color c) { + gtk_up_frame(x, y, w, h, c); + + gtk_color(fl_color_average(FL_WHITE, c, 0.4f)); + fl_xyline(x + 2, y + 2, x + w - 3); + gtk_color(fl_color_average(FL_WHITE, c, 0.2f)); + fl_xyline(x + 2, y + 3, x + w - 3); + gtk_color(fl_color_average(FL_WHITE, c, 0.1f)); + fl_xyline(x + 2, y + 4, x + w - 3); + gtk_color(c); + fl_rectf(x + 2, y + 5, w - 4, h - 7); + gtk_color(fl_color_average(FL_BLACK, c, 0.025f)); + fl_xyline(x + 2, y + h - 4, x + w - 3); + gtk_color(fl_color_average(FL_BLACK, c, 0.05f)); + fl_xyline(x + 2, y + h - 3, x + w - 3); + gtk_color(fl_color_average(FL_BLACK, c, 0.1f)); + fl_xyline(x + 2, y + h - 2, x + w - 3); + fl_yxline(x + w - 2, y + 2, y + h - 3); +} + + +static void gtk_down_frame(int x, int y, int w, int h, Fl_Color c) { + gtk_color(fl_color_average(FL_BLACK, c, 0.5)); + fl_begin_loop(); + fl_vertex(x, y + 2); + fl_vertex(x + 2, y); + fl_vertex(x + w - 3, y); + fl_vertex(x + w - 1, y + 2); + fl_vertex(x + w - 1, y + h - 3); + fl_vertex(x + w - 3, y + h - 1); + fl_vertex(x + 2, y + h - 1); + fl_vertex(x, y + h - 3); + fl_end_loop(); + + gtk_color(fl_color_average(FL_BLACK, c, 0.1f)); + fl_xyline(x + 2, y + 1, x + w - 3); + fl_yxline(x + 1, y + 2, y + h - 3); + + gtk_color(fl_color_average(FL_BLACK, c, 0.05f)); + fl_yxline(x + 2, y + h - 2, y + 2, x + w - 2); +} + + +static void gtk_down_box(int x, int y, int w, int h, Fl_Color c) { + gtk_down_frame(x, y, w, h, c); + + gtk_color(c); + fl_rectf(x + 3, y + 3, w - 5, h - 4); + fl_yxline(x + w - 2, y + 3, y + h - 3); +} + + +static void gtk_thin_up_frame(int x, int y, int w, int h, Fl_Color c) { + gtk_color(fl_color_average(FL_WHITE, c, 0.6f)); + fl_xyline(x + 1, y, x + w - 2); + fl_yxline(x, y + 1, y + h - 2); + + gtk_color(fl_color_average(FL_BLACK, c, 0.4f)); + fl_xyline(x + 1, y + h - 1, x + w - 2); + fl_yxline(x + w - 1, y + 1, y + h - 2); +} + + +static void gtk_thin_up_box(int x, int y, int w, int h, Fl_Color c) { + gtk_thin_up_frame(x, y, w, h, c); + + gtk_color(fl_color_average(FL_WHITE, c, 0.4f)); + fl_xyline(x + 1, y + 1, x + w - 2); + gtk_color(fl_color_average(FL_WHITE, c, 0.2f)); + fl_xyline(x + 1, y + 2, x + w - 2); + gtk_color(fl_color_average(FL_WHITE, c, 0.1f)); + fl_xyline(x + 1, y + 3, x + w - 2); + gtk_color(c); + fl_rectf(x + 1, y + 4, w - 2, h - 8); + gtk_color(fl_color_average(FL_BLACK, c, 0.025f)); + fl_xyline(x + 1, y + h - 4, x + w - 2); + gtk_color(fl_color_average(FL_BLACK, c, 0.05f)); + fl_xyline(x + 1, y + h - 3, x + w - 2); + gtk_color(fl_color_average(FL_BLACK, c, 0.1f)); + fl_xyline(x + 1, y + h - 2, x + w - 2); +} + + +static void gtk_thin_down_frame(int x, int y, int w, int h, Fl_Color c) { + gtk_color(fl_color_average(FL_BLACK, c, 0.4f)); + fl_xyline(x + 1, y, x + w - 2); + fl_yxline(x, y + 1, y + h - 2); + + gtk_color(fl_color_average(FL_WHITE, c, 0.6f)); + fl_xyline(x + 1, y + h - 1, x + w - 2); + fl_yxline(x + w - 1, y + 1, y + h - 2); +} + + +static void gtk_thin_down_box(int x, int y, int w, int h, Fl_Color c) { + gtk_thin_down_frame(x, y, w, h, c); + + gtk_color(c); + fl_rectf(x + 1, y + 1, w - 2, h - 2); +} + +//------------------------ +// new GTK+ style for round buttons +#if 1 + +static void fl_arc_i(int x,int y,int w,int h,double a1,double a2) { + fl_arc(x,y,w,h,a1,a2); +} + +enum {UPPER_LEFT, LOWER_RIGHT, CLOSED, FILL}; + +static void draw(int which, int x,int y,int w,int h, int inset) +{ + if (inset*2 >= w) inset = (w-1)/2; + if (inset*2 >= h) inset = (h-1)/2; + x += inset; + y += inset; + w -= 2*inset; + h -= 2*inset; + int d = w <= h ? w : h; + if (d <= 1) return; + void (*f)(int,int,int,int,double,double); + f = (which==FILL) ? fl_pie : fl_arc_i; + if (which >= CLOSED) { + f(x+w-d, y, d, d, w<=h ? 0 : -90, w<=h ? 180 : 90); + f(x, y+h-d, d, d, w<=h ? 180 : 90, w<=h ? 360 : 270); + } else if (which == UPPER_LEFT) { + f(x+w-d, y, d, d, 45, w<=h ? 180 : 90); + f(x, y+h-d, d, d, w<=h ? 180 : 90, 225); + } else { // LOWER_RIGHT + f(x, y+h-d, d, d, 225, w<=h ? 360 : 270); + f(x+w-d, y, d, d, w<=h ? 360 : 270, 360+45); + } + if (which == FILL) { + if (w < h) + fl_rectf(x, y+d/2, w, h-(d&-2)); + else if (w > h) + fl_rectf(x+d/2, y, w-(d&-2), h); + } else { + if (w < h) { + if (which != UPPER_LEFT) fl_yxline(x+w-1, y+d/2-1, y+h-d/2+1); + if (which != LOWER_RIGHT) fl_yxline(x, y+d/2-1, y+h-d/2+1); + } else if (w > h) { + if (which != UPPER_LEFT) fl_xyline(x+d/2-1, y+h-1, x+w-d/2+1); + if (which != LOWER_RIGHT) fl_xyline(x+d/2-1, y, x+w-d/2+1); + } + } +} + +void gtk_round_up_box(int x, int y, int w, int h, Fl_Color c) { + fl_color(c); + draw(FILL, x, y, w, h, 2); + + gtk_color(fl_color_average(FL_BLACK, c, 0.025f)); + draw(LOWER_RIGHT, x+1, y, w-2, h, 2); + draw(LOWER_RIGHT, x, y, w, h, 3); + gtk_color(fl_color_average(FL_BLACK, c, 0.05f)); + draw(LOWER_RIGHT, x+1, y, w-2, h, 1); + draw(LOWER_RIGHT, x, y, w, h, 2); + gtk_color(fl_color_average(FL_BLACK, c, 0.1f)); + draw(LOWER_RIGHT, x+1, y, w-2, h, 0); + draw(LOWER_RIGHT, x, y, w, h, 1); + + gtk_color(fl_color_average(FL_WHITE, c, 0.1f)); + draw(UPPER_LEFT, x, y, w, h, 4); + draw(UPPER_LEFT, x+1, y, w-2, h, 3); + gtk_color(fl_color_average(FL_WHITE, c, 0.2f)); + draw(UPPER_LEFT, x, y, w, h, 3); + draw(UPPER_LEFT, x+1, y, w-2, h, 2); + gtk_color(fl_color_average(FL_WHITE, c, 0.4f)); + draw(UPPER_LEFT, x, y, w, h, 2); + draw(UPPER_LEFT, x+1, y, w-2, h, 1); + gtk_color(fl_color_average(FL_WHITE, c, 0.5f)); + draw(UPPER_LEFT, x, y, w, h, 1); + draw(UPPER_LEFT, x+1, y, w-2, h, 0); + + gtk_color(fl_color_average(FL_BLACK, c, 0.5f)); + draw(CLOSED, x, y, w, h, 0); +} + +void gtk_round_down_box(int x, int y, int w, int h, Fl_Color c) { + fl_color(c); + draw(FILL, x, y, w, h, 2); + + gtk_color(fl_color_average(FL_BLACK, c, 0.05f)); + draw(UPPER_LEFT, x, y, w, h, 2); + draw(UPPER_LEFT, x+1, y, w-2, h, 1); + gtk_color(fl_color_average(FL_BLACK, c, 0.1f)); + draw(UPPER_LEFT, x, y, w, h, 1); + draw(UPPER_LEFT, x+1, y, w-2, h, 0); + + gtk_color(fl_color_average(FL_BLACK, c, 0.5f)); + draw(CLOSED, x, y, w, h, 0); +} + +#else + +static void gtk_round_up_box(int x, int y, int w, int h, Fl_Color c) { + gtk_color(c); + fl_pie(x, y, w, h, 0.0, 360.0); + gtk_color(fl_color_average(FL_WHITE, c, 0.5f)); + fl_arc(x, y, w, h, 45.0, 180.0); + gtk_color(fl_color_average(FL_WHITE, c, 0.25f)); + fl_arc(x, y, w, h, 180.0, 405.0); + gtk_color(fl_color_average(FL_BLACK, c, 0.5f)); + fl_arc(x, y, w, h, 225.0, 360.0); +} + + +static void gtk_round_down_box(int x, int y, int w, int h, Fl_Color c) { + gtk_color(c); + fl_pie(x, y, w, h, 0.0, 360.0); + gtk_color(fl_color_average(FL_BLACK, c, 0.2)); + fl_arc(x + 1, y, w, h, 90.0, 210.0); + gtk_color(fl_color_average(FL_BLACK, c, 0.6)); + fl_arc(x, y, w, h, 0.0, 360.0); +} + +#endif + +Fl_Boxtype fl_define_FL_GTK_UP_BOX() { + fl_internal_boxtype(_FL_GTK_UP_BOX, gtk_up_box); + fl_internal_boxtype(_FL_GTK_DOWN_BOX, gtk_down_box); + fl_internal_boxtype(_FL_GTK_UP_FRAME, gtk_up_frame); + fl_internal_boxtype(_FL_GTK_DOWN_FRAME, gtk_down_frame); + fl_internal_boxtype(_FL_GTK_THIN_UP_BOX, gtk_thin_up_box); + fl_internal_boxtype(_FL_GTK_THIN_DOWN_BOX, gtk_thin_down_box); + fl_internal_boxtype(_FL_GTK_THIN_UP_FRAME, gtk_thin_up_frame); + fl_internal_boxtype(_FL_GTK_THIN_DOWN_FRAME, gtk_thin_down_frame); + fl_internal_boxtype(_FL_GTK_ROUND_UP_BOX, gtk_round_up_box); + fl_internal_boxtype(_FL_GTK_ROUND_DOWN_BOX, gtk_round_down_box); + + return _FL_GTK_UP_BOX; +} + + +// +// End of "$Id: fl_gtk.cxx 5721 2007-02-27 19:23:24Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_labeltype.cxx b/plugins/zynaddsubfx/fltk/src/fl_labeltype.cxx new file mode 100644 index 000000000..f96ab4514 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_labeltype.cxx @@ -0,0 +1,133 @@ +// +// "$Id: fl_labeltype.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Label drawing routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Drawing code for the (one) common label types. +// Other label types (symbols) are in their own source files +// to avoid linking if not used. + +#include +#include +#include +#include +#include + +void +fl_no_label(const Fl_Label*,int,int,int,int,Fl_Align) {} + +void +fl_normal_label(const Fl_Label* o, int X, int Y, int W, int H, Fl_Align align) +{ + fl_font(o->font, o->size); + fl_color((Fl_Color)o->color); + fl_draw(o->value, X, Y, W, H, align, o->image); +} + +void +fl_normal_measure(const Fl_Label* o, int& W, int& H) { + fl_font(o->font, o->size); + fl_measure(o->value, W, H); + if (o->image) { + if (o->image->w() > W) W = o->image->w(); + H += o->image->h(); + } +} + +#define MAX_LABELTYPE 16 + +static Fl_Label_Draw_F* table[MAX_LABELTYPE] = { + fl_normal_label, + fl_no_label, + fl_normal_label, // _FL_SHADOW_LABEL, + fl_normal_label, // _FL_ENGRAVED_LABEL, + fl_normal_label, // _FL_EMBOSSED_LABEL, + fl_no_label, // _FL_MULTI_LABEL, + fl_no_label, // _FL_ICON_LABEL, + // FL_FREE_LABELTYPE+n: + fl_no_label, fl_no_label, fl_no_label, + fl_no_label, fl_no_label, fl_no_label, + fl_no_label, fl_no_label, fl_no_label +}; + +static Fl_Label_Measure_F* measure[MAX_LABELTYPE]; + +void Fl::set_labeltype(Fl_Labeltype t,Fl_Label_Draw_F* f,Fl_Label_Measure_F*m) +{ + table[t] = f; measure[t] = m; +} + +//////////////////////////////////////////////////////////////// + +// draw label with arbitrary alignment in arbitrary box: +void Fl_Label::draw(int X, int Y, int W, int H, Fl_Align align) const { + if (!value && !image) return; + table[type](this, X, Y, W, H, align); +} + +void Fl_Label::measure(int& W, int& H) const { + if (!value && !image) { + W = H = 0; + return; + } + + Fl_Label_Measure_F* f = ::measure[type]; if (!f) f = fl_normal_measure; + f(this, W, H); +} + +// The normal call for a draw() method: +void Fl_Widget::draw_label() const { + int X = x_+Fl::box_dx(box()); + int W = w_-Fl::box_dw(box()); + if (W > 11 && align()&(FL_ALIGN_LEFT|FL_ALIGN_RIGHT)) {X += 3; W -= 6;} + draw_label(X, y_+Fl::box_dy(box()), W, h_-Fl::box_dh(box())); +} + +// draw() can use this instead to change the bounding box: +void Fl_Widget::draw_label(int X, int Y, int W, int H) const { + // quit if we are not drawing a label inside the widget: + if ((align()&15) && !(align() & FL_ALIGN_INSIDE)) return; + draw_label(X,Y,W,H,align()); +} + +// Anybody can call this to force the label to draw anywhere: +void Fl_Widget::draw_label(int X, int Y, int W, int H, Fl_Align a) const { + if (flags()&SHORTCUT_LABEL) fl_draw_shortcut = 1; + Fl_Label l1 = label_; + if (!active_r()) { + l1.color = fl_inactive((Fl_Color)l1.color); + if (l1.deimage) l1.image = l1.deimage; + } + l1.draw(X,Y,W,H,a); + fl_draw_shortcut = 0; +} + +// include these vars here so they can be referenced without including +// Fl_Input_ code: +#include + +// +// End of "$Id: fl_labeltype.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_line_style.cxx b/plugins/zynaddsubfx/fltk/src/fl_line_style.cxx new file mode 100644 index 000000000..55b59887d --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_line_style.cxx @@ -0,0 +1,165 @@ +// +// "$Id: fl_line_style.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Line style code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include "flstring.h" +#include + +#ifdef __APPLE_QUARTZ__ +float fl_quartz_line_width_ = 1.0f; +static enum CGLineCap fl_quartz_line_cap_ = kCGLineCapButt; +static enum CGLineJoin fl_quartz_line_join_ = kCGLineJoinMiter; +static float *fl_quartz_line_pattern = 0; +static int fl_quartz_line_pattern_size = 0; +void fl_quartz_restore_line_style_() { + CGContextSetLineWidth(fl_gc, fl_quartz_line_width_); + CGContextSetLineCap(fl_gc, fl_quartz_line_cap_); + CGContextSetLineJoin(fl_gc, fl_quartz_line_join_); + CGContextSetLineDash(fl_gc, 0, fl_quartz_line_pattern, fl_quartz_line_pattern_size); +} +#endif + +void fl_line_style(int style, int width, char* dashes) { +#ifdef WIN32 + // According to Bill, the "default" cap and join should be the + // "fastest" mode supported for the platform. I don't know why + // they should be different (same graphics cards, etc., right?) MRS + static DWORD Cap[4]= {PS_ENDCAP_FLAT, PS_ENDCAP_FLAT, PS_ENDCAP_ROUND, PS_ENDCAP_SQUARE}; + static DWORD Join[4]={PS_JOIN_ROUND, PS_JOIN_MITER, PS_JOIN_ROUND, PS_JOIN_BEVEL}; + int s1 = PS_GEOMETRIC | Cap[(style>>8)&3] | Join[(style>>12)&3]; + DWORD a[16]; int n = 0; + if (dashes && dashes[0]) { + s1 |= PS_USERSTYLE; + for (n = 0; n < 16 && *dashes; n++) a[n] = *dashes++; + } else { + s1 |= style & 0xff; // allow them to pass any low 8 bits for style + } + if ((style || n) && !width) width = 1; // fix cards that do nothing for 0? + LOGBRUSH penbrush = {BS_SOLID,fl_RGB(),0}; // can this be fl_brush()? + HPEN newpen = ExtCreatePen(s1, width, &penbrush, n, n ? a : 0); + if (!newpen) { + Fl::error("fl_line_style(): Could not create GDI pen object."); + return; + } + HPEN oldpen = (HPEN)SelectObject(fl_gc, newpen); + DeleteObject(oldpen); + DeleteObject(fl_current_xmap->pen); + fl_current_xmap->pen = newpen; +#elif defined(__APPLE_QD__) + // QuickDraw supports pen size and pattern, but no arbitrary line styles. + static Pattern styles[] = { + { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } }, // FL_SOLID + { { 0xf0, 0xf0, 0xf0, 0xf0, 0x0f, 0x0f, 0x0f, 0x0f } }, // FL_DASH + { { 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55 } } // FL_DOT + }; + + if (!width) width = 1; + PenSize(width, width); + + style &= 0xff; + if (style > 2) style = 2; + PenPat(styles + style); +#elif defined(__APPLE_QUARTZ__) + static enum CGLineCap Cap[4] = { kCGLineCapButt, kCGLineCapButt, + kCGLineCapRound, kCGLineCapSquare }; + static enum CGLineJoin Join[4] = { kCGLineJoinMiter, kCGLineJoinMiter, + kCGLineJoinRound, kCGLineJoinBevel }; + if (width<1) width = 1; + fl_quartz_line_width_ = (float)width; + fl_quartz_line_cap_ = Cap[(style>>8)&3]; + fl_quartz_line_join_ = Join[(style>>12)&3]; + char *d = dashes; + static float pattern[16]; + if (d && *d) { + float *p = pattern; + while (*d) { *p++ = (float)*d++; } + fl_quartz_line_pattern = pattern; + fl_quartz_line_pattern_size = d-dashes; + } else if (style & 0xff) { + char dash, dot, gap; + // adjust lengths to account for cap: + if (style & 0x200) { + dash = char(2*width); + dot = 1; + gap = char(2*width-1); + } else { + dash = char(3*width); + dot = gap = char(width); + } + float *p = pattern; + switch (style & 0xff) { + case FL_DASH: *p++ = dash; *p++ = gap; break; + case FL_DOT: *p++ = dot; *p++ = gap; break; + case FL_DASHDOT: *p++ = dash; *p++ = gap; *p++ = dot; *p++ = gap; break; + case FL_DASHDOTDOT: *p++ = dash; *p++ = gap; *p++ = dot; *p++ = gap; *p++ = dot; *p++ = gap; break; + } + fl_quartz_line_pattern_size = p-pattern; + fl_quartz_line_pattern = pattern; + } else { + fl_quartz_line_pattern = 0; fl_quartz_line_pattern_size = 0; + } + fl_quartz_restore_line_style_(); +#else + int ndashes = dashes ? strlen(dashes) : 0; + // emulate the WIN32 dash patterns on X + char buf[7]; + if (!ndashes && (style&0xff)) { + int w = width ? width : 1; + char dash, dot, gap; + // adjust lengths to account for cap: + if (style & 0x200) { + dash = char(2*w); + dot = 1; // unfortunately 0 does not work + gap = char(2*w-1); + } else { + dash = char(3*w); + dot = gap = char(w); + } + char* p = dashes = buf; + switch (style & 0xff) { + case FL_DASH: *p++ = dash; *p++ = gap; break; + case FL_DOT: *p++ = dot; *p++ = gap; break; + case FL_DASHDOT: *p++ = dash; *p++ = gap; *p++ = dot; *p++ = gap; break; + case FL_DASHDOTDOT: *p++ = dash; *p++ = gap; *p++ = dot; *p++ = gap; *p++ = dot; *p++ = gap; break; + } + ndashes = p-buf; + } + static int Cap[4] = {CapButt, CapButt, CapRound, CapProjecting}; + static int Join[4] = {JoinMiter, JoinMiter, JoinRound, JoinBevel}; + XSetLineAttributes(fl_display, fl_gc, width, + ndashes ? LineOnOffDash : LineSolid, + Cap[(style>>8)&3], Join[(style>>12)&3]); + if (ndashes) XSetDashes(fl_display, fl_gc, 0, dashes, ndashes); +#endif +} + + +// +// End of "$Id: fl_line_style.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_open_uri.cxx b/plugins/zynaddsubfx/fltk/src/fl_open_uri.cxx new file mode 100644 index 000000000..f8a9cd7ee --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_open_uri.cxx @@ -0,0 +1,370 @@ +// +// "$Id: fl_open_uri.cxx 5636 2007-01-23 20:45:28Z mike $" +// +// fl_open_uri() code for FLTK. +// +// Test with: +// +// gcc -I/fltk/dir -I/fltk/dir/src -DTEST -o fl_open_uri fl_open_uri.cxx -lfltk +// +// Copyright 2003-2007 by Michael R Sweet +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// + +// +// Include necessary headers... +// + +#include +#include +#include +#include +#include +#include "flstring.h" +#ifdef WIN32 +# include +# include +#else +# include +# include +# include +# include +#endif // WIN32 + + +// +// Local functions... +// + +#if !defined(WIN32) && !defined(__APPLE__) +static char *path_find(const char *program, char *filename, int filesize); +#endif // !WIN32 && !__APPLE__ +#ifndef WIN32 +static int run_program(const char *program, char **argv, char *msg, int msglen); +#endif // !WIN32 + + +/** + * Open the specified URI. + * + * fl_open_uri() opens the specified Uniform Resource Identifier (URI) + * using an operating-system dependent program or interface. For URIs + * using the "ftp", "http", or "https" schemes, the system default web + * browser is used to open the URI, while "mailto" and "news" URIs are + * typically opened using the system default mail reader and "file" URIs + * are opened using the file system navigator. + * + * On success, the (optional) msg buffer is filled with the command that + * was run to open the URI; on Windows, this will always be "open uri". + * + * On failure, the msg buffer is filled with an English error message. + * + * @param uri The URI to open + * @param msg Optional buffer which contains the command or error message + * @param msglen Length of optional buffer + * @return 1 on success, 0 on failure + */ + +int +fl_open_uri(const char *uri, char *msg, int msglen) { + // Supported URI schemes... + static const char * const schemes[] = { + "file://", + "ftp://", + "http://", + "https://", + "mailto:", + "news://", + NULL + }; + + // Validate the URI scheme... + int i; + for (i = 0; schemes[i]; i ++) + if (!strncmp(uri, schemes[i], strlen(schemes[i]))) + break; + + if (!schemes[i]) { + if (msg) { + char scheme[255]; + if (sscanf(uri, "%254[^:]", scheme) == 1) { + snprintf(msg, msglen, "URI scheme \"%s\" not supported.", scheme); + } else { + snprintf(msg, msglen, "Bad URI \"%s\"", uri); + } + } + + return 0; + } + +#ifdef WIN32 + if (msg) snprintf(msg, msglen, "open %s", uri); + + return (int)ShellExecute(HWND_DESKTOP, "open", uri, NULL, NULL, SW_SHOW) > 32; + +#elif defined(__APPLE__) + char *argv[3]; // Command-line arguments + + argv[0] = "open"; + argv[1] = (char *)uri; + argv[2] = 0; + + if (msg) snprintf(msg, msglen, "open %s", uri); + + return run_program("/usr/bin/open", argv, msg, msglen) != 0; + +#else // !WIN32 && !__APPLE__ + // Run any of several well-known commands to open the URI. + // + // We give preference to the Portland group's xdg-utils + // programs which run the user's preferred web browser, etc. + // based on the current desktop environment in use. We fall + // back on older standards and then finally test popular programs + // until we find one we can use. + // + // Note that we specifically do not support the MAILER and + // BROWSER environment variables because we have no idea whether + // we need to run the listed commands in a terminal program. + + char command[1024], // Command to run... + *argv[4], // Command-line arguments + remote[1024]; // Remote-mode command... + const char * const *commands; // Array of commands to check... + static const char * const browsers[] = { + "xdg-open", // Portland + "htmlview", // Freedesktop.org + "firefox", + "mozilla", + "netscape", + "konqueror", // KDE + "opera", + "hotjava", // Solaris + "mosaic", + NULL + }; + static const char * const readers[] = { + "xdg-email", // Portland + "thunderbird", + "mozilla", + "netscape", + "evolution", // GNOME + "kmailservice", // KDE + NULL + }; + static const char * const managers[] = { + "xdg-open", // Portland + "fm", // IRIX + "dtaction", // CDE + "nautilus", // GNOME + "konqueror", // KDE + NULL + }; + + // Figure out which commands to check for... + if (!strncmp(uri, "file://", 7)) commands = managers; + else if (!strncmp(uri, "mailto:", 7) || + !strncmp(uri, "news:", 5)) commands = readers; + else commands = browsers; + + // Find the command to run... + for (i = 0; commands[i]; i ++) + if (path_find(commands[i], command, sizeof(command))) break; + + if (!commands[i]) { + if (msg) { + snprintf(msg, msglen, "No helper application found for \"%s\"", uri); + } + + return 0; + } + + // Handle command-specific arguments... + argv[0] = (char *)commands[i]; + + if (!strcmp(commands[i], "firefox") || + !strcmp(commands[i], "mozilla") || + !strcmp(commands[i], "netscape") || + !strcmp(commands[i], "thunderbird")) { + // program -remote openURL(uri) + snprintf(remote, sizeof(remote), "openURL(%s)", uri); + + argv[1] = (char *)"-remote"; + argv[2] = remote; + argv[3] = 0; + } else if (!strcmp(commands[i], "dtaction")) { + // dtaction open uri + argv[1] = (char *)"open"; + argv[2] = (char *)uri; + argv[3] = 0; + } else { + // program uri + argv[1] = (char *)uri; + argv[2] = 0; + } + + if (msg) { + strlcpy(msg, argv[0], msglen); + + for (i = 1; argv[i]; i ++) { + strlcat(msg, " ", msglen); + strlcat(msg, argv[i], msglen); + } + } + + return run_program(command, argv, msg, msglen) != 0; +#endif // WIN32 +} + + +#if !defined(WIN32) && !defined(__APPLE__) +// Find a program in the path... +static char *path_find(const char *program, char *filename, int filesize) { + const char *path; // Search path + char *ptr, // Pointer into filename + *end; // End of filename buffer + + + if ((path = getenv("PATH")) == NULL) path = "/bin:/usr/bin"; + + for (ptr = filename, end = filename + filesize - 1; *path; path ++) { + if (*path == ':') { + if (ptr > filename && ptr[-1] != '/' && ptr < end) *ptr++ = '/'; + + strlcpy(ptr, program, end - ptr + 1); + + if (!access(filename, X_OK)) return filename; + + ptr = filename; + } else if (ptr < end) *ptr++ = *path; + } + + if (ptr > filename) { + if (ptr[-1] != '/' && ptr < end) *ptr++ = '/'; + + strlcpy(ptr, program, end - ptr + 1); + + if (!access(filename, X_OK)) return filename; + } + + return 0; +} +#endif // !WIN32 && !__APPLE__ + + +#ifndef WIN32 +// Run the specified program, returning 1 on success and 0 on failure +static int +run_program(const char *program, char **argv, char *msg, int msglen) { + pid_t pid; // Process ID of first child + int status; // Exit status from first child + sigset_t set, oldset; // Signal masks + + + // Block SIGCHLD while we run the program... + // + // Note that I only use the POSIX signal APIs, however older operating + // systems may either not support POSIX signals or have side effects. + // IRIX, for example, provides three separate and incompatible signal + // APIs, so it is possible that an application setting a signal handler + // via signal() or sigset() will not have its SIGCHLD signals blocked... + + sigemptyset(&set); + sigaddset(&set, SIGCHLD); + sigprocmask(SIG_BLOCK, &set, &oldset); + + // Create child processes that actually run the program for us... + if ((pid = fork()) == 0) { + // First child comes here, fork a second child and exit... + if (!fork()) { + // Second child comes here, redirect stdin/out/err to /dev/null... + close(0); + open("/dev/null", O_RDONLY); + + close(1); + open("/dev/null", O_WRONLY); + + close(2); + open("/dev/null", O_WRONLY); + + // Detach from the current process group... + setsid(); + + // Run the program... + execv(program, argv); + _exit(0); + } else { + // First child gets here, exit immediately... + _exit(0); + } + } else if (pid < 0) { + // Restore signal handling... + sigprocmask(SIG_SETMASK, &oldset, NULL); + + // Return indicating failure... + return 0; + } + + // Wait for the first child to exit... + while (waitpid(pid, &status, 0) < 0) { + if (errno != EINTR) { + // Someone else grabbed the child status... + if (msg) snprintf(msg, msglen, "waitpid(%ld) failed: %s", (long)pid, + strerror(errno)); + + // Restore signal handling... + sigprocmask(SIG_SETMASK, &oldset, NULL); + + // Return indicating failure... + return 0; + } + } + + // Restore signal handling... + sigprocmask(SIG_SETMASK, &oldset, NULL); + + // Return indicating success... + return 1; +} +#endif // !WIN32 + + +#ifdef TEST +// +// Test code... +// + +// Open the URI on the command-line... +int main(int argc, char **argv) { + char msg[1024]; + + + if (argc != 2) { + puts("Usage: fl_open_uri URI"); + return 1; + } + + if (!fl_open_uri(argv[1], msg, sizeof(msg))) { + puts(msg); + return 1; + } else return 0; +} +#endif // TEST + + +// +// End of "$Id: fl_open_uri.cxx 5636 2007-01-23 20:45:28Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_oval_box.cxx b/plugins/zynaddsubfx/fltk/src/fl_oval_box.cxx new file mode 100644 index 000000000..ff88fafca --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_oval_box.cxx @@ -0,0 +1,66 @@ +// +// "$Id: fl_oval_box.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Oval box drawing code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + + +// Less-used box types are in seperate files so they are not linked +// in if not used. + +#include +#include + +static void fl_oval_flat_box(int x, int y, int w, int h, Fl_Color c) { + fl_color(c); + fl_pie(x, y, w, h, 0, 360); +} + +static void fl_oval_frame(int x, int y, int w, int h, Fl_Color c) { + fl_color(c); + fl_arc(x, y, w, h, 0, 360); +} + +static void fl_oval_box(int x, int y, int w, int h, Fl_Color c) { + fl_oval_flat_box(x,y,w,h,c); + fl_oval_frame(x,y,w,h,FL_BLACK); +} + +static void fl_oval_shadow_box(int x, int y, int w, int h, Fl_Color c) { + fl_oval_flat_box(x+3,y+3,w,h,FL_DARK3); + fl_oval_box(x,y,w,h,c); +} + +extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*); +Fl_Boxtype fl_define_FL_OVAL_BOX() { + fl_internal_boxtype(_FL_OSHADOW_BOX,fl_oval_shadow_box); + fl_internal_boxtype(_FL_OVAL_FRAME,fl_oval_frame); + fl_internal_boxtype(_FL_OFLAT_BOX,fl_oval_flat_box); + fl_internal_boxtype(_FL_OVAL_BOX,fl_oval_box); + return _FL_OVAL_BOX; +} + +// +// End of "$Id: fl_oval_box.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_overlay.cxx b/plugins/zynaddsubfx/fltk/src/fl_overlay.cxx new file mode 100644 index 000000000..f3e5ce4d3 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_overlay.cxx @@ -0,0 +1,125 @@ +// +// "$Id: fl_overlay.cxx 5614 2007-01-18 15:25:09Z matt $" +// +// Overlay support for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Extremely limited "overlay" support. You can use this to drag out +// a rectangle in response to mouse events. It is your responsibility +// to erase the overlay before drawing anything that might intersect +// it. + +#include +#include +#ifdef __APPLE__ +#include +#endif + +//#define USE_XOR + +static int px,py,pw,ph; + +#ifndef USE_XOR +#include +static uchar *bgN = 0L, *bgS = 0L, *bgE = 0L, *bgW = 0L; +static int bgx, bgy, bgw, bgh; +#endif + +static void draw_current_rect() { +#ifdef USE_XOR +# ifdef WIN32 + int old = SetROP2(fl_gc, R2_NOT); + fl_rect(px, py, pw, ph); + SetROP2(fl_gc, old); +# elif defined(__APPLE_QD__) + PenMode( patXor ); + fl_rect(px, py, pw, ph); + PenMode( patCopy ); +# elif defined(__APPLE_QUARTZ__) + // warning: Quartz does not support xor drawing + // Use the Fl_Overlay_Window instead. + fl_color(FL_WHITE); + fl_rect(px, py, pw, ph); +# else + XSetFunction(fl_display, fl_gc, GXxor); + XSetForeground(fl_display, fl_gc, 0xffffffff); + XDrawRectangle(fl_display, fl_window, fl_gc, px, py, pw, ph); + XSetFunction(fl_display, fl_gc, GXcopy); +# endif +#else + if (bgN) { free(bgN); bgN = 0L; } + if (bgS) { free(bgS); bgS = 0L; } + if (bgE) { free(bgE); bgE = 0L; } + if (bgW) { free(bgW); bgW = 0L; } + if (pw>0 && ph>0) { + bgE = fl_read_image(0L, px+pw-1, py, 1, ph); + bgW = fl_read_image(0L, px, py, 1, ph); + bgS = fl_read_image(0L, px, py+ph-1, pw, 1); + bgN = fl_read_image(0L, px, py, pw, 1); + bgx = px; bgy = py; + bgw = pw; bgh = ph; + } + fl_color(FL_WHITE); + fl_line_style(FL_SOLID); + fl_rect(px, py, pw, ph); + fl_color(FL_BLACK); + fl_line_style(FL_DOT); + fl_rect(px, py, pw, ph); + fl_line_style(FL_SOLID); +#endif +} + +static void erase_current_rect() { +#ifdef USE_XOR +# ifdef __APPLE_QUARTZ__ + fl_rect(px, py, pw, ph); +# else + draw_current_rect(); +# endif +#else + if (bgN) fl_draw_image(bgN, bgx, bgy, bgw, 1); + if (bgS) fl_draw_image(bgS, bgx, bgy+bgh-1, bgw, 1); + if (bgW) fl_draw_image(bgW, bgx, bgy, 1, bgh); + if (bgE) fl_draw_image(bgE, bgx+bgw-1, bgy, 1, bgh); +#endif +} + +void fl_overlay_clear() { + if (pw > 0) {erase_current_rect(); pw = 0;} +} + +void fl_overlay_rect(int x, int y, int w, int h) { + if (w < 0) {x += w; w = -w;} else if (!w) w = 1; + if (h < 0) {y += h; h = -h;} else if (!h) h = 1; + if (pw > 0) { + if (x==px && y==py && w==pw && h==ph) return; + erase_current_rect(); + } + px = x; py = y; pw = w; ph = h; + draw_current_rect(); +} + +// +// End of "$Id: fl_overlay.cxx 5614 2007-01-18 15:25:09Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_overlay_visual.cxx b/plugins/zynaddsubfx/fltk/src/fl_overlay_visual.cxx new file mode 100644 index 000000000..d0a1ae7eb --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_overlay_visual.cxx @@ -0,0 +1,105 @@ +// +// "$Id: fl_overlay_visual.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// X overlay support for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Return an overlay visual, if any. Also allocate a colormap and +// record the depth for fl_color() to use. +// Another disgusting X interface, based on code extracted and +// purified with great difficulty from XLayerUtil.cxx: + +#include +#if HAVE_OVERLAY +#include +#include + +// SERVER_OVERLAY_VISUALS property element: +struct OverlayInfo { + long overlay_visual; + long transparent_type; + long value; + long layer; +}; + +extern Colormap fl_overlay_colormap; +extern XVisualInfo* fl_overlay_visual; +extern ulong fl_transparent_pixel; + +XVisualInfo *fl_find_overlay_visual() { + static char beenhere; + if (beenhere) return fl_overlay_visual; + beenhere = 1; + + fl_open_display(); + Atom overlayVisualsAtom = + XInternAtom(fl_display,"SERVER_OVERLAY_VISUALS",1); + if (!overlayVisualsAtom) return 0; + OverlayInfo *overlayInfo; + ulong sizeData, bytesLeft; + Atom actualType; + int actualFormat; + if (XGetWindowProperty(fl_display, RootWindow(fl_display, fl_screen), + overlayVisualsAtom, 0L, 10000L, False, + overlayVisualsAtom, &actualType, &actualFormat, + &sizeData, &bytesLeft, + (unsigned char **) &overlayInfo)) return 0; + + if (actualType == overlayVisualsAtom && actualFormat == 32) { + int n = int(sizeData/4); + XVisualInfo* v = 0; + // find the greatest depth that has a transparent pixel: + for (int i = 0; i < n; i++) { + if (overlayInfo[i].transparent_type != 1) continue; + if (overlayInfo[i].layer <= 0) continue; + XVisualInfo templt; + templt.visualid = overlayInfo[i].overlay_visual; + int num; + XVisualInfo *v1=XGetVisualInfo(fl_display, VisualIDMask, &templt, &num); + if (v1->screen == fl_screen && v1->c_class == PseudoColor + && (!v || v1->depth > v->depth && v1->depth <= 8)) { + if (v) XFree((char*)v); + v = v1; + fl_transparent_pixel = overlayInfo[i].value; + } else { + XFree((char*)v1); + } + } + if (v) { + fl_overlay_visual = v; + fl_overlay_colormap = + XCreateColormap(fl_display, RootWindow(fl_display, fl_screen), + v->visual, AllocNone); + } + } + XFree((char*)overlayInfo); + //printf("overlay visual %ld selected\n", fl_overlay_visual->visualid); + return fl_overlay_visual; +} + +#endif + +// +// End of "$Id: fl_overlay_visual.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_plastic.cxx b/plugins/zynaddsubfx/fltk/src/fl_plastic.cxx new file mode 100644 index 000000000..fe253182d --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_plastic.cxx @@ -0,0 +1,381 @@ +// +// "$Id: fl_plastic.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// "Plastic" drawing routines for the Fast Light Tool Kit (FLTK). +// +// These box types provide a cross between Aqua and KDE buttons; kindof +// like translucent plastic buttons... +// +// Copyright 2001-2005 by Michael Sweet. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Box drawing code for an obscure box type. +// These box types are in seperate files so they are not linked +// in if not used. + +#include +#include +#include "flstring.h" + +// +// Uncomment the following line to restore the old plastic box type +// appearance. +// + +//#define USE_OLD_PLASTIC_BOX +#define USE_OLD_PLASTIC_COLOR + +extern uchar *fl_gray_ramp(); + +inline Fl_Color shade_color(uchar gc, Fl_Color bc) { +#ifdef USE_OLD_PLASTIC_COLOR + return fl_color_average((Fl_Color)gc, bc, 0.75f); +#else + unsigned grgb = Fl::get_color((Fl_Color)gc), + brgb = Fl::get_color(bc); + int red, green, blue, gray; + + + gray = ((grgb >> 24) & 255); + red = gray * ((brgb >> 24) & 255) / 255 + gray * gray / 510; + gray = ((grgb >> 16) & 255); + green = gray * ((brgb >> 16) & 255) / 255 + gray * gray / 510; + gray = ((grgb >> 8) & 255); + blue = gray * ((brgb >> 8) & 255) / 255 + gray * gray / 510; + + if (red > 255) + red = 255; + + if (green > 255) + green = 255; + + if (blue > 255) + blue = 255; + + if (Fl::draw_box_active()) + return fl_rgb_color(red, green, blue); + else + return fl_color_average(FL_GRAY, fl_rgb_color(red, green, blue), 0.75f); +#endif // USE_OLD_PLASTIC_COLOR +} + + +static void frame_rect(int x, int y, int w, int h, const char *c, Fl_Color bc) { + uchar *g = fl_gray_ramp(); + int b = strlen(c) / 4 + 1; + + for (x += b, y += b, w -= 2 * b, h -= 2 * b; b > 1; b --) + { + // Draw lines around the perimeter of the button, 4 colors per + // circuit. + fl_color(shade_color(g[*c++], bc)); + fl_line(x, y + h + b, x + w - 1, y + h + b, x + w + b - 1, y + h); + fl_color(shade_color(g[*c++], bc)); + fl_line(x + w + b - 1, y + h, x + w + b - 1, y, x + w - 1, y - b); + fl_color(shade_color(g[*c++], bc)); + fl_line(x + w - 1, y - b, x, y - b, x - b, y); + fl_color(shade_color(g[*c++], bc)); + fl_line(x - b, y, x - b, y + h, x, y + h + b); + } +} + + +static void frame_round(int x, int y, int w, int h, const char *c, Fl_Color bc) { + uchar *g = fl_gray_ramp(); + int b = strlen(c) / 4 + 1; + + if (w==h) { + for (; b > 1; b --, x ++, y ++, w -= 2, h -= 2) + { + fl_color(shade_color(g[*c++], bc)); + fl_arc(x, y, w, h, 45.0, 135.0); + fl_color(shade_color(g[*c++], bc)); + fl_arc(x, y, w, h, 315.0, 405.0); + fl_color(shade_color(g[*c++], bc)); + fl_arc(x, y, w, h, 225.0, 315.0); + fl_color(shade_color(g[*c++], bc)); + fl_arc(x, y, w, h, 135.0, 225.0); + } + } else if (w>h) { + int d = h/2; + for (; b > 1; d--, b --, x ++, y ++, w -= 2, h -= 2) + { + fl_color(shade_color(g[*c++], bc)); + fl_arc(x, y, h, h, 90.0, 135.0); + fl_xyline(x+d, y, x+w-d); + fl_arc(x+w-h, y, h, h, 45.0, 90.0); + fl_color(shade_color(g[*c++], bc)); + fl_arc(x+w-h, y, h, h, 315.0, 405.0); + fl_color(shade_color(g[*c++], bc)); + fl_arc(x+w-h, y, h, h, 270.0, 315.0); + fl_xyline(x+d, y+h-1, x+w-d); + fl_arc(x, y, h, h, 225.0, 270.0); + fl_color(shade_color(g[*c++], bc)); + fl_arc(x, y, h, h, 135.0, 225.0); + } + } else if (w 1; d--, b --, x ++, y ++, w -= 2, h -= 2) + { + fl_color(shade_color(g[*c++], bc)); + fl_arc(x, y, w, w, 45.0, 135.0); + fl_color(shade_color(g[*c++], bc)); + fl_arc(x, y, w, w, 0.0, 45.0); + fl_yxline(x+w-1, y+d, y+h-d); + fl_arc(x, y+h-w, w, w, 315.0, 360.0); + fl_color(shade_color(g[*c++], bc)); + fl_arc(x, y+h-w, w, w, 225.0, 315.0); + fl_color(shade_color(g[*c++], bc)); + fl_arc(x, y+h-w, w, w, 180.0, 225.0); + fl_yxline(x, y+d, y+h-d); + fl_arc(x, y, w, w, 135.0, 180.0); + } + } +} + + +static void shade_rect(int x, int y, int w, int h, const char *c, Fl_Color bc) { + uchar *g = fl_gray_ramp(); + int i, j; + int clen = strlen(c) - 1; + int chalf = clen / 2; + int cstep = 1; + + if (h < (w * 2)) { + // Horizontal shading... + if (clen >= h) cstep = 2; + + for (i = 0, j = 0; j < chalf; i ++, j += cstep) { + // Draw the top line and points... + fl_color(shade_color(g[c[i]], bc)); + fl_xyline(x + 1, y + i, x + w - 2); + + fl_color(shade_color(g[c[i] - 2], bc)); + fl_point(x, y + i + 1); + fl_point(x + w - 1, y + i + 1); + + // Draw the bottom line and points... + fl_color(shade_color(g[c[clen - i]], bc)); + fl_xyline(x + 1, y + h - i, x + w - 2); + + fl_color(shade_color(g[c[clen - i] - 2], bc)); + fl_point(x, y + h - i); + fl_point(x + w - 1, y + h - i); + } + + // Draw the interior and sides... + i = chalf / cstep; + + fl_color(shade_color(g[c[chalf]], bc)); + fl_rectf(x + 1, y + i, w - 2, h - 2 * i + 1); + + fl_color(shade_color(g[c[chalf] - 2], bc)); + fl_yxline(x, y + i, y + h - i); + fl_yxline(x + w - 1, y + i, y + h - i); + } else { + // Vertical shading... + if (clen >= w) cstep = 2; + + for (i = 0, j = 0; j < chalf; i ++, j += cstep) { + // Draw the left line and points... + fl_color(shade_color(g[c[i]], bc)); + fl_yxline(x + i, y + 1, y + h - 1); + + fl_color(shade_color(g[c[i] - 2], bc)); + fl_point(x + i + 1, y); + fl_point(x + i + 1, y + h); + + // Draw the right line and points... + fl_color(shade_color(g[c[clen - i]], bc)); + fl_yxline(x + w - 1 - i, y + 1, y + h - 1); + + fl_color(shade_color(g[c[clen - i] - 2], bc)); + fl_point(x + w - 2 - i, y); + fl_point(x + w - 2 - i, y + h); + } + + // Draw the interior, top, and bottom... + i = chalf / cstep; + + fl_color(shade_color(g[c[chalf]], bc)); + fl_rectf(x + i, y + 1, w - 2 * i, h - 1); + + fl_color(shade_color(g[c[chalf] - 2], bc)); + fl_xyline(x + i, y, x + w - i); + fl_xyline(x + i, y + h, x + w - i); + } +} + +static void shade_round(int x, int y, int w, int h, const char *c, Fl_Color bc) { + uchar *g = fl_gray_ramp(); + int i; + int clen = strlen(c) - 1; + int chalf = clen / 2; + + if (w>h) { + int d = h/2; + const int na = 8; + for (i=0; i 1) { + fl_xyline(x+1, y, x+w-2); + fl_xyline(x+1, y+h-1, x+w-2); + } + if (h > 1) { + fl_yxline(x, y+1, y+h-2); + fl_yxline(x+w-1, y+1, y+h-2); + } +} + + +static void thin_up_box(int x, int y, int w, int h, Fl_Color c) { +#ifdef USE_OLD_PLASTIC_BOX + shade_rect(x + 2, y + 2, w - 4, h - 5, "RVQNOPQRSTUVWVQ", c); + up_frame(x, y, w, h, c); +#else + if (w > 4 && h > 4) { + shade_rect(x + 1, y + 1, w - 2, h - 3, "RQOQSUWQ", c); + frame_rect(x, y, w, h - 1, "IJLM", c); + } else { + narrow_thin_box(x, y, w, h, c); + } +#endif // USE_OLD_PLASTIC_BOX +} + + +static void up_box(int x, int y, int w, int h, Fl_Color c) { +#ifdef USE_OLD_PLASTIC_BOX + shade_rect(x + 2, y + 2, w - 4, h - 5, "RVQNOPQRSTUVWVQ", c); + up_frame(x, y, w, h, c); +#else + if (w > 8 && h > 8) { + shade_rect(x + 1, y + 1, w - 2, h - 3, "RVQNOPQRSTUVWVQ", c); + frame_rect(x, y, w, h - 1, "IJLM", c); + } else { + thin_up_box(x, y, w, h, c); + } +#endif // USE_OLD_PLASTIC_BOX +} + + +static void up_round(int x, int y, int w, int h, Fl_Color c) { + shade_round(x, y, w, h, "RVQNOPQRSTUVWVQ", c); + frame_round(x, y, w, h, "IJLM", c); +} + + +static void down_frame(int x, int y, int w, int h, Fl_Color c) { + frame_rect(x, y, w, h - 1, "LLLLTTRR", c); +} + + +static void down_box(int x, int y, int w, int h, Fl_Color c) { + if (w > 6 && h > 6) { + shade_rect(x + 2, y + 2, w - 4, h - 5, "STUVWWWVT", c); + down_frame(x, y, w, h, c); + } + else { + narrow_thin_box(x, y, w, h, c); + } +} + + +static void down_round(int x, int y, int w, int h, Fl_Color c) { + shade_round(x, y, w, h, "STUVWWWVT", c); + frame_round(x, y, w, h, "IJLM", c); +} + + +extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*); + + +Fl_Boxtype fl_define_FL_PLASTIC_UP_BOX() { + fl_internal_boxtype(_FL_PLASTIC_UP_BOX, up_box); + fl_internal_boxtype(_FL_PLASTIC_DOWN_BOX, down_box); + fl_internal_boxtype(_FL_PLASTIC_UP_FRAME, up_frame); + fl_internal_boxtype(_FL_PLASTIC_DOWN_FRAME, down_frame); + fl_internal_boxtype(_FL_PLASTIC_THIN_UP_BOX, thin_up_box); + fl_internal_boxtype(_FL_PLASTIC_THIN_DOWN_BOX, down_box); + fl_internal_boxtype(_FL_PLASTIC_ROUND_UP_BOX, up_round); + fl_internal_boxtype(_FL_PLASTIC_ROUND_DOWN_BOX, down_round); + + return _FL_PLASTIC_UP_BOX; +} + + +// +// End of "$Id: fl_plastic.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_read_image.cxx b/plugins/zynaddsubfx/fltk/src/fl_read_image.cxx new file mode 100644 index 000000000..054670fd9 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_read_image.cxx @@ -0,0 +1,491 @@ +// +// "$Id: fl_read_image.cxx 6065 2008-03-09 17:58:10Z matt $" +// +// X11 image reading routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include +#include "flstring.h" + +#ifdef DEBUG +# include +#endif // DEBUG + +#ifdef WIN32 +# include "fl_read_image_win32.cxx" +#elif defined(__APPLE__) +# include "fl_read_image_mac.cxx" +#else +# include +# ifdef __sgi +# include +# else +# include +# endif // __sgi + +// Defined in fl_color.cxx +extern uchar fl_redmask, fl_greenmask, fl_bluemask; +extern int fl_redshift, fl_greenshift, fl_blueshift, fl_extrashift; + +// +// 'fl_subimage_offsets()' - Calculate subimage offsets for an axis +static inline int +fl_subimage_offsets(int a, int aw, int b, int bw, int &obw) +{ + int off; + int ob; + + if (b >= a) { + ob = b; + off = 0; + } else { + ob = a; + off = a - b; + } + + bw -= off; + + if (ob + bw <= a + aw) { + obw = bw; + } else { + obw = (a + aw) - ob; + } + + return off; +} + + +// +// 'fl_read_image()' - Read an image from the current window. +// + +uchar * // O - Pixel buffer or NULL if failed +fl_read_image(uchar *p, // I - Pixel buffer or NULL to allocate + int X, // I - Left position + int Y, // I - Top position + int w, // I - Width of area to read + int h, // I - Height of area to read + int alpha) { // I - Alpha value for image (0 for none) + XImage *image; // Captured image + int i, maxindex; // Looping vars + int x, y; // Current X & Y in image + int d; // Depth of image + unsigned char *line, // Array to hold image row + *line_ptr; // Pointer to current line image + unsigned char *pixel; // Current color value + XColor colors[4096]; // Colors from the colormap... + unsigned char cvals[4096][3]; // Color values from the colormap... + unsigned index_mask, + index_shift, + red_mask, + red_shift, + green_mask, + green_shift, + blue_mask, + blue_shift; + + + // + // Under X11 we have the option of the XGetImage() interface or SGI's + // ReadDisplay extension which does all of the really hard work for + // us... + // + +# ifdef __sgi + if (XReadDisplayQueryExtension(fl_display, &i, &i)) { + image = XReadDisplay(fl_display, fl_window, X, Y, w, h, 0, NULL); + } else +# else + image = 0; +# endif // __sgi + + if (!image) { + // fetch absolute coordinates + int dx, dy, sx, sy, sw, sh; + Window child_win; + Fl_Window *win = fl_find(fl_window); + if (win) { + XTranslateCoordinates(fl_display, fl_window, + RootWindow(fl_display, fl_screen), X, Y, &dx, &dy, &child_win); + // screen dimensions + Fl::screen_xywh(sx, sy, sw, sh, fl_screen); + } + if (!win || (dx >= sx && dy >= sy && dx + w <= sw && dy + h <= sh)) { + // the image is fully contained, we can use the traditional method + image = XGetImage(fl_display, fl_window, X, Y, w, h, AllPlanes, ZPixmap); + } else { + // image is crossing borders, determine visible region + int nw, nh, noffx, noffy; + noffx = fl_subimage_offsets(sx, sw, dx, w, nw); + noffy = fl_subimage_offsets(sy, sh, dy, h, nh); + if (nw <= 0 || nh <= 0) return 0; + + // allocate the image + int bpp = fl_visual->depth + ((fl_visual->depth / 8) % 2) * 8; + char* buf = (char*)malloc(bpp / 8 * w * h); + image = XCreateImage(fl_display, fl_visual->visual, + fl_visual->depth, ZPixmap, 0, buf, w, h, bpp, 0); + if (!image) { + if (buf) free(buf); + return 0; + } + + if (!XGetSubImage(fl_display, fl_window, X + noffx, Y + noffy, + nw, nh, AllPlanes, ZPixmap, image, noffx, noffy)) { + XDestroyImage(image); + return 0; + } + } + } + + if (!image) return 0; + +#ifdef DEBUG + printf("width = %d\n", image->width); + printf("height = %d\n", image->height); + printf("xoffset = %d\n", image->xoffset); + printf("format = %d\n", image->format); + printf("data = %p\n", image->data); + printf("byte_order = %d\n", image->byte_order); + printf("bitmap_unit = %d\n", image->bitmap_unit); + printf("bitmap_bit_order = %d\n", image->bitmap_bit_order); + printf("bitmap_pad = %d\n", image->bitmap_pad); + printf("depth = %d\n", image->depth); + printf("bytes_per_line = %d\n", image->bytes_per_line); + printf("bits_per_pixel = %d\n", image->bits_per_pixel); + printf("red_mask = %08x\n", image->red_mask); + printf("green_mask = %08x\n", image->green_mask); + printf("blue_mask = %08x\n", image->blue_mask); + printf("map_entries = %d\n", fl_visual->visual->map_entries); +#endif // DEBUG + + d = alpha ? 4 : 3; + + // Allocate the image data array as needed... + if (!p) p = new uchar[w * h * d]; + + // Initialize the default colors/alpha in the whole image... + memset(p, alpha, w * h * d); + + // Check that we have valid mask/shift values... + if (!image->red_mask && image->bits_per_pixel > 12) { + // Greater than 12 bits must be TrueColor... + image->red_mask = fl_visual->visual->red_mask; + image->green_mask = fl_visual->visual->green_mask; + image->blue_mask = fl_visual->visual->blue_mask; + +#ifdef DEBUG + puts("\n---- UPDATED ----"); + printf("fl_redmask = %08x\n", fl_redmask); + printf("fl_redshift = %d\n", fl_redshift); + printf("fl_greenmask = %08x\n", fl_greenmask); + printf("fl_greenshift = %d\n", fl_greenshift); + printf("fl_bluemask = %08x\n", fl_bluemask); + printf("fl_blueshift = %d\n", fl_blueshift); + printf("red_mask = %08x\n", image->red_mask); + printf("green_mask = %08x\n", image->green_mask); + printf("blue_mask = %08x\n", image->blue_mask); +#endif // DEBUG + } + + // Check if we have colormap image... + if (!image->red_mask) { + // Get the colormap entries for this window... + maxindex = fl_visual->visual->map_entries; + + for (i = 0; i < maxindex; i ++) colors[i].pixel = i; + + XQueryColors(fl_display, fl_colormap, colors, maxindex); + + for (i = 0; i < maxindex; i ++) { + cvals[i][0] = colors[i].red >> 8; + cvals[i][1] = colors[i].green >> 8; + cvals[i][2] = colors[i].blue >> 8; + } + + // Read the pixels and output an RGB image... + for (y = 0; y < image->height; y ++) { + pixel = (unsigned char *)(image->data + y * image->bytes_per_line); + line = p + y * w * d; + + switch (image->bits_per_pixel) { + case 1 : + for (x = image->width, line_ptr = line, index_mask = 128; + x > 0; + x --, line_ptr += d) { + if (*pixel & index_mask) { + line_ptr[0] = cvals[1][0]; + line_ptr[1] = cvals[1][1]; + line_ptr[2] = cvals[1][2]; + } else { + line_ptr[0] = cvals[0][0]; + line_ptr[1] = cvals[0][1]; + line_ptr[2] = cvals[0][2]; + } + + if (index_mask > 1) { + index_mask >>= 1; + } else { + index_mask = 128; + pixel ++; + } + } + break; + + case 2 : + for (x = image->width, line_ptr = line, index_shift = 6; + x > 0; + x --, line_ptr += d) { + i = (*pixel >> index_shift) & 3; + + line_ptr[0] = cvals[i][0]; + line_ptr[1] = cvals[i][1]; + line_ptr[2] = cvals[i][2]; + + if (index_shift > 0) { + index_mask >>= 2; + index_shift -= 2; + } else { + index_mask = 192; + index_shift = 6; + pixel ++; + } + } + break; + + case 4 : + for (x = image->width, line_ptr = line, index_shift = 4; + x > 0; + x --, line_ptr += d) { + if (index_shift == 4) i = (*pixel >> 4) & 15; + else i = *pixel & 15; + + line_ptr[0] = cvals[i][0]; + line_ptr[1] = cvals[i][1]; + line_ptr[2] = cvals[i][2]; + + if (index_shift > 0) { + index_shift = 0; + } else { + index_shift = 4; + pixel ++; + } + } + break; + + case 8 : + for (x = image->width, line_ptr = line; + x > 0; + x --, line_ptr += d, pixel ++) { + line_ptr[0] = cvals[*pixel][0]; + line_ptr[1] = cvals[*pixel][1]; + line_ptr[2] = cvals[*pixel][2]; + } + break; + + case 12 : + for (x = image->width, line_ptr = line, index_shift = 0; + x > 0; + x --, line_ptr += d) { + if (index_shift == 0) { + i = ((pixel[0] << 4) | (pixel[1] >> 4)) & 4095; + } else { + i = ((pixel[1] << 8) | pixel[2]) & 4095; + } + + line_ptr[0] = cvals[i][0]; + line_ptr[1] = cvals[i][1]; + line_ptr[2] = cvals[i][2]; + + if (index_shift == 0) { + index_shift = 4; + } else { + index_shift = 0; + pixel += 3; + } + } + break; + } + } + } else { + // RGB(A) image, so figure out the shifts & masks... + red_mask = image->red_mask; + red_shift = 0; + + while ((red_mask & 1) == 0) { + red_mask >>= 1; + red_shift ++; + } + + green_mask = image->green_mask; + green_shift = 0; + + while ((green_mask & 1) == 0) { + green_mask >>= 1; + green_shift ++; + } + + blue_mask = image->blue_mask; + blue_shift = 0; + + while ((blue_mask & 1) == 0) { + blue_mask >>= 1; + blue_shift ++; + } + + // Read the pixels and output an RGB image... + for (y = 0; y < image->height; y ++) { + pixel = (unsigned char *)(image->data + y * image->bytes_per_line); + line = p + y * w * d; + + switch (image->bits_per_pixel) { + case 8 : + for (x = image->width, line_ptr = line; + x > 0; + x --, line_ptr += d, pixel ++) { + i = *pixel; + + line_ptr[0] = 255 * ((i >> red_shift) & red_mask) / red_mask; + line_ptr[1] = 255 * ((i >> green_shift) & green_mask) / green_mask; + line_ptr[2] = 255 * ((i >> blue_shift) & blue_mask) / blue_mask; + } + break; + + case 12 : + for (x = image->width, line_ptr = line, index_shift = 0; + x > 0; + x --, line_ptr += d) { + if (index_shift == 0) { + i = ((pixel[0] << 4) | (pixel[1] >> 4)) & 4095; + } else { + i = ((pixel[1] << 8) | pixel[2]) & 4095; + } + + line_ptr[0] = 255 * ((i >> red_shift) & red_mask) / red_mask; + line_ptr[1] = 255 * ((i >> green_shift) & green_mask) / green_mask; + line_ptr[2] = 255 * ((i >> blue_shift) & blue_mask) / blue_mask; + + if (index_shift == 0) { + index_shift = 4; + } else { + index_shift = 0; + pixel += 3; + } + } + break; + + case 16 : + if (image->byte_order == LSBFirst) { + // Little-endian... + for (x = image->width, line_ptr = line; + x > 0; + x --, line_ptr += d, pixel += 2) { + i = (pixel[1] << 8) | pixel[0]; + + line_ptr[0] = 255 * ((i >> red_shift) & red_mask) / red_mask; + line_ptr[1] = 255 * ((i >> green_shift) & green_mask) / green_mask; + line_ptr[2] = 255 * ((i >> blue_shift) & blue_mask) / blue_mask; + } + } else { + // Big-endian... + for (x = image->width, line_ptr = line; + x > 0; + x --, line_ptr += d, pixel += 2) { + i = (pixel[0] << 8) | pixel[1]; + + line_ptr[0] = 255 * ((i >> red_shift) & red_mask) / red_mask; + line_ptr[1] = 255 * ((i >> green_shift) & green_mask) / green_mask; + line_ptr[2] = 255 * ((i >> blue_shift) & blue_mask) / blue_mask; + } + } + break; + + case 24 : + if (image->byte_order == LSBFirst) { + // Little-endian... + for (x = image->width, line_ptr = line; + x > 0; + x --, line_ptr += d, pixel += 3) { + i = (((pixel[2] << 8) | pixel[1]) << 8) | pixel[0]; + + line_ptr[0] = 255 * ((i >> red_shift) & red_mask) / red_mask; + line_ptr[1] = 255 * ((i >> green_shift) & green_mask) / green_mask; + line_ptr[2] = 255 * ((i >> blue_shift) & blue_mask) / blue_mask; + } + } else { + // Big-endian... + for (x = image->width, line_ptr = line; + x > 0; + x --, line_ptr += d, pixel += 3) { + i = (((pixel[0] << 8) | pixel[1]) << 8) | pixel[2]; + + line_ptr[0] = 255 * ((i >> red_shift) & red_mask) / red_mask; + line_ptr[1] = 255 * ((i >> green_shift) & green_mask) / green_mask; + line_ptr[2] = 255 * ((i >> blue_shift) & blue_mask) / blue_mask; + } + } + break; + + case 32 : + if (image->byte_order == LSBFirst) { + // Little-endian... + for (x = image->width, line_ptr = line; + x > 0; + x --, line_ptr += d, pixel += 4) { + i = (((((pixel[3] << 8) | pixel[2]) << 8) | pixel[1]) << 8) | pixel[0]; + + line_ptr[0] = 255 * ((i >> red_shift) & red_mask) / red_mask; + line_ptr[1] = 255 * ((i >> green_shift) & green_mask) / green_mask; + line_ptr[2] = 255 * ((i >> blue_shift) & blue_mask) / blue_mask; + } + } else { + // Big-endian... + for (x = image->width, line_ptr = line; + x > 0; + x --, line_ptr += d, pixel += 4) { + i = (((((pixel[0] << 8) | pixel[1]) << 8) | pixel[2]) << 8) | pixel[3]; + + line_ptr[0] = 255 * ((i >> red_shift) & red_mask) / red_mask; + line_ptr[1] = 255 * ((i >> green_shift) & green_mask) / green_mask; + line_ptr[2] = 255 * ((i >> blue_shift) & blue_mask) / blue_mask; + } + } + break; + } + } + } + + // Destroy the X image we've read and return the RGB(A) image... + XDestroyImage(image); + + return p; +} + +#endif + +// +// End of "$Id: fl_read_image.cxx 6065 2008-03-09 17:58:10Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_read_image_mac.cxx b/plugins/zynaddsubfx/fltk/src/fl_read_image_mac.cxx new file mode 100644 index 000000000..1c015aac8 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_read_image_mac.cxx @@ -0,0 +1,137 @@ +// +// "$Id: fl_read_image_mac.cxx 5614 2007-01-18 15:25:09Z matt $" +// +// WIN32 image reading routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2006 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include + +// warning: this function is only implemented in Quickdraw. The function +// below may not work If FLTK is compiled with Quartz enabled + +// +// 'fl_read_image()' - Read an image from the current window. +// + +uchar * // O - Pixel buffer or NULL if failed +fl_read_image(uchar *p, // I - Pixel buffer or NULL to allocate + int x, // I - Left position + int y, // I - Top position + int w, // I - Width of area to read + int h, // I - Height of area to read + int alpha) { // I - Alpha value for image (0 for none) + Rect src, // Source rectangle + dst; // Destination rectangle + GWorldPtr osbuffer; // Temporary off-screen buffer for copy + GrafPtr srcPort; // Source port + RGBColor rgb; // RGB colors for copy mask... + PixMapHandle pm; // Pixmap handle for off-screen buffer + uchar *base, // Base address of off-screen buffer + *psrc, // Pointer into off-screen buffer + *pdst; // Pointer into pixel buffer + int idx, idy; // Current X & Y in image + int d; // Depth of image + int rowBytes; // Number of bytes per row... + + // Set the source and destination rectangles... + src.top = y; + src.left = x; + src.bottom = y + h; + src.right = x + w; + + dst.top = 0; + dst.left = 0; + dst.bottom = h; + dst.right = w; + + // Get an off-screen buffer for copying the image... + QDErr err = NewGWorld(&osbuffer, 0, &dst, 0L, 0L, 0); + if (!osbuffer) return 0; + if (err!=noErr) { + DisposeGWorld(osbuffer); + return 0; + } + + // Get the source port... + GetPort(&srcPort); + + // Set the RGB copy mask via the foreground/background colors... + rgb.red = 0xffff; + rgb.green = 0xffff; + rgb.blue = 0xffff; + RGBBackColor(&rgb); + + rgb.red = 0x0000; + rgb.green = 0x0000; + rgb.blue = 0x0000; + RGBForeColor(&rgb); + + // Copy the screen image to the off-screen buffer... + CopyBits(GetPortBitMapForCopyBits(srcPort), + GetPortBitMapForCopyBits(osbuffer), &src, &dst, srcCopy, 0L); + + // Allocate the image data array as needed... + d = alpha ? 4 : 3; + + if (!p) p = new uchar[w * h * d]; + + // Initialize the default colors/alpha in the whole image... + memset(p, alpha, w * h * d); + + // Set the correct port for the off-screen buffer and lock the buffer + SetGWorld(osbuffer, 0); + + pm = GetGWorldPixMap(osbuffer); + LockPixels(pm); + + base = (uchar *)GetPixBaseAddr(pm); + rowBytes = (*pm)->rowBytes & 0x3fff; + + // Copy the image from the off-screen buffer to the memory buffer. + for (idy = 0, pdst = p; idy < h; idy ++) +#ifdef __i386__ + for (idx = 0, psrc = base + idy * rowBytes; idx < w; idx ++, psrc += 4, pdst += d) { + pdst[0] = psrc[2]; + pdst[1] = psrc[1]; + pdst[2] = psrc[0]; + } +#else + for (idx = 0, psrc = base + idy * rowBytes + 1; idx < w; idx ++, psrc += 4, pdst += d) { + pdst[0] = psrc[0]; + pdst[1] = psrc[1]; + pdst[2] = psrc[2]; + } +#endif // __i386__ + // Unlock and delete the off-screen buffer, then return... + UnlockPixels(pm); + DisposeGWorld(osbuffer); + + SetPort(srcPort); + return p; +} + + +// +// End of "$Id: fl_read_image_mac.cxx 5614 2007-01-18 15:25:09Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_read_image_win32.cxx b/plugins/zynaddsubfx/fltk/src/fl_read_image_win32.cxx new file mode 100644 index 000000000..8d651f4f8 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_read_image_win32.cxx @@ -0,0 +1,72 @@ +// +// "$Id: fl_read_image_win32.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// WIN32 image reading routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// +// 'fl_read_image()' - Read an image from the current window. +// + +uchar * // O - Pixel buffer or NULL if failed +fl_read_image(uchar *p, // I - Pixel buffer or NULL to allocate + int X, // I - Left position + int Y, // I - Top position + int w, // I - Width of area to read + int h, // I - Height of area to read + int alpha) { // I - Alpha value for image (0 for none) + int x, y; // Looping vars + int d; // Depth of image + uchar *ptr; // Pointer in image data + + + // Allocate the image data array as needed... + d = alpha ? 4 : 3; + + if (!p) p = new uchar[w * h * d]; + + // Initialize the default colors/alpha in the whole image... + memset(p, alpha, w * h * d); + + // Grab all of the pixels in the image, one at a time... + // MRS: there has to be a better way than this! + for (y = 0, ptr = p; y < h; y ++) { + for (x = 0; x < w; x ++, ptr += d) { + COLORREF c = GetPixel(fl_gc, X + x, Y + y); + + ptr[0] = (uchar)c; + c >>= 8; + ptr[1] = (uchar)c; + c >>= 8; + ptr[2] = (uchar)c; + } + } + + return p; +} + + +// +// End of "$Id: fl_read_image_win32.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_rect.cxx b/plugins/zynaddsubfx/fltk/src/fl_rect.cxx new file mode 100644 index 000000000..501cdec8c --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_rect.cxx @@ -0,0 +1,685 @@ +// +// "$Id: fl_rect.cxx 5692 2007-02-12 16:41:41Z matt $" +// +// Rectangle drawing routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// These routines from fl_draw.H are used by the standard boxtypes +// and thus are always linked into an fltk program. +// Also all fl_clip routines, since they are always linked in so +// that minimal update works. + +#include +#include +#include +#include +#include + +#ifdef __APPLE_QUARTZ__ +extern float fl_quartz_line_width_; +#endif + +void fl_rect(int x, int y, int w, int h) { + if (w<=0 || h<=0) return; +#ifdef WIN32 + MoveToEx(fl_gc, x, y, 0L); + LineTo(fl_gc, x+w-1, y); + LineTo(fl_gc, x+w-1, y+h-1); + LineTo(fl_gc, x, y+h-1); + LineTo(fl_gc, x, y); +#elif defined(__APPLE_QD__) + Rect rect; + SetRect(&rect, x, y, x+w, y+h); + FrameRect(&rect); +#elif defined(__APPLE_QUARTZ__) + if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false); + CGRect rect = CGRectMake(x, y, w-1, h-1); + CGContextStrokeRect(fl_gc, rect); + if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true); +#else + XDrawRectangle(fl_display, fl_window, fl_gc, x, y, w-1, h-1); +#endif +} + +void fl_rectf(int x, int y, int w, int h) { + if (w<=0 || h<=0) return; +#ifdef WIN32 + RECT rect; + rect.left = x; rect.top = y; + rect.right = x + w; rect.bottom = y + h; + FillRect(fl_gc, &rect, fl_brush()); +#elif defined(__APPLE_QD__) + Rect rect; + SetRect(&rect, x, y, x+w, y+h); + PaintRect(&rect); +#elif defined(__APPLE_QUARTZ__) + if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false); + CGRect rect = CGRectMake(x, y, w-1, h-1); + CGContextFillRect(fl_gc, rect); + if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true); +#else + if (w && h) XFillRectangle(fl_display, fl_window, fl_gc, x, y, w, h); +#endif +} + +void fl_xyline(int x, int y, int x1) { +#ifdef WIN32 + MoveToEx(fl_gc, x, y, 0L); LineTo(fl_gc, x1+1, y); +#elif defined(__APPLE_QD__) + MoveTo(x, y); LineTo(x1, y); +#elif defined(__APPLE_QUARTZ__) + if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false); + CGContextMoveToPoint(fl_gc, x, y); + CGContextAddLineToPoint(fl_gc, x1, y); + CGContextStrokePath(fl_gc); + if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true); +#else + XDrawLine(fl_display, fl_window, fl_gc, x, y, x1, y); +#endif +} + +void fl_xyline(int x, int y, int x1, int y2) { +#ifdef WIN32 + if (y2 < y) y2--; + else y2++; + MoveToEx(fl_gc, x, y, 0L); + LineTo(fl_gc, x1, y); + LineTo(fl_gc, x1, y2); +#elif defined(__APPLE_QD__) + MoveTo(x, y); + LineTo(x1, y); + LineTo(x1, y2); +#elif defined(__APPLE_QUARTZ__) + if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false); + CGContextMoveToPoint(fl_gc, x, y); + CGContextAddLineToPoint(fl_gc, x1, y); + CGContextAddLineToPoint(fl_gc, x1, y2); + CGContextStrokePath(fl_gc); + if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true); +#else + XPoint p[3]; + p[0].x = x; p[0].y = p[1].y = y; + p[1].x = p[2].x = x1; p[2].y = y2; + XDrawLines(fl_display, fl_window, fl_gc, p, 3, 0); +#endif +} + +void fl_xyline(int x, int y, int x1, int y2, int x3) { +#ifdef WIN32 + if(x3 < x1) x3--; + else x3++; + MoveToEx(fl_gc, x, y, 0L); + LineTo(fl_gc, x1, y); + LineTo(fl_gc, x1, y2); + LineTo(fl_gc, x3, y2); +#elif defined(__APPLE_QD__) + MoveTo(x, y); + LineTo(x1, y); + LineTo(x1, y2); + LineTo(x3, y2); +#elif defined(__APPLE_QUARTZ__) + if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false); + CGContextMoveToPoint(fl_gc, x, y); + CGContextAddLineToPoint(fl_gc, x1, y); + CGContextAddLineToPoint(fl_gc, x1, y2); + CGContextAddLineToPoint(fl_gc, x3, y2); + CGContextStrokePath(fl_gc); + if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true); +#else + XPoint p[4]; + p[0].x = x; p[0].y = p[1].y = y; + p[1].x = p[2].x = x1; p[2].y = p[3].y = y2; + p[3].x = x3; + XDrawLines(fl_display, fl_window, fl_gc, p, 4, 0); +#endif +} + +void fl_yxline(int x, int y, int y1) { +#ifdef WIN32 + if (y1 < y) y1--; + else y1++; + MoveToEx(fl_gc, x, y, 0L); LineTo(fl_gc, x, y1); +#elif defined(__APPLE_QD__) + MoveTo(x, y); LineTo(x, y1); +#elif defined(__APPLE_QUARTZ__) + if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false); + CGContextMoveToPoint(fl_gc, x, y); + CGContextAddLineToPoint(fl_gc, x, y1); + CGContextStrokePath(fl_gc); + if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true); +#else + XDrawLine(fl_display, fl_window, fl_gc, x, y, x, y1); +#endif +} + +void fl_yxline(int x, int y, int y1, int x2) { +#ifdef WIN32 + if (x2 > x) x2++; + else x2--; + MoveToEx(fl_gc, x, y, 0L); + LineTo(fl_gc, x, y1); + LineTo(fl_gc, x2, y1); +#elif defined(__APPLE_QD__) + MoveTo(x, y); + LineTo(x, y1); + LineTo(x2, y1); +#elif defined(__APPLE_QUARTZ__) + if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, false); + CGContextMoveToPoint(fl_gc, x, y); + CGContextAddLineToPoint(fl_gc, x, y1); + CGContextAddLineToPoint(fl_gc, x2, y1); + CGContextStrokePath(fl_gc); + if (fl_quartz_line_width_==1.0f) CGContextSetShouldAntialias(fl_gc, true); +#else + XPoint p[3]; + p[0].x = p[1].x = x; p[0].y = y; + p[1].y = p[2].y = y1; p[2].x = x2; + XDrawLines(fl_display, fl_window, fl_gc, p, 3, 0); +#endif +} + +void fl_yxline(int x, int y, int y1, int x2, int y3) { +#ifdef WIN32 + if(y3 0 && h > 0) { + r = XRectangleRegion(x,y,w,h); + Fl_Region current = rstack[rstackptr]; + if (current) { +#ifdef WIN32 + CombineRgn(r,r,current,RGN_AND); +#elif defined(__APPLE_QD__) + SectRgn(r, current, r); +#elif defined(__APPLE_QUARTZ__) + SectRgn(r, current, r); +#else + Fl_Region temp = XCreateRegion(); + XIntersectRegion(current, r, temp); + XDestroyRegion(r); + r = temp; +#endif + } + } else { // make empty clip region: +#ifdef WIN32 + r = CreateRectRgn(0,0,0,0); +#elif defined(__APPLE_QD__) + r = NewRgn(); + SetEmptyRgn(r); +#elif defined(__APPLE_QUARTZ__) + r = NewRgn(); + SetEmptyRgn(r); +#else + r = XCreateRegion(); +#endif + } + if (rstackptr < STACK_MAX) rstack[++rstackptr] = r; + else Fl::warning("fl_push_clip: clip stack overflow!\n"); + fl_restore_clip(); +} + +// make there be no clip (used by fl_begin_offscreen() only!) +void fl_push_no_clip() { + if (rstackptr < STACK_MAX) rstack[++rstackptr] = 0; + else Fl::warning("fl_push_no_clip: clip stack overflow!\n"); + fl_restore_clip(); +} + +// pop back to previous clip: +void fl_pop_clip() { + if (rstackptr > 0) { + Fl_Region oldr = rstack[rstackptr--]; + if (oldr) XDestroyRegion(oldr); + } else Fl::warning("fl_pop_clip: clip stack underflow!\n"); + fl_restore_clip(); +} + +// does this rectangle intersect current clip? +int fl_not_clipped(int x, int y, int w, int h) { + if (x+w <= 0 || y+h <= 0) return 0; + Fl_Region r = rstack[rstackptr]; +#ifdef WIN32 + if (!r) return 1; + RECT rect; + rect.left = x; rect.top = y; rect.right = x+w; rect.bottom = y+h; + return RectInRegion(r,&rect); +#elif defined(__APPLE_QD__) + if (!r) return 1; + Rect rect; + rect.left = x; rect.top = y; rect.right = x+w; rect.bottom = y+h; + return RectInRgn(&rect, r); +#elif defined(__APPLE_QUARTZ__) + if (!r) return 1; + Rect rect; + rect.left = x; rect.top = y; rect.right = x+w; rect.bottom = y+h; + return RectInRgn(&rect, r); +#else + return r ? XRectInRegion(r, x, y, w, h) : 1; +#endif +} + +// return rectangle surrounding intersection of this rectangle and clip: +int fl_clip_box(int x, int y, int w, int h, int& X, int& Y, int& W, int& H){ + X = x; Y = y; W = w; H = h; + Fl_Region r = rstack[rstackptr]; + if (!r) return 0; +#ifdef WIN32 +// The win32 API makes no distinction between partial and complete +// intersection, so we have to check for partial intersection ourselves. +// However, given that the regions may be composite, we have to do +// some voodoo stuff... + Fl_Region rr = XRectangleRegion(x,y,w,h); + Fl_Region temp = CreateRectRgn(0,0,0,0); + int ret; + if (CombineRgn(temp, rr, r, RGN_AND) == NULLREGION) { // disjoint + W = H = 0; + ret = 2; + } else if (EqualRgn(temp, rr)) { // complete + ret = 0; + } else { // parital intersection + RECT rect; + GetRgnBox(temp, &rect); + X = rect.left; Y = rect.top; W = rect.right - X; H = rect.bottom - Y; + ret = 1; + } + DeleteObject(temp); + DeleteObject(rr); + return ret; +#elif defined(__APPLE_QD__) + RgnHandle rr = NewRgn(); + SetRectRgn( rr, x, y, x+w, y+h ); + SectRgn( r, rr, rr ); + Rect rp; GetRegionBounds(rr, &rp); + X = rp.left; + Y = rp.top; + W = rp.right - X; + H = rp.bottom - Y; + DisposeRgn( rr ); + if ( H==0 ) return 2; + if ( h==H && w==W ) return 0; + return 0; +#elif defined(__APPLE_QUARTZ__) + RgnHandle rr = NewRgn(); + SetRectRgn( rr, x, y, x+w, y+h ); + SectRgn( r, rr, rr ); + Rect rp; GetRegionBounds(rr, &rp); + X = rp.left; + Y = rp.top; + W = rp.right - X; + H = rp.bottom - Y; + DisposeRgn( rr ); + if ( H==0 ) return 2; + if ( h==H && w==W ) return 0; + return 0; +#else + switch (XRectInRegion(r, x, y, w, h)) { + case 0: // completely outside + W = H = 0; + return 2; + case 1: // completely inside: + return 0; + default: // partial: + break; + } + Fl_Region rr = XRectangleRegion(x,y,w,h); + Fl_Region temp = XCreateRegion(); + XIntersectRegion(r, rr, temp); + XRectangle rect; + XClipBox(temp, &rect); + X = rect.x; Y = rect.y; W = rect.width; H = rect.height; + XDestroyRegion(temp); + XDestroyRegion(rr); + return 1; +#endif +} + +// +// End of "$Id: fl_rect.cxx 5692 2007-02-12 16:41:41Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_round_box.cxx b/plugins/zynaddsubfx/fltk/src/fl_round_box.cxx new file mode 100644 index 000000000..b02fe6f53 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_round_box.cxx @@ -0,0 +1,122 @@ +// +// "$Id: fl_round_box.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Round box drawing routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Box drawing code for an obscure box type. +// These box types are in seperate files so they are not linked +// in if not used. + +#include +#include + +// A compiler from a certain very large software company will not compile +// the function pointer assignment due to the name conflict with fl_arc. +// This function is to fix that: +void fl_arc_i(int x,int y,int w,int h,double a1,double a2) { + fl_arc(x,y,w,h,a1,a2); +} + +enum {UPPER_LEFT, LOWER_RIGHT, CLOSED, FILL}; + +static void draw(int which, int x,int y,int w,int h, int inset, uchar color) +{ + if (inset*2 >= w) inset = (w-1)/2; + if (inset*2 >= h) inset = (h-1)/2; + x += inset; + y += inset; + w -= 2*inset; + h -= 2*inset; + int d = w <= h ? w : h; + if (d <= 1) return; + fl_color((Fl_Color)color); + void (*f)(int,int,int,int,double,double); + f = (which==FILL) ? fl_pie : fl_arc_i; + if (which >= CLOSED) { + f(x+w-d, y, d, d, w<=h ? 0 : -90, w<=h ? 180 : 90); + f(x, y+h-d, d, d, w<=h ? 180 : 90, w<=h ? 360 : 270); + } else if (which == UPPER_LEFT) { + f(x+w-d, y, d, d, 45, w<=h ? 180 : 90); + f(x, y+h-d, d, d, w<=h ? 180 : 90, 225); + } else { // LOWER_RIGHT + f(x, y+h-d, d, d, 225, w<=h ? 360 : 270); + f(x+w-d, y, d, d, w<=h ? 360 : 270, 360+45); + } + if (which == FILL) { + if (w < h) + fl_rectf(x, y+d/2, w, h-(d&-2)); + else if (w > h) + fl_rectf(x+d/2, y, w-(d&-2), h); + } else { + if (w < h) { + if (which != UPPER_LEFT) fl_yxline(x+w-1, y+d/2-1, y+h-d/2+1); + if (which != LOWER_RIGHT) fl_yxline(x, y+d/2-1, y+h-d/2+1); + } else if (w > h) { + if (which != UPPER_LEFT) fl_xyline(x+d/2-1, y+h-1, x+w-d/2+1); + if (which != LOWER_RIGHT) fl_xyline(x+d/2-1, y, x+w-d/2+1); + } + } +} + +extern uchar* fl_gray_ramp(); + +void fl_round_down_box(int x, int y, int w, int h, Fl_Color bgcolor) { + uchar *g = fl_gray_ramp(); + draw(FILL, x, y, w, h, 2, bgcolor); + draw(UPPER_LEFT, x+1, y, w-2, h, 0, g['N']); + draw(UPPER_LEFT, x+1, y, w-2, h, 1, g['H']); + draw(UPPER_LEFT, x, y, w, h, 0, g['N']); + draw(UPPER_LEFT, x, y, w, h, 1, g['H']); + draw(LOWER_RIGHT, x, y, w, h, 0, g['S']); + draw(LOWER_RIGHT, x+1, y, w-2, h, 0, g['U']); + draw(LOWER_RIGHT, x, y, w, h, 1, g['U']); + draw(LOWER_RIGHT, x+1, y, w-2, h, 1, g['W']); + draw(CLOSED, x, y, w, h, 2, g['A']); +} + +void fl_round_up_box(int x, int y, int w, int h, Fl_Color bgcolor) { + uchar *g = fl_gray_ramp(); + draw(FILL, x, y, w, h, 2, bgcolor); + draw(LOWER_RIGHT, x+1, y, w-2, h, 0, g['H']); + draw(LOWER_RIGHT, x+1, y, w-2, h, 1, g['N']); + draw(LOWER_RIGHT, x, y, w, h, 1, g['H']); + draw(LOWER_RIGHT, x, y, w, h, 2, g['N']); + draw(UPPER_LEFT, x, y, w, h, 2, g['U']); + draw(UPPER_LEFT, x+1, y, w-2, h, 1, g['S']); + draw(UPPER_LEFT, x, y, w, h, 1, g['W']); + draw(UPPER_LEFT, x+1, y, w-2, h, 0, g['U']); + draw(CLOSED, x, y, w, h, 0, g['A']); +} + +extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*); +Fl_Boxtype fl_define_FL_ROUND_UP_BOX() { + fl_internal_boxtype(_FL_ROUND_DOWN_BOX, fl_round_down_box); + fl_internal_boxtype(_FL_ROUND_UP_BOX, fl_round_up_box); + return _FL_ROUND_UP_BOX; +} + +// +// End of "$Id: fl_round_box.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_rounded_box.cxx b/plugins/zynaddsubfx/fltk/src/fl_rounded_box.cxx new file mode 100644 index 000000000..5e110f708 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_rounded_box.cxx @@ -0,0 +1,99 @@ +// +// "$Id: fl_rounded_box.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Rounded box drawing routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include + +#define RN 5 +#define RS 15 +#define BW 3 + +static double offset[RN] = { 0.0, 0.07612, 0.29289, 0.61732, 1.0}; + +static void rbox(int fill, int x, int y, int w, int h) { + int i; + int rsx ,rsy, rs; + rsx = w*2/5; rsy = h*2/5; + if (rsx > rsy) rs = rsy; else rs = rsx; + if (rs > RS) rs = RS; + rsx = rs; rsy = rs; + + if (fill) fl_begin_polygon(); else fl_begin_loop(); + for (i=0; i +#include +#include +#include + +// scroll a rectangle and redraw the newly exposed portions: +void fl_scroll(int X, int Y, int W, int H, int dx, int dy, + void (*draw_area)(void*, int,int,int,int), void* data) +{ + if (!dx && !dy) return; + if (dx <= -W || dx >= W || dy <= -H || dy >= H) { + // no intersection of old an new scroll + draw_area(data,X,Y,W,H); + return; + } + int src_x, src_w, dest_x, clip_x, clip_w; + if (dx > 0) { + src_x = X; + dest_x = X+dx; + src_w = W-dx; + clip_x = X; + clip_w = dx; + } else { + src_x = X-dx; + dest_x = X; + src_w = W+dx; + clip_x = X+src_w; + clip_w = W-src_w; + } + int src_y, src_h, dest_y, clip_y, clip_h; + if (dy > 0) { + src_y = Y; + dest_y = Y+dy; + src_h = H-dy; + clip_y = Y; + clip_h = dy; + } else { + src_y = Y-dy; + dest_y = Y; + src_h = H+dy; + clip_y = Y+src_h; + clip_h = H-src_h; + } +#ifdef WIN32 + typedef int (WINAPI* fl_GetRandomRgn_func)(HDC, HRGN, INT); + static fl_GetRandomRgn_func fl_GetRandomRgn = 0L; + static char first_time = 1; + + // We will have to do some Region magic now, so let's see if the + // required function is available (and it should be staring w/Win95) + if (first_time) { + HMODULE hMod = GetModuleHandle("GDI32.DLL"); + if (hMod) { + fl_GetRandomRgn = (fl_GetRandomRgn_func)GetProcAddress(hMod, "GetRandomRgn"); + } + first_time = 0; + } + + // Now check if the source scrolling area is fully visible. + // If it is, we will do a quick scroll and just update the + // newly exposed area. If it is not, we go the safe route and + // re-render the full area instead. + // Note 1: we could go and find the areas that are actually + // obscured and recursively call fl_scroll for the newly found + // rectangles. However, this practice would rely on the + // elements of the undocumented Rgn structure. + // Note 2: although this method should take care of most + // multi-screen solutions, it will not solve issues scrolling + // from a different resolution screen onto another. + // Note 3: this has been tested with image maps, too. + if (fl_GetRandomRgn) { + // get the DC region minus all overlapping windows + HRGN sys_rgn = CreateRectRgn(0, 0, 0, 0); + fl_GetRandomRgn(fl_gc, sys_rgn, 4); + // now get the source scrolling rectangle + HRGN src_rgn = CreateRectRgn(src_x, src_y, src_x+src_w, src_y+src_h); + POINT offset = { 0, 0 }; + if (GetDCOrgEx(fl_gc, &offset)) { + OffsetRgn(src_rgn, offset.x, offset.y); + } + // see if all source pixels are available in the system region + // Note: we could be a bit more merciful and subtract the + // scroll destination region as well. + HRGN dst_rgn = CreateRectRgn(0, 0, 0, 0); + int r = CombineRgn(dst_rgn, src_rgn, sys_rgn, RGN_DIFF); + DeleteObject(dst_rgn); + DeleteObject(src_rgn); + DeleteObject(sys_rgn); + if (r!=NULLREGION) { + draw_area(data,X,Y,W,H); + return; + } + } + + // Great, we can do an accelerated scroll insteasd of re-rendering + BitBlt(fl_gc, dest_x, dest_y, src_w, src_h, fl_gc, src_x, src_y,SRCCOPY); + +#elif defined(__APPLE_QD__) + Rect src = { src_y, src_x, src_y+src_h, src_x+src_w }; + Rect dst = { dest_y, dest_x, dest_y+src_h, dest_x+src_w }; + static RGBColor bg = { 0xffff, 0xffff, 0xffff }; RGBBackColor( &bg ); + static RGBColor fg = { 0x0000, 0x0000, 0x0000 }; RGBForeColor( &fg ); + CopyBits( GetPortBitMapForCopyBits( GetWindowPort(fl_window) ), + GetPortBitMapForCopyBits( GetWindowPort(fl_window) ), &src, &dst, srcCopy, 0L); +#elif defined(__APPLE_QUARTZ__) + // warning: there does not seem to be an equivalent to this function in Quartz + // ScrollWindowRect is a QuickDraw function and won't work here. + // Since on OS X all windows are fully double buffered, we need not + // worry about offscreen or obscured areas + Rect src = { src_y, src_x, src_y+src_h, src_x+src_w }; + Rect dst = { dest_y, dest_x, dest_y+src_h, dest_x+src_w }; + static RGBColor bg = { 0xffff, 0xffff, 0xffff }; RGBBackColor( &bg ); + static RGBColor fg = { 0x0000, 0x0000, 0x0000 }; RGBForeColor( &fg ); + CopyBits( GetPortBitMapForCopyBits( GetWindowPort(fl_window) ), + GetPortBitMapForCopyBits( GetWindowPort(fl_window) ), &src, &dst, srcCopy, 0L); +#else + XCopyArea(fl_display, fl_window, fl_window, fl_gc, + src_x, src_y, src_w, src_h, dest_x, dest_y); + // we have to sync the display and get the GraphicsExpose events! (sigh) + for (;;) { + XEvent e; XWindowEvent(fl_display, fl_window, ExposureMask, &e); + if (e.type == NoExpose) break; + // otherwise assumme it is a GraphicsExpose event: + draw_area(data, e.xexpose.x, e.xexpose.y, + e.xexpose.width, e.xexpose.height); + if (!e.xgraphicsexpose.count) break; + } +#endif + if (dx) draw_area(data, clip_x, dest_y, clip_w, src_h); + if (dy) draw_area(data, X, clip_y, W, clip_h); +} + +// +// End of "$Id: fl_scroll_area.cxx 5714 2007-02-25 00:00:49Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_set_font.cxx b/plugins/zynaddsubfx/fltk/src/fl_set_font.cxx new file mode 100644 index 000000000..803d01a48 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_set_font.cxx @@ -0,0 +1,90 @@ +// +// "$Id: fl_set_font.cxx 5420 2006-09-05 11:16:15Z matt $" +// +// Font utilities for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Add a font to the internal table. +// Also see fl_set_fonts.cxx which adds all possible fonts. + +#include +#include +#include +#include "flstring.h" +#include "Fl_Font.H" +#include + +static int table_size; + +void Fl::set_font(Fl_Font fnum, const char* name) { + while (fnum >= table_size) { + int i = table_size; + if (!i) { // don't realloc the built-in table + table_size = 2*FL_FREE_FONT; + i = FL_FREE_FONT; + Fl_Fontdesc* t = (Fl_Fontdesc*)malloc(table_size*sizeof(Fl_Fontdesc)); + memcpy(t, fl_fonts, FL_FREE_FONT*sizeof(Fl_Fontdesc)); + fl_fonts = t; + } else { + table_size = 2*table_size; + fl_fonts=(Fl_Fontdesc*)realloc(fl_fonts, table_size*sizeof(Fl_Fontdesc)); + } + for (; i < table_size; i++) { + fl_fonts[i].fontname[0] = 0; + fl_fonts[i].name = 0; +#if !defined(WIN32) && !defined(__APPLE__) + fl_fonts[i].xlist = 0; + fl_fonts[i].n = 0; +#endif // !WIN32 && !__APPLE__ + } + } + Fl_Fontdesc* s = fl_fonts+fnum; + if (s->name) { + if (!strcmp(s->name, name)) {s->name = name; return;} +#if !defined(WIN32) && !defined(__APPLE__) + if (s->xlist && s->n >= 0) XFreeFontNames(s->xlist); +#endif + for (Fl_FontSize* f = s->first; f;) { + Fl_FontSize* n = f->next; delete f; f = n; + } + s->first = 0; + } + s->name = name; + s->fontname[0] = 0; +#if !defined(WIN32) && !defined(__APPLE__) + s->xlist = 0; +#endif + s->first = 0; + fl_font(-1, 0); +} + +void Fl::set_font(Fl_Font fnum, Fl_Font from) { + Fl::set_font(fnum, get_font(from)); +} + +const char* Fl::get_font(Fl_Font fnum) {return fl_fonts[fnum].name;} + +// +// End of "$Id: fl_set_font.cxx 5420 2006-09-05 11:16:15Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_set_fonts.cxx b/plugins/zynaddsubfx/fltk/src/fl_set_fonts.cxx new file mode 100644 index 000000000..9b528b42f --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_set_fonts.cxx @@ -0,0 +1,46 @@ +// +// "$Id: fl_set_fonts.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// More font utilities for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include +#include "Fl_Font.H" +#include "flstring.h" +#include + +#ifdef WIN32 +# include "fl_set_fonts_win32.cxx" +#elif defined(__APPLE__) +# include "fl_set_fonts_mac.cxx" +#elif USE_XFT +# include "fl_set_fonts_xft.cxx" +#else +# include "fl_set_fonts_x.cxx" +#endif // WIN32 + +// +// End of "$Id: fl_set_fonts.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_set_fonts_mac.cxx b/plugins/zynaddsubfx/fltk/src/fl_set_fonts_mac.cxx new file mode 100644 index 000000000..2126dd09a --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_set_fonts_mac.cxx @@ -0,0 +1,213 @@ +// +// "$Id: fl_set_fonts_mac.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// MacOS font utilities for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include + +// This function fills in the fltk font table with all the fonts that +// are found on the X server. It tries to place the fonts into families +// and to sort them so the first 4 in a family are normal, bold, italic, +// and bold italic. + +// Bug: older versions calculated the value for *ap as a side effect of +// making the name, and then forgot about it. To avoid having to change +// the header files I decided to store this value in the last character +// of the font name array. +#define ENDOFBUFFER 127 // sizeof(Fl_Font.fontname)-1 + +// turn a stored font name into a pretty name: +const char* Fl::get_font_name(Fl_Font fnum, int* ap) { +#ifdef __APPLE_QD__ + Fl_Fontdesc *f = fl_fonts + fnum; + if (!f->fontname[0]) { + const char* p = f->name; + if (!p || !*p) {if (ap) *ap = 0; return "";} + int type; + switch (*p) { + case 'B': type = FL_BOLD; break; + case 'I': type = FL_ITALIC; break; + case 'P': type = FL_BOLD | FL_ITALIC; break; + default: type = 0; break; + } + strlcpy(f->fontname, p+1, ENDOFBUFFER); + if (type & FL_BOLD) strlcat(f->fontname, " bold", ENDOFBUFFER); + if (type & FL_ITALIC) strlcat(f->fontname, " italic", ENDOFBUFFER); + f->fontname[ENDOFBUFFER] = (char)type; + } + if (ap) *ap = f->fontname[ENDOFBUFFER]; + return f->fontname; +#elif defined(__APPLE_QUARTZ__) + Fl_Fontdesc *f = fl_fonts + fnum; + if (!f->fontname[0]) { + const char* p = f->name; + if (!p || !*p) {if (ap) *ap = 0; return "";} + strlcpy(f->fontname, p, ENDOFBUFFER); + int type = 0; + if (strstr(f->name, "Bold")) type |= FL_BOLD; + if (strstr(f->name, "Italic")) type |= FL_ITALIC; + f->fontname[ENDOFBUFFER] = (char)type; + } + if (ap) *ap = f->fontname[ENDOFBUFFER]; + return f->fontname; +#endif +} + +static int fl_free_font = FL_FREE_FONT; + +Fl_Font Fl::set_fonts(const char* xstarname) { +#pragma unused ( xstarname ) +#ifdef __APPLE_QD__ + if (fl_free_font != FL_FREE_FONT) + return (Fl_Font)fl_free_font; + static char styleLU[] = " BIP"; + FMFontFamilyInstanceIterator ffiIterator; + FMFontFamilyIterator ffIterator; + FMFontFamily family; + FMFont font; + FMFontStyle style; // bits 0..6: bold, italic underline, outline, shadow, condens, extended (FLTK supports 0 and 1 ) + FMFontSize size; + //FMFilter filter; // do we need to set a specific (or multiple) filter(s) to get ALL fonts? + + Str255 buf; + //filter.format = kFMCurrentFilterFormat; + //filter.selector = kFMGenerationFilterSelector; + //filter.filter.generationFilter = + FMCreateFontFamilyIterator( NULL, NULL, kFMUseGlobalScopeOption, &ffIterator ); + OSStatus listFamilies, listInstances; + for (;;) + { + listFamilies = FMGetNextFontFamily( &ffIterator, &family ); + if ( listFamilies != 0 ) break; + FMGetFontFamilyName( family, buf ); + buf[ buf[0]+1 ] = 0; + //printf( "Font Family: %s\n", buf+1 ); + int i; + for (i=0; iname) s = fl_fonts; // empty slot in table, use entry 0 + int cnt = 0; + +#ifdef __APPLE_QD__ + Str255 name; + int len = strlen( s->name ); + memcpy(((char*)name)+1, s->name+1, len ); + name[0] = len-1; + FMFontFamily family = FMGetFontFamilyFromName( name ); + if ( family == kInvalidFontFamily ) return 0; + + sizep = array; + FMFont font; + FMFontStyle style, fStyle; + switch ( s->name[0] ) { + default : + fStyle=0; + break; + case 'B' : + fStyle=1; + break; + case 'I' : + fStyle=2; + break; + case 'P' : + fStyle=3; + break; + } + FMFontSize size, pSize = -1; + FMFontFamilyInstanceIterator ffiIterator; + FMCreateFontFamilyInstanceIterator( family, &ffiIterator ); + OSStatus listInstances; + for (;;) + { + listInstances = FMGetNextFontFamilyInstance( &ffiIterator, &font, &style, &size ); + if ( listInstances != 0 ) break; + if ( style==fStyle ) + { + if ( size>pSize ) + { + array[ cnt++ ] = size; + pSize = size; + } + } + } + FMDisposeFontFamilyInstanceIterator( &ffiIterator ); +#elif defined(__APPLE_QUARTZ__) + // ATS supports all font size + array[0] = 0; + sizep = array; + cnt = 1; +#endif + + return cnt; +} + +// +// End of "$Id: fl_set_fonts_mac.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_set_fonts_win32.cxx b/plugins/zynaddsubfx/fltk/src/fl_set_fonts_win32.cxx new file mode 100644 index 000000000..2e5c8953b --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_set_fonts_win32.cxx @@ -0,0 +1,149 @@ +// +// "$Id: fl_set_fonts_win32.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// WIN32 font utilities for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this7 library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// This function fills in the FLTK font table with all the fonts that +// are found on the X server. It tries to place the fonts into families +// and to sort them so the first 4 in a family are normal, bold, italic, +// and bold italic. + +// Bug: older versions calculated the value for *ap as a side effect of +// making the name, and then forgot about it. To avoid having to change +// the header files I decided to store this value in the last character +// of the font name array. +#define ENDOFBUFFER 127 // sizeof(Fl_Font.fontname)-1 + +// turn a stored font name into a pretty name: +const char* Fl::get_font_name(Fl_Font fnum, int* ap) { + Fl_Fontdesc *f = fl_fonts + fnum; + if (!f->fontname[0]) { + const char* p = f->name; + if (!p || !*p) {if (ap) *ap = 0; return "";} + int type; + switch (*p) { + case 'B': type = FL_BOLD; break; + case 'I': type = FL_ITALIC; break; + case 'P': type = FL_BOLD | FL_ITALIC; break; + default: type = 0; break; + } + strlcpy(f->fontname, p+1, ENDOFBUFFER); + if (type & FL_BOLD) strlcat(f->fontname, " bold", ENDOFBUFFER); + if (type & FL_ITALIC) strlcat(f->fontname, " italic", ENDOFBUFFER); + f->fontname[ENDOFBUFFER] = (char)type; + } + if (ap) *ap = f->fontname[ENDOFBUFFER]; + return f->fontname; +} + +static int fl_free_font = FL_FREE_FONT; + +static int CALLBACK +enumcb(CONST LOGFONT *lpelf, + CONST TEXTMETRIC * /*lpntm*/, + DWORD /*FontType*/, + LPARAM p) { + if (!p && lpelf->lfCharSet != ANSI_CHARSET) return 1; + const char *n = lpelf->lfFaceName; + for (int i=0; ilfWeight <= 400) + buffer[0] = 'B', Fl::set_font((Fl_Font)(fl_free_font++), strdup(buffer)); + buffer[0] = 'I'; Fl::set_font((Fl_Font)(fl_free_font++), strdup(buffer)); + if (lpelf->lfWeight <= 400) + buffer[0] = 'P', Fl::set_font((Fl_Font)(fl_free_font++), strdup(buffer)); + return 1; +} + +Fl_Font Fl::set_fonts(const char* xstarname) { + if (fl_free_font == FL_FREE_FONT) {// if not already been called + if (!fl_gc) fl_GetDC(0); + EnumFontFamilies(fl_gc, NULL, (FONTENUMPROC)enumcb, xstarname != 0); + } + return (Fl_Font)fl_free_font; +} + + +static int nbSize; +static int cyPerInch; +static int sizes[128]; + +static int CALLBACK +EnumSizeCb(CONST LOGFONT * /*lpelf*/, + CONST TEXTMETRIC *lpntm, + DWORD fontType, + LPARAM /*p*/) { + if ((fontType & RASTER_FONTTYPE) == 0) { + sizes[0] = 0; + nbSize = 1; + + // Scalable font + return 0; + } + + int add = lpntm->tmHeight - lpntm->tmInternalLeading; + add = MulDiv(add, 72, cyPerInch); + + int start = 0; + while ((start < nbSize) && (sizes[start] < add)) { + start++; + } + + if ((start < nbSize) && (sizes[start] == add)) { + return 1; + } + + for (int i=nbSize; i>start; i--) sizes[i] = sizes[i - 1]; + + sizes[start] = add; + nbSize++; + + // Stop enum if buffer overflow + return nbSize < 128; +} + + +int +Fl::get_font_sizes(Fl_Font fnum, int*& sizep) { + nbSize = 0; + Fl_Fontdesc *s = fl_fonts+fnum; + if (!s->name) s = fl_fonts; // empty slot in table, use entry 0 + + if (!fl_gc) fl_GetDC(0); + cyPerInch = GetDeviceCaps(fl_gc, LOGPIXELSY); + if (cyPerInch < 1) cyPerInch = 1; + EnumFontFamilies(fl_gc, s->name+1, (FONTENUMPROC)EnumSizeCb, 0); + + sizep = sizes; + return nbSize; +} + + +// +// End of "$Id: fl_set_fonts_win32.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_set_fonts_x.cxx b/plugins/zynaddsubfx/fltk/src/fl_set_fonts_x.cxx new file mode 100644 index 000000000..945de4ec9 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_set_fonts_x.cxx @@ -0,0 +1,350 @@ +// +// "$Id: fl_set_fonts_x.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// X11 font utilities for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// This function fills in the fltk font table with all the fonts that +// are found on the X server. It tries to place the fonts into families +// and to sort them so the first 4 in a family are normal, bold, italic, +// and bold italic. + +// Standard X fonts are matched by a pattern that is always of +// this form, and this pattern is put in the table: +// "-*-family-weight-slant-width1-style-*-registry-encoding" + +// Non-standard font names (those not starting with '-') are matched +// by a pattern of the form "prefix*suffix", where the '*' is where +// fltk thinks the point size is, or by the actual font name if no +// point size is found. + +// Fltk knows how to pull an "attribute" out of a font name, such as +// bold or italic, by matching known x font field values. All words +// that don't match a known attribute are combined into the "name" +// of the font. Names are compared before attributes for sorting, this +// makes the bold and plain version of a font come out next to each +// other despite the poor X font naming scheme. + +// By default fl_set_fonts() only does iso8859-1 encoded fonts. You can +// do all normal X fonts by passing "-*" or every possible font with "*". + +// Fl::set_font will take strings other than the ones this stores +// and can identify any font on X that way. You may want to write your +// own system of font management and not use this code. + +// turn word N of a X font name into either some attribute bits +// (right now 0, FL_BOLD, or FL_ITALIC), or into -1 indicating that +// the word should be put into the name: + +static int attribute(int n, const char *p) { + // don't put blank things into name: + if (!*p || *p=='-' || *p=='*') return 0; + if (n == 3) { // weight + if (!strncmp(p,"normal",6) || + !strncmp(p,"light",5) || + !strncmp(p,"medium",6) || + !strncmp(p,"book",4)) return 0; + if (!strncmp(p,"bold",4) || !strncmp(p,"demi",4)) return FL_BOLD; + } else if (n == 4) { // slant + if (*p == 'r') return 0; + if (*p == 'i' || *p == 'o') return FL_ITALIC; + } else if (n == 5) { // sWidth + if (!strncmp(p,"normal",6)) return 0; + } + return -1; +} + +// return non-zero if the registry-encoding should be used: +extern const char* fl_encoding; +static int use_registry(const char *p) { + return *p && *p!='*' && strcmp(p,fl_encoding); +} + +// Bug: older versions calculated the value for *ap as a side effect of +// making the name, and then forgot about it. To avoid having to change +// the header files I decided to store this value in the last character +// of the font name array. +#define ENDOFBUFFER 127 // sizeof(Fl_Font.fontname)-1 + +// turn a stored (with *'s) X font name into a pretty name: +const char* Fl::get_font_name(Fl_Font fnum, int* ap) { + Fl_Fontdesc *f = fl_fonts + fnum; + if (!f->fontname[0]) { + int type = 0; + const char* p = f->name; + if (!p) { + if (ap) *ap = 0; + return ""; + } + char *o = f->fontname; + + if (*p != '-') { // non-standard font, just replace * with spaces: + if (strstr(p,"bold")) type = FL_BOLD; + if (strstr(p,"ital")) type |= FL_ITALIC; + for (;*p; p++) { + if (*p == '*' || *p == ' ' || *p == '-') { + do p++; while (*p == '*' || *p == ' ' || *p == '-'); + if (!*p) break; + if (o < (f->fontname + ENDOFBUFFER - 1)) *o++ = ' '; + } + if (o < (f->fontname + ENDOFBUFFER - 1)) *o++ = *p; + } + *o = 0; + + } else { // standard dash-seperated font: + + // get the family: + const char *x = fl_font_word(p,2); if (*x) x++; if (*x=='*') x++; + if (!*x) { + if (ap) *ap = 0; + return p; + } + const char *e = fl_font_word(x,1); + if ((e - x) < (int)(ENDOFBUFFER - 1)) { + // MRS: we want strncpy here, not strlcpy... + strncpy(o,x,e-x); + o += e-x; + } else { + strlcpy(f->fontname, x, ENDOFBUFFER); + o = f->fontname+ENDOFBUFFER-1; + } + + // collect all the attribute words: + for (int n = 3; n <= 6; n++) { + // get the next word: + if (*e) e++; x = e; e = fl_font_word(x,1); + int t = attribute(n,x); + if (t < 0) { + if (o < (f->fontname + ENDOFBUFFER - 1)) *o++ = ' '; + if ((e - x) < (int)(ENDOFBUFFER - (o - f->fontname) - 1)) { + // MRS: we want strncpy here, not strlcpy... + strncpy(o,x,e-x); + o += e-x; + } else { + strlcpy(o,x, ENDOFBUFFER - (o - f->fontname) - 1); + o = f->fontname+ENDOFBUFFER-1; + } + } else type |= t; + } + + // skip over the '*' for the size and get the registry-encoding: + x = fl_font_word(e,2); + if (*x) {x++; *o++ = '('; while (*x) *o++ = *x++; *o++ = ')';} + + *o = 0; + if (type & FL_BOLD) strlcat(f->fontname, " bold", ENDOFBUFFER); + if (type & FL_ITALIC) strlcat(f->fontname, " italic", ENDOFBUFFER); + } + f->fontname[ENDOFBUFFER] = (char)type; + } + if (ap) *ap = f->fontname[ENDOFBUFFER]; + return f->fontname; +} + +extern "C" { +// sort raw (non-'*') X font names into perfect order: + +static int ultrasort(const void *aa, const void *bb) { + const char *a = *(char **)aa; + const char *b = *(char **)bb; + + // sort all non x-fonts at the end: + if (*a != '-') { + if (*b == '-') return 1; + // 2 non-x fonts are matched by "numeric sort" + int ret = 0; + for (;;) { + if (isdigit(*a) && isdigit(*b)) { + int na = strtol(a, (char **)&a, 10); + int nb = strtol(b, (char **)&b, 10); + if (!ret) ret = na-nb; + } else if (*a != *b) { + return (*a-*b); + } else if (!*a) { + return ret; + } else { + a++; b++; + } + } + } else { + if (*b != '-') return -1; + } + + // skip the foundry (assumme equal): + for (a++; *a && *a++!='-';); + for (b++; *b && *b++!='-';); + + // compare the family and all the attribute words: + int atype = 0; + int btype = 0; + for (int n = 2; n <= 6; n++) { + int at = attribute(n,a); + int bt = attribute(n,b); + if (at < 0) { + if (bt >= 0) return 1; + for (;;) {if (*a!=*b) return *a-*b; b++; if (!*a || *a++=='-') break;} + } else { + if (bt < 0) return -1; + a = fl_font_word(a,1); if (*a) a++; + b = fl_font_word(b,1); if (*b) b++; + atype |= at; btype |= bt; + } + } + + // remember the pixel size: + int asize = atoi(a); + int bsize = atoi(b); + + // compare the registry/encoding: + a = fl_font_word(a,6); if (*a) a++; + b = fl_font_word(b,6); if (*b) b++; + if (use_registry(a)) { + if (!use_registry(b)) return 1; + int r = strcmp(a,b); if (r) return r; + } else { + if (use_registry(b)) return -1; + } + + if (atype != btype) return atype-btype; + if (asize != bsize) return asize-bsize; + + // something wrong, just do a string compare... + return strcmp(*(char**)aa, *(char**)bb); +} +} + +// converts a X font name to a standard starname, returns point size: +static int to_canonical(char *to, const char *from, size_t tolen) { + char* c = fl_find_fontsize((char*)from); + if (!c) return -1; // no point size found... + const char* endptr; + int size = strtol(c,(char**)&endptr,10); + if (from[0] == '-') { + // replace the "foundry" with -*-: + *to++ = '-'; *to++ = '*'; + for (from++; *from && *from != '-'; from++); + // skip to the registry-encoding: + endptr = (char*)fl_font_word(endptr,6); + if (*endptr && !use_registry(endptr+1)) endptr = ""; + } + int n = c-from; + // MRS: we want strncpy here, not strlcpy... + if (n > (int)(tolen - 1)) return -1; + strncpy(to,from,n); + to[n++] = '*'; + strlcpy(to+n,endptr, tolen - n); + return size; +} + +static int fl_free_font = FL_FREE_FONT; + +Fl_Font Fl::set_fonts(const char* xstarname) { + if (fl_free_font > FL_FREE_FONT) // already been here + return (Fl_Font)fl_free_font; + fl_open_display(); + int xlistsize; + char buf[20]; + if (!xstarname) { + strcpy(buf,"-*-"); strcpy(buf+3,fl_encoding); + xstarname = buf; + } + char **xlist = XListFonts(fl_display, xstarname, 10000, &xlistsize); + if (!xlist) return (Fl_Font)fl_free_font; + qsort(xlist, xlistsize, sizeof(*xlist), ultrasort); + int used_xlist = 0; + for (int i=0; i= 0) { + for (;;) { // find all matching fonts: + if (i >= xlistsize) break; + const char *q = xlist[i]; + char this_canon[1024]; + if (to_canonical(this_canon, q, sizeof(this_canon)) < 0) break; + if (strcmp(canon, this_canon)) break; + i++; + } + /*if (*p=='-' || i > first_xlist+1)*/ p = canon; + } + int j; + for (j = 0;; j++) { + if (j < FL_FREE_FONT) { + // see if it is one of our built-in fonts: + // if so, set the list of x fonts, since we have it anyway + if (fl_fonts[j].name && !strcmp(fl_fonts[j].name, p)) break; + } else { + j = fl_free_font++; + if (p == canon) p = strdup(p); else used_xlist = 1; + Fl::set_font((Fl_Font)j, p); + break; + } + } + if (!fl_fonts[j].xlist) { + fl_fonts[j].xlist = xlist+first_xlist; + fl_fonts[j].n = -(i-first_xlist); + used_xlist = 1; + } + } + if (!used_xlist) XFreeFontNames(xlist); + return (Fl_Font)fl_free_font; +} + +int Fl::get_font_sizes(Fl_Font fnum, int*& sizep) { + Fl_Fontdesc *s = fl_fonts+fnum; + if (!s->name) s = fl_fonts; // empty slot in table, use entry 0 + if (!s->xlist) { + fl_open_display(); + s->xlist = XListFonts(fl_display, s->name, 100, &(s->n)); + if (!s->xlist) return 0; + } + int listsize = s->n; if (listsize<0) listsize = -listsize; + static int sizes[128]; + int numsizes = 0; + for (int i = 0; i < listsize; i++) { + char *q = s->xlist[i]; + char *d = fl_find_fontsize(q); + if (!d) continue; + int s = strtol(d,0,10); + if (!numsizes || sizes[numsizes-1] < s) { + sizes[numsizes++] = s; + } else { + // insert-sort the new size into list: + int n; + for (n = numsizes-1; n > 0; n--) if (sizes[n-1] < s) break; + if (sizes[n] != s) { + for (int m = numsizes; m > n; m--) sizes[m] = sizes[m-1]; + sizes[n] = s; + numsizes++; + } + } + } + sizep = sizes; + return numsizes; +} + +// +// End of "$Id: fl_set_fonts_x.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_set_fonts_xft.cxx b/plugins/zynaddsubfx/fltk/src/fl_set_fonts_xft.cxx new file mode 100644 index 000000000..951b7ed8b --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_set_fonts_xft.cxx @@ -0,0 +1,366 @@ +// +// "$Id: fl_set_fonts_xft.cxx 5505 2006-10-03 02:35:12Z mike $" +// +// More font utilities for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2006 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include + +// This function fills in the fltk font table with all the fonts that +// are found on the X server. It tries to place the fonts into families +// and to sort them so the first 4 in a family are normal, bold, italic, +// and bold italic. + +// Bug: older versions calculated the value for *ap as a side effect of +// making the name, and then forgot about it. To avoid having to change +// the header files I decided to store this value in the last character +// of the font name array. +#define ENDOFBUFFER 127 // sizeof(Fl_Font.fontname)-1 + +// turn a stored font name into a pretty name: +const char* Fl::get_font_name(Fl_Font fnum, int* ap) { + Fl_Fontdesc *f = fl_fonts + fnum; + if (!f->fontname[0]) { + const char* p = f->name; + int type; + switch (p[0]) { + case 'B': type = FL_BOLD; break; + case 'I': type = FL_ITALIC; break; + case 'P': type = FL_BOLD | FL_ITALIC; break; + default: type = 0; break; + } + + // NOTE: This can cause duplications in fonts that already have Bold or Italic in + // their "name". Maybe we need to find a cleverer way? + strlcpy(f->fontname, p+1, ENDOFBUFFER); + if (type & FL_BOLD) strlcat(f->fontname, " bold", ENDOFBUFFER); + if (type & FL_ITALIC) strlcat(f->fontname, " italic", ENDOFBUFFER); + f->fontname[ENDOFBUFFER] = (char)type; + } + if (ap) *ap = f->fontname[ENDOFBUFFER]; + return f->fontname; +} + +/////////////////////////////////////////////////////////// +#define LOCAL_RAW_NAME_MAX 256 + +extern "C" { +// sort returned fontconfig font names +static int name_sort(const void *aa, const void *bb) { + // What should we do here? Just do a string compare for now... + // NOTE: This yeilds some oddities - in particular a Blah Bold font will be + // listed before Blah... + // Also - the fontconfig listing returns some faces that are effectively duplicates + // as far as fltk is concerned, e.g. where there are ko or ja variants that we + // can't distinguish (since we are not yet fully UTF-*) - should we strip them here? + return strcasecmp(*(char**)aa, *(char**)bb); +} // end of name_sort +} // end of extern C section + + +// Read the "pretty" name we have derived from fontconfig then convert +// it into the format fltk uses internally for Xft names... +// This is just a mess - I should have tokenised the strings and gone from there, +// but I really thought this would be easier! +static void make_raw_name(char *raw, char *pretty) +{ + // Input name will be "Some Name:style = Bold Italic" or whatever + // The plan is this: + // - the first char in the "raw" name becomes either I, B, P or " " for + // italic, bold, bold italic or normal - this seems to be the fltk way... + + char *style = strchr(pretty, ':'); + char *last = style + strlen(style) - 2; + + if (style) + { + *style = 0; // Terminate "name" string + style ++; // point to start of style section + } + raw[0] = ' '; raw[1] = 0; // Default start of "raw name" text + strncat(raw, pretty, LOCAL_RAW_NAME_MAX); + // At this point, the name is "marked" as regular... + if (style) + { +#define PLAIN 0 +#define BOLD 1 +#define ITALIC 2 +#define BITALIC (BOLD | ITALIC) + int mods = PLAIN; + // Now try and parse the style string - look for the "=" sign + style = strchr(style, '='); + while ((style) && (style < last)) + { + int type; + while ((*style == '=') || (*style == ' ') || (*style == '\t')) + { + style++; // Start of Style string + if ((style >= last) || (*style == 0)) continue; + } + type = toupper(style[0]); + switch (type) + { + // Things we might see: Regular Normal Bold Italic Oblique (??what??) Medium + // Roman Light Demi Sans SemiCondensed SuperBold Book... etc... + // Things we actually care about: Bold Italic Oblique SuperBold - Others??? + case 'I': + if (strncasecmp(style, "Italic", 6) == 0) + { + mods |= ITALIC; + } + goto NEXT_STYLE; + + case 'B': + if (strncasecmp(style, "Bold", 4) == 0) + { + mods |= BOLD; + } + goto NEXT_STYLE; + + case 'O': + if (strncasecmp(style, "Oblique", 7) == 0) + { + mods |= ITALIC; + } + goto NEXT_STYLE; + + case 's': + if (strncasecmp(style, "SuperBold", 9) == 0) + { + mods |= BOLD; + } + goto NEXT_STYLE; + + default: // find the next gap + goto NEXT_STYLE; + } // switch end +NEXT_STYLE: + while ((*style != ' ') && (*style != '\t')) + { + style++; + if ((style >= last) || (*style == 0)) goto STYLE_DONE; + } + } +STYLE_DONE: + // Set the "modifier" character in the raw string + switch(mods) + { + case BOLD: raw[0] = 'B'; + break; + case ITALIC: raw[0] = 'I'; + break; + case BITALIC: raw[0] = 'P'; + break; + default: raw[0] = ' '; + break; + } + } +} // make_raw_name + +/////////////////////////////////////////////////////////// + +static int fl_free_font = FL_FREE_FONT; + +// Uses the fontconfig lib to construct a list of all installed fonts. +// I tried using XftListFonts for this, but the API is tricky - and when +// I looked at the XftList* code, it calls the Fc* functions anyway, so... +// +// Also, for now I'm ignoring the "pattern_name" and just getting everything... +// AND I don't try and skip the fonts we've already loaded in the defaults. +// Blimey! What a hack! +Fl_Font Fl::set_fonts(const char* pattern_name) +{ + FcFontSet *fnt_set; // Will hold the list of fonts we find + FcPattern *fnt_pattern; // Holds the generic "match all names" pattern + FcObjectSet *fnt_obj_set = 0; // Holds the generic "match all objects" + + int j; // loop iterator variable + int font_count; // Total number of fonts found to process + char **full_list; // The list of font names we build + + if (fl_free_font > FL_FREE_FONT) // already been here + return (Fl_Font)fl_free_font; + + fl_open_display(); // Just in case... + + // Make sure fontconfig is ready... is this necessary? The docs say it is + // safe to call it multiple times, so just go for it anyway! + if (!FcInit()) + { + // What to do? Just return defaults... + return FL_FREE_FONT; + } + + // Create a search pattern that will match every font name - I think this + // does the Right Thing, but am not certain... + // + // This could possibly be "enhanced" to pay attention to the requested + // "pattern_name"? + fnt_pattern = FcPatternCreate(); + fnt_obj_set = FcObjectSetBuild(FC_FAMILY, FC_STYLE, (void *)0); + + // Hopefully, this is a set of all the fonts... + fnt_set = FcFontList(0, fnt_pattern, fnt_obj_set); + + // We don't need the fnt_pattern any more, release it + FcPatternDestroy(fnt_pattern); + + // Now, if we got any fonts, iterate through them... + if (fnt_set) + { + char *stop; + char *start; + char *first; + + font_count = fnt_set->nfont; // How many fonts? + + // Allocate array of char*'s to hold the name strings + full_list = (char **)malloc(sizeof(char *) * font_count); + + // iterate through all the font patterns and get the names out... + for (j = 0; j < font_count; j++) + { + // NOTE: FcChar8 is a typedef of "unsigned char"... + FcChar8 *font; // String to hold the font's name + + // Convert from fontconfig internal pattern to human readable name + // NOTE: This WILL malloc storage, so we need to free it later... + font = FcNameUnparse(fnt_set->fonts[j]); + + // The returned strings look like this... + // Century Schoolbook:style=Bold Italic,fed kursiv,Fett Kursiv,... + // So the bit we want is up to the first comma - BUT some strings have + // more than one name, separated by, guess what?, a comma... + stop = start = first = 0; + stop = strchr((const char *)font, ','); + start = strchr((const char *)font, ':'); + if ((stop) && (start) && (stop < start)) + { + first = stop + 1; // discard first version of name + // find first comma *after* the end of the name + stop = strchr((const char *)start, ','); + } + else + { + first = (char *)font; // name is just what was returned + } + // Truncate the name after the (english) modifiers description + if (stop) + { + *stop = 0; // Terminate the string at the first comma, if there is one + } + + // Copy the font description into our list + if (first == (char *)font) + { // The listed name is still OK + full_list[j] = (char *)font; + } + else + { // The listed name has been modified + full_list[j] = strdup(first); + // Free the font name storage + free (font); + } + // replace "style=Regular" so strcmp sorts it first + if (start) { + char *reg = strstr(full_list[j], "=Regular"); + if (reg) reg[1]='.'; + } + } + + // Release the fnt_set - we don't need it any more + FcFontSetDestroy(fnt_set); + + // Sort the list into alphabetic order + qsort(full_list, font_count, sizeof(*full_list), name_sort); + + // Now let us add the names we got to fltk's font list... + for (j = 0; j < font_count; j++) + { + if (full_list[j]) + { + char xft_name[LOCAL_RAW_NAME_MAX]; + char *stored_name; + // Parse the strings into FLTK-XFT style.. + make_raw_name(xft_name, full_list[j]); + // NOTE: This just adds on AFTER the default fonts - no attempt is made + // to identify already loaded fonts. Is this bad? + stored_name = strdup(xft_name); + Fl::set_font((Fl_Font)(j + FL_FREE_FONT), stored_name); + fl_free_font ++; + + free(full_list[j]); // release that name from our internal array + } + } + // Now we are done with the list, release it fully + free(full_list); + } + return (Fl_Font)fl_free_font; +} // ::set_fonts +//////////////////////////////////////////////////////////////// + + +extern "C" { +static int int_sort(const void *aa, const void *bb) { + return (*(int*)aa)-(*(int*)bb); +} +} + +//////////////////////////////////////////////////////////////// + +// Return all the point sizes supported by this font: +// Suprisingly enough Xft works exactly like fltk does and returns +// the same list. Except there is no way to tell if the font is scalable. +int Fl::get_font_sizes(Fl_Font fnum, int*& sizep) { + Fl_Fontdesc *s = fl_fonts+fnum; + if (!s->name) s = fl_fonts; // empty slot in table, use entry 0 + + fl_open_display(); + XftFontSet* fs = XftListFonts(fl_display, fl_screen, + XFT_FAMILY, XftTypeString, s->name+1, + (void *)0, + XFT_PIXEL_SIZE, + (void *)0); + static int* array = 0; + static int array_size = 0; + if (fs->nfont >= array_size) { + delete[] array; + array = new int[array_size = fs->nfont+1]; + } + array[0] = 0; int j = 1; // claim all fonts are scalable + for (int i = 0; i < fs->nfont; i++) { + double v; + if (XftPatternGetDouble(fs->fonts[i], XFT_PIXEL_SIZE, 0, &v) == XftResultMatch) { + array[j++] = int(v); + } + } + qsort(array+1, j-1, sizeof(int), int_sort); + XftFontSetDestroy(fs); + sizep = array; + return j; +} + +// +// End of "$Id: fl_set_fonts_xft.cxx 5505 2006-10-03 02:35:12Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_shadow_box.cxx b/plugins/zynaddsubfx/fltk/src/fl_shadow_box.cxx new file mode 100644 index 000000000..00bcc51be --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_shadow_box.cxx @@ -0,0 +1,56 @@ +// +// "$Id: fl_shadow_box.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Shadow box drawing routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +#include +#include + +#define BW 3 + +static void fl_shadow_frame(int x, int y, int w, int h, Fl_Color c) { + fl_color(FL_DARK3); + fl_rectf(x+BW, y+h-BW, w - BW, BW); + fl_rectf(x+w-BW, y+BW, BW, h - BW); + fl_color(c); + fl_rect(x,y,w-BW,h-BW); +} + +static void fl_shadow_box(int x, int y, int w, int h, Fl_Color c) { + fl_color(c); + fl_rectf(x+1,y+1,w-2-BW,h-2-BW); + fl_shadow_frame(x,y,w,h,FL_GRAY0); +} + +extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*); +Fl_Boxtype fl_define_FL_SHADOW_BOX() { + fl_internal_boxtype(_FL_SHADOW_FRAME, fl_shadow_frame); + fl_internal_boxtype(_FL_SHADOW_BOX, fl_shadow_box); + return _FL_SHADOW_BOX; +} + +// +// End of "$Id: fl_shadow_box.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_shortcut.cxx b/plugins/zynaddsubfx/fltk/src/fl_shortcut.cxx new file mode 100644 index 000000000..3e2fcc54d --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_shortcut.cxx @@ -0,0 +1,239 @@ +// +// "$Id: fl_shortcut.cxx 5981 2007-11-19 16:21:19Z matt $" +// +// Shortcut support routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Code to test and parse fltk shortcut numbers. +// +// A shortcut is a keysym or'd with shift flags. In the simplest +// sense a shortcut is matched if the shift state is exactly as +// given and the key returning that keysym is pressed. +// +// To make it easier to match some things it is more complex: +// +// Only FL_META, FL_ALT, FL_SHIFT, and FL_CTRL must be "off". A +// zero in the other shift flags indicates "dont care". +// +// It also checks against the first character of Fl::event_text(), +// and zero for FL_SHIFT means "don't care". +// This allows punctuation shortcuts like "#" to work (rather than +// calling it "shift+3") + +#include +#include +#include +#include +#include +#include "flstring.h" +#if !defined(WIN32) && !defined(__APPLE__) +#include +#endif + +int Fl::test_shortcut(int shortcut) { + if (!shortcut) return 0; + + int v = shortcut & 0xffff; +#ifdef __APPLE__ + if (v > 32 && v < 0x7f || v >= 0x80 && v <= 0xff) { +#else + // most X11 use MSWindows Latin-1 if set to Western encoding, so 0x80 to 0xa0 are defined + if (v > 32 && v < 0x7f || v >= 0x80 && v <= 0xff) { +#endif + if (isupper(v)) { + shortcut |= FL_SHIFT; + } + } + + int shift = Fl::event_state(); + // see if any required shift flags are off: + if ((shortcut&shift) != (shortcut&0x7fff0000)) return 0; + // record shift flags that are wrong: + int mismatch = (shortcut^shift)&0x7fff0000; + // these three must always be correct: + if (mismatch&(FL_META|FL_ALT|FL_CTRL)) return 0; + + int key = shortcut & 0xffff; + + // if shift is also correct, check for exactly equal keysyms: + if (!(mismatch&(FL_SHIFT)) && key == Fl::event_key()) return 1; + + // try matching ascii, ignore shift: + if (key == event_text()[0]) return 1; + + // kludge so that Ctrl+'_' works (as opposed to Ctrl+'^_'): + if ((shift&FL_CTRL) && key >= 0x3f && key <= 0x5F + && event_text()[0]==(key^0x40)) return 1; + return 0; +} + +#if defined(WIN32) || defined(__APPLE__) // if not X +// This table must be in numeric order by fltk (X) keysym number: +struct Keyname {int key; const char* name;}; +static Keyname table[] = { + {' ', "Space"}, + {FL_BackSpace, "Backspace"}, + {FL_Tab, "Tab"}, + {0xff0b/*XK_Clear*/, "Clear"}, + {FL_Enter, "Enter"}, // X says "Enter" + {FL_Pause, "Pause"}, + {FL_Scroll_Lock, "Scroll_Lock"}, + {FL_Escape, "Escape"}, + {FL_Home, "Home"}, + {FL_Left, "Left"}, + {FL_Up, "Up"}, + {FL_Right, "Right"}, + {FL_Down, "Down"}, + {FL_Page_Up, "Page_Up"}, // X says "Prior" + {FL_Page_Down,"Page_Down"}, // X says "Next" + {FL_End, "End"}, + {FL_Print, "Print"}, + {FL_Insert, "Insert"}, + {FL_Menu, "Menu"}, + {FL_Num_Lock, "Num_Lock"}, + {FL_KP_Enter, "KP_Enter"}, + {FL_Shift_L, "Shift_L"}, + {FL_Shift_R, "Shift_R"}, + {FL_Control_L,"Control_L"}, + {FL_Control_R,"Control_R"}, + {FL_Caps_Lock,"Caps_Lock"}, + {FL_Meta_L, "Meta_L"}, + {FL_Meta_R, "Meta_R"}, + {FL_Alt_L, "Alt_L"}, + {FL_Alt_R, "Alt_R"}, + {FL_Delete, "Delete"} +}; +#endif + +const char * fl_shortcut_label(int shortcut) { + static char buf[20]; + char *p = buf; + if (!shortcut) {*p = 0; return buf;} + // fix upper case shortcuts + int v = shortcut & 0xffff; +#ifdef __APPLE__ + if (v > 32 && v < 0x7f || v >= 0x80 && v <= 0xff) { +#else + if (v > 32 && v < 0x7f || v >= 0xa0 && v <= 0xff) { +#endif + if (isupper(v)) { + shortcut |= FL_SHIFT; + } + } +#ifdef __APPLE__ + // \todo Mac : we might want to change the symbols for Mac users - consider drawing Apple Symbols... . + if (shortcut & FL_SHIFT) {strcpy(p,"Shift+"); p += 6;} //: Mac hollow up arrow + if (shortcut & FL_META) {strcpy(p,"Cmd+"); p += 4;} //: Mac 'Apple' key + if (shortcut & FL_ALT) {strcpy(p,"Option+"); p += 7;} //: Mac 'Alt/Option' or fancy switch symbol + if (shortcut & FL_CTRL) {strcpy(p,"Ctrl+"); p += 5;} //: Mac ctrl key +#else + if (shortcut & FL_META) {strcpy(p,"Meta+"); p += 5;} + if (shortcut & FL_ALT) {strcpy(p,"Alt+"); p += 4;} + if (shortcut & FL_SHIFT) {strcpy(p,"Shift+"); p += 6;} + if (shortcut & FL_CTRL) {strcpy(p,"Ctrl+"); p += 5;} +#endif // __APPLE__ + int key = shortcut & 0xFFFF; +#if defined(WIN32) || defined(__APPLE__) // if not X + if (key >= FL_F && key <= FL_F_Last) { + *p++ = 'F'; + if (key > FL_F+9) *p++ = (key-FL_F)/10+'0'; + *p++ = (key-FL_F)%10 + '0'; + } else { + // binary search the table for a match: + int a = 0; + int b = sizeof(table)/sizeof(*table); + while (a < b) { + int c = (a+b)/2; + if (table[c].key == key) { + if (p > buf) {strcpy(p,table[c].name); return buf;} + return table[c].name; + } + if (table[c].key < key) a = c+1; + else b = c; + } + if (key >= FL_KP && key <= FL_KP_Last) { + // mark keypad keys with KP_ prefix + strcpy(p,"KP_"); p += 3; + *p++ = uchar(key & 127); + } else { + // if none found, use the keystroke as a match: + *p++ = uchar(toupper(key & 255)); + } + } + *p = 0; + return buf; +#else + const char* q; + if (key == FL_Enter || key == '\r') q="Enter"; // don't use Xlib's "Return": + else if (key > 32 && key < 0x100) q = 0; + else q = XKeysymToString(key); + if (!q) {*p++ = uchar(toupper(key & 255)); *p = 0; return buf;} + if (p > buf) {strcpy(p,q); return buf;} else return q; +#endif +} + +// Emulation of XForms named shortcuts +#include +int fl_old_shortcut(const char* s) { + if (!s || !*s) return 0; + int n = 0; + if (*s == '#') {n |= FL_ALT; s++;} + if (*s == '+') {n |= FL_SHIFT; s++;} + if (*s == '^') {n |= FL_CTRL; s++;} + if (*s && s[1]) return n | (int)strtol(s,0,0); // allow 0xf00 to get any key + return n | *s; +} + +// Tests for &x shortcuts in button labels: + +char Fl_Widget::label_shortcut(const char *t) { + if (!t) return 0; + for (;;) { + if (*t==0) return 0; + if (*t=='&') { + char s = t[1]; + if (s==0) return 0; + else if (s=='&') t++; + else return s; + } + t++; + } +} + +int Fl_Widget::test_shortcut(const char *t) { + char c = Fl::event_text()[0]; + if (!c || !t) return 0; + if (c == label_shortcut(t)) + return 1; + return 0; +} + +int Fl_Widget::test_shortcut() { + if (!(flags()&SHORTCUT_LABEL)) return 0; + return test_shortcut(label()); +} + +// +// End of "$Id: fl_shortcut.cxx 5981 2007-11-19 16:21:19Z matt $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_show_colormap.cxx b/plugins/zynaddsubfx/fltk/src/fl_show_colormap.cxx new file mode 100644 index 000000000..58d77e8b9 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_show_colormap.cxx @@ -0,0 +1,161 @@ +// +// "$Id: fl_show_colormap.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Colormap color selection dialog for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Select a color from the colormap. +// Pretty much unchanged from Forms. + +#include +#include +#include +#include +#include + +#define BOXSIZE 14 +#define BORDER 4 + +class ColorMenu : public Fl_Window { + Fl_Color initial; + Fl_Color which, previous; + int done; + void drawbox(Fl_Color); + void draw(); + int handle(int); +public: + ColorMenu(Fl_Color oldcol); + Fl_Color run(); +}; + +ColorMenu::ColorMenu(Fl_Color oldcol) : + Fl_Window(BOXSIZE*8+1+2*BORDER, BOXSIZE*32+1+2*BORDER) { + clear_border(); + set_modal(); + initial = which = oldcol; +} + +void ColorMenu::drawbox(Fl_Color c) { + if (c < 0 || c > 255) return; + int X = (c%8)*BOXSIZE+BORDER; + int Y = (c/8)*BOXSIZE+BORDER; +#if BORDER_WIDTH < 3 + if (c == which) fl_draw_box(FL_DOWN_BOX, X+1, Y+1, BOXSIZE-1, BOXSIZE-1, c); + else fl_draw_box(FL_BORDER_BOX, X, Y, BOXSIZE+1, BOXSIZE+1, c); +#else + fl_draw_box(c == which ? FL_DOWN_BOX : FL_BORDER_BOX, + X, Y, BOXSIZE+1, BOXSIZE+1, c); +#endif +} + +void ColorMenu::draw() { + if (damage() != FL_DAMAGE_CHILD) { + fl_draw_box(FL_UP_BOX,0,0,w(),h(),color()); + for (int c = 0; c < 256; c++) drawbox((Fl_Color)c); + } else { + drawbox(previous); + drawbox(which); + } + previous = which; +} + +int ColorMenu::handle(int e) { + int c = which; + switch (e) { + case FL_PUSH: + case FL_DRAG: { + int X = (Fl::event_x_root() - x() - BORDER); + if (X >= 0) X = X/BOXSIZE; + int Y = (Fl::event_y_root() - y() - BORDER); + if (Y >= 0) Y = Y/BOXSIZE; + if (X >= 0 && X < 8 && Y >= 0 && Y < 32) + c = 8*Y + X; + else + c = initial; + } break; + case FL_RELEASE: + done = 1; + return 1; + case FL_KEYBOARD: + switch (Fl::event_key()) { + case FL_Up: if (c > 7) c -= 8; break; + case FL_Down: if (c < 256-8) c += 8; break; + case FL_Left: if (c > 0) c--; break; + case FL_Right: if (c < 255) c++; break; + case FL_Escape: which = initial; done = 1; return 1; + case FL_KP_Enter: + case FL_Enter: done = 1; return 1; + default: return 0; + } + break; + default: + return 0; + } + if (c != which) { + which = (Fl_Color)c; damage(FL_DAMAGE_CHILD); + int bx = (c%8)*BOXSIZE+BORDER; + int by = (c/8)*BOXSIZE+BORDER; + int px = x(); + int py = y(); + int scr_x, scr_y, scr_w, scr_h; + Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h); + if (px < scr_x) px = scr_x; + if (px+bx+BOXSIZE+BORDER >= scr_x+scr_w) px = scr_x+scr_w-bx-BOXSIZE-BORDER; + if (py < scr_y) py = scr_y; + if (py+by+BOXSIZE+BORDER >= scr_y+scr_h) py = scr_y+scr_h-by-BOXSIZE-BORDER; + if (px+bx < BORDER) px = BORDER-bx; + if (py+by < BORDER) py = BORDER-by; + position(px,py); + } + return 1; +} + +extern char fl_override_redirect; // hack for menus + +#ifdef _MSC_VER +#pragma optimize("a",off) // needed to get the done check to work +#endif +Fl_Color ColorMenu::run() { + if (which < 0 || which > 255) { + position(Fl::event_x_root()-w()/2, Fl::event_y_root()-y()/2); + } else { + position(Fl::event_x_root()-(initial%8)*BOXSIZE-BOXSIZE/2-BORDER, + Fl::event_y_root()-(initial/8)*BOXSIZE-BOXSIZE/2-BORDER); + } + show(); + Fl::grab(*this); + done = 0; + while (!done) Fl::wait(); + Fl::release(); + return which; +} + +Fl_Color fl_show_colormap(Fl_Color oldcol) { + ColorMenu m(oldcol); + return m.run(); +} + +// +// End of "$Id: fl_show_colormap.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_symbols.cxx b/plugins/zynaddsubfx/fltk/src/fl_symbols.cxx new file mode 100644 index 000000000..e27254582 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_symbols.cxx @@ -0,0 +1,700 @@ +// +// "$Id: fl_symbols.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Symbol drawing code for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// These are small graphics drawn by the normal label-drawing +// code when the string starts with an '@' sign. + +// Adapted from original code written by: + +// Written by Mark Overmars +// Version 2.1 a +// Date: Oct 2, 1992 + +#include +#include +#include +#include "flstring.h" + +typedef struct { + const char *name; + void (*drawit)(Fl_Color); + char scalable; + char notempty; +} SYMBOL; + +#define MAXSYMBOL 211 + /* Maximal number of symbols in table. Only half of them are + used. Should be prime. */ + +static SYMBOL symbols[MAXSYMBOL]; /* The symbols */ +static int symbnumb = -1; /* Their number */ + +static int find(const char *name) { +// returns hash entry if it exists, or first empty slot: + int pos = name[0] ? ( + name[1] ? ( + name[2] ? 71*name[0]+31*name[1]+name[2] : 31*name[0]+name[1] + ) : + name[0] + ) : 0; + pos %= MAXSYMBOL; + int hh2 = name[0] ? ( + (name[1]) ? 51*name[0]+3*name[1] : 3*name[0] + ) : 1; + hh2 %= MAXSYMBOL; if (!hh2) hh2 = 1; + for (;;) { + if (!symbols[pos].notempty) return pos; + if (!strcmp(symbols[pos].name,name)) return pos; + pos = (pos + hh2) % MAXSYMBOL; + } +} + +static void fl_init_symbols(void); + +/**************** The routines seen by the user *************************/ + +int fl_add_symbol(const char *name, void (*drawit)(Fl_Color), int scalable) +/* Adds a symbol to the system. Returns whether correct. */ +{ + fl_init_symbols(); + int pos; + if (symbnumb > MAXSYMBOL / 2) return 0; // table is full + pos = find(name); + symbols[pos].name = name; + symbols[pos].drawit = drawit; + symbols[pos].notempty = 1; + symbols[pos].scalable = scalable; + symbnumb++; + return 1; +} + +int fl_return_arrow(int x,int y,int w,int h); + +// provided for back compatability: +int fl_draw_symbol(const char *label,int x,int y,int w,int h,Fl_Color col) { + const char *p = label; + if (*p++ != '@') return 0; + fl_init_symbols(); + int equalscale = 0; + if (*p == '#') {equalscale = 1; p++;} + if (*p == '-' && p[1]>='1' && p[1]<='9') { + int n = p[1]-'0'; + x += n; y += n; w -= 2*n; h -= 2*n; + p += 2; + } else if (*p == '+' && p[1]>='1' && p[1]<='9') { + int n = p[1]-'0'; + x -= n; y -= n; w += 2*n; h += 2*n; + p += 2; + } + if (w < 10) {x -= (10-w)/2; w = 10;} + if (h < 10) {y -= (10-h)/2; h = 10;} + w = (w-1)|1; h = (h-1)|1; + char flip_x = 0, flip_y = 0; + if (*p=='$') { + flip_x = 1; + p++; + } + if (*p=='%') { + flip_y = 1; + p++; + } + int rotangle; + switch (*p++) { + case '0': + rotangle = 1000*(p[1]-'0') + 100*(p[2]-'0') + 10*(p[3]-'0'); + p += 4; + break; + case '1': rotangle = 2250; break; + case '2': rotangle = 2700; break; + case '3': rotangle = 3150; break; + case '4': rotangle = 1800; break; + case '5': + case '6': rotangle = 0; break; + case '7': rotangle = 1350; break; + case '8': rotangle = 900; break; + case '9': rotangle = 450; break; + default: rotangle = 0; p--; break; + } + int pos = find(p); + if (!symbols[pos].notempty) return 0; + if (symbols[pos].scalable == 3) { // kludge to detect return arrow + fl_return_arrow(x,y,w,h); + return 1; + } + fl_push_matrix(); + fl_translate(x+w/2,y+h/2); + if (symbols[pos].scalable) { + if (equalscale) {if (w0; i--, a-=da, r-=dr1) { + double ar = a/180.0 * M_PI; + vv(cos(ar)*r, sin(ar)*r); + } + for (i=27; i>=0; a+=da, i--, r-=dr2) { + double ar = a/180.0 * M_PI; + vv(cos(ar)*r, sin(ar)*r); + } + if (j&1) { + EC; + } else { + ECP; + } + } +} + +static void draw_refresh(Fl_Color c) { + draw_round_arrow(c); + fl_rotate(180.0); + draw_round_arrow(c); + fl_rotate(-180.0); +} + +static void draw_reload(Fl_Color c) { + fl_rotate(-135.0); + draw_round_arrow(c, 10); + fl_rotate(135.0); +} + +static void draw_undo(Fl_Color c) { + fl_translate(0.0, 0.2); + fl_scale(1.0, -1.0); + draw_round_arrow(c, 6); + fl_scale(1.0, -1.0); + fl_translate(0.0, -0.2); +} + +static void draw_redo(Fl_Color c) { + fl_scale(-1.0, 1.0); + draw_undo(c); + fl_scale(-1.0, 1.0); +} + +static void fl_init_symbols(void) { + static char beenhere; + if (beenhere) return; + beenhere = 1; + symbnumb = 0; + + fl_add_symbol("", draw_arrow1, 1); + fl_add_symbol("->", draw_arrow1, 1); + fl_add_symbol(">", draw_arrow2, 1); + fl_add_symbol(">>", draw_arrow3, 1); + fl_add_symbol(">|", draw_arrowbar, 1); + fl_add_symbol(">[]", draw_arrowbox, 1); + fl_add_symbol("|>", draw_bararrow, 1); + fl_add_symbol("<-", draw_arrow01, 1); + fl_add_symbol("<", draw_arrow02, 1); + fl_add_symbol("<<", draw_arrow03, 1); + fl_add_symbol("|<", draw_0arrowbar, 1); + fl_add_symbol("[]<", draw_0arrowbox, 1); + fl_add_symbol("<|", draw_0bararrow, 1); + fl_add_symbol("<->", draw_doublearrow, 1); + fl_add_symbol("-->", draw_arrow, 1); + fl_add_symbol("+", draw_plus, 1); + fl_add_symbol("->|", draw_arrow1bar, 1); + fl_add_symbol("arrow", draw_arrow, 1); + fl_add_symbol("returnarrow", 0, 3); + fl_add_symbol("square", draw_square, 1); + fl_add_symbol("circle", draw_circle, 1); + fl_add_symbol("line", draw_line, 1); + fl_add_symbol("plus", draw_plus, 1); + fl_add_symbol("menu", draw_menu, 1); + fl_add_symbol("UpArrow", draw_uparrow, 1); + fl_add_symbol("DnArrow", draw_downarrow, 1); + fl_add_symbol("||", draw_doublebar, 1); + fl_add_symbol("search", draw_search, 1); + fl_add_symbol("FLTK", draw_fltk, 1); + + fl_add_symbol("filenew", draw_filenew, 1); + fl_add_symbol("fileopen", draw_fileopen, 1); + fl_add_symbol("filesave", draw_filesave, 1); + fl_add_symbol("filesaveas", draw_filesaveas, 1); + fl_add_symbol("fileprint", draw_fileprint, 1); + + fl_add_symbol("refresh", draw_refresh, 1); + fl_add_symbol("reload", draw_reload, 1); + fl_add_symbol("undo", draw_undo, 1); + fl_add_symbol("redo", draw_redo, 1); + +// fl_add_symbol("file", draw_file, 1); +} + +// +// End of "$Id: fl_symbols.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/fl_vertex.cxx b/plugins/zynaddsubfx/fltk/src/fl_vertex.cxx new file mode 100644 index 000000000..87faee2c9 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/fl_vertex.cxx @@ -0,0 +1,325 @@ +// +// "$Id: fl_vertex.cxx 5190 2006-06-09 16:16:34Z mike $" +// +// Portable drawing routines for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + +// Portable drawing code for drawing arbitrary shapes with +// simple 2D transformations. See also fl_arc.cxx + +// matt: the Quartz implementation purposly doesn't use the Quartz matrix +// operations for reasons of compatibility and maintainability + +#include +#include +#include +#include +#include +#include + +struct matrix {double a, b, c, d, x, y;}; + +static matrix m = {1, 0, 0, 1, 0, 0}; + +static matrix stack[32]; +static int sptr = 0; + +void fl_push_matrix() { + if (sptr==32) + Fl::error("fl_push_matrix(): matrix stack overflow."); + else + stack[sptr++] = m; +} + +void fl_pop_matrix() { + if (sptr==0) + Fl::error("fl_pop_matrix(): matrix stack underflow."); + else + m = stack[--sptr]; +} + +void fl_mult_matrix(double a, double b, double c, double d, double x, double y) { + matrix o; + o.a = a*m.a + b*m.c; + o.b = a*m.b + b*m.d; + o.c = c*m.a + d*m.c; + o.d = c*m.b + d*m.d; + o.x = x*m.a + y*m.c + m.x; + o.y = x*m.b + y*m.d + m.y; + m = o; +} + +void fl_scale(double x,double y) {fl_mult_matrix(x,0,0,y,0,0);} + +void fl_scale(double x) {fl_mult_matrix(x,0,0,x,0,0);} + +void fl_translate(double x,double y) {fl_mult_matrix(1,0,0,1,x,y);} + +void fl_rotate(double d) { + if (d) { + double s, c; + if (d == 0) {s = 0; c = 1;} + else if (d == 90) {s = 1; c = 0;} + else if (d == 180) {s = 0; c = -1;} + else if (d == 270 || d == -90) {s = -1; c = 0;} + else {s = sin(d*M_PI/180); c = cos(d*M_PI/180);} + fl_mult_matrix(c,-s,s,c,0,0); + } +} + +// typedef what the x,y fields in a point are: +#ifdef WIN32 +typedef int COORD_T; +# define XPOINT XPoint +#elif defined(__APPLE_QUARTZ__) +typedef float COORD_T; +typedef struct { float x; float y; } QPoint; +# define XPOINT QPoint +extern float fl_quartz_line_width_; +#else +typedef short COORD_T; +# define XPOINT XPoint +#endif + +static XPOINT *p = (XPOINT *)0; + +static int p_size; +static int n; +static int what; +enum {LINE, LOOP, POLYGON, POINT_}; + +void fl_begin_points() {n = 0; what = POINT_;} + +void fl_begin_line() {n = 0; what = LINE;} + +void fl_begin_loop() {n = 0; what = LOOP;} + +void fl_begin_polygon() {n = 0; what = POLYGON;} + +double fl_transform_x(double x, double y) {return x*m.a + y*m.c + m.x;} + +double fl_transform_y(double x, double y) {return x*m.b + y*m.d + m.y;} + +double fl_transform_dx(double x, double y) {return x*m.a + y*m.c;} + +double fl_transform_dy(double x, double y) {return x*m.b + y*m.d;} + +static void fl_transformed_vertex(COORD_T x, COORD_T y) { + if (!n || x != p[n-1].x || y != p[n-1].y) { + if (n >= p_size) { + p_size = p ? 2*p_size : 16; + p = (XPOINT*)realloc((void*)p, p_size*sizeof(*p)); + } + p[n].x = x; + p[n].y = y; + n++; + } +} + +void fl_transformed_vertex(double xf, double yf) { +#ifdef __APPLE_QUARTZ__ + fl_transformed_vertex(COORD_T(xf), COORD_T(yf)); +#else + fl_transformed_vertex(COORD_T(rint(xf)), COORD_T(rint(yf))); +#endif +} + +void fl_vertex(double x,double y) { + fl_transformed_vertex(x*m.a + y*m.c + m.x, x*m.b + y*m.d + m.y); +} + +void fl_end_points() { +#ifdef WIN32 + for (int i=0; i1) XDrawPoints(fl_display, fl_window, fl_gc, p, n, 0); +#endif +} + +void fl_end_line() { + if (n < 2) { + fl_end_points(); + return; + } +#ifdef WIN32 + if (n>1) Polyline(fl_gc, p, n); +#elif defined(__APPLE_QD__) + if (n<=1) return; + MoveTo(p[0].x, p[0].y); + for (int i=1; i1) XDrawLines(fl_display, fl_window, fl_gc, p, n, 0); +#endif +} + +static void fixloop() { // remove equal points from closed path + while (n>2 && p[n-1].x == p[0].x && p[n-1].y == p[0].y) n--; +} + +void fl_end_loop() { + fixloop(); + if (n>2) fl_transformed_vertex((COORD_T)p[0].x, (COORD_T)p[0].y); + fl_end_line(); +} + +void fl_end_polygon() { + fixloop(); + if (n < 3) { + fl_end_line(); + return; + } +#ifdef WIN32 + if (n>2) { + SelectObject(fl_gc, fl_brush()); + Polygon(fl_gc, p, n); + } +#elif defined(__APPLE_QD__) + if (n<=1) return; + PolyHandle ph = OpenPoly(); + MoveTo(p[0].x, p[0].y); + for (int i=1; i2) XFillPolygon(fl_display, fl_window, fl_gc, p, n, Convex, 0); +#endif +} + +static int gap; +#ifdef WIN32 +static int counts[20]; +static int numcount; +#endif + +void fl_begin_complex_polygon() { + fl_begin_polygon(); + gap = 0; +#ifdef WIN32 + numcount = 0; +#endif +} + +void fl_gap() { + while (n>gap+2 && p[n-1].x == p[gap].x && p[n-1].y == p[gap].y) n--; + if (n > gap+2) { + fl_transformed_vertex((COORD_T)p[gap].x, (COORD_T)p[gap].y); +#ifdef WIN32 + counts[numcount++] = n-gap; +#endif + gap = n; + } else { + n = gap; + } +} + +void fl_end_complex_polygon() { + fl_gap(); + if (n < 3) { + fl_end_line(); + return; + } +#ifdef WIN32 + if (n>2) { + SelectObject(fl_gc, fl_brush()); + PolyPolygon(fl_gc, p, counts, numcount); + } +#elif defined(__APPLE_QD__) + if (n<=1) return; + PolyHandle ph = OpenPoly(); + MoveTo(p[0].x, p[0].y); + for (int i=1; i2) XFillPolygon(fl_display, fl_window, fl_gc, p, n, 0, 0); +#endif +} + +// shortcut the closed circles so they use XDrawArc: +// warning: these do not draw rotated ellipses correctly! +// See fl_arc.c for portable version. + +void fl_circle(double x, double y,double r) { + double xt = fl_transform_x(x,y); + double yt = fl_transform_y(x,y); + double rx = r * (m.c ? sqrt(m.a*m.a+m.c*m.c) : fabs(m.a)); + double ry = r * (m.b ? sqrt(m.b*m.b+m.d*m.d) : fabs(m.d)); + int llx = (int)rint(xt-rx); + int w = (int)rint(xt+rx)-llx; + int lly = (int)rint(yt-ry); + int h = (int)rint(yt+ry)-lly; +#ifdef WIN32 + if (what==POLYGON) { + SelectObject(fl_gc, fl_brush()); + Pie(fl_gc, llx, lly, llx+w, lly+h, 0,0, 0,0); + } else + Arc(fl_gc, llx, lly, llx+w, lly+h, 0,0, 0,0); +#elif defined(__APPLE_QD__) + Rect rt; rt.left=llx; rt.right=llx+w; rt.top=lly; rt.bottom=lly+h; + (what == POLYGON ? PaintOval : FrameOval)(&rt); +#elif defined(__APPLE_QUARTZ__) + // Quartz warning : circle won't scale to current matrix! + CGContextAddArc(fl_gc, xt, yt, (w+h)*0.25f, 0, 2.0f*M_PI, 1); + (what == POLYGON ? CGContextFillPath : CGContextStrokePath)(fl_gc); +#else + (what == POLYGON ? XFillArc : XDrawArc) + (fl_display, fl_window, fl_gc, llx, lly, w, h, 0, 360*64); +#endif +} + +// +// End of "$Id: fl_vertex.cxx 5190 2006-06-09 16:16:34Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/flstring.c b/plugins/zynaddsubfx/fltk/src/flstring.c new file mode 100644 index 000000000..954f99b61 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/flstring.c @@ -0,0 +1,105 @@ +/* + * "$Id: flstring.c 4288 2005-04-16 00:13:17Z mike $" + * + * BSD string functions for the Fast Light Tool Kit (FLTK). + * + * Copyright 1998-2005 by Bill Spitzak and others. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems on the following page: + * + * http://www.fltk.org/str.php + */ + +#include "flstring.h" + + +/* + * 'fl_strlcat()' - Safely concatenate two strings. + */ + +size_t /* O - Length of string */ +fl_strlcat(char *dst, /* O - Destination string */ + const char *src, /* I - Source string */ + size_t size) { /* I - Size of destination string buffer */ + size_t srclen; /* Length of source string */ + size_t dstlen; /* Length of destination string */ + + + /* + * Figure out how much room is left... + */ + + dstlen = strlen(dst); + size -= dstlen + 1; + + if (!size) return (dstlen); /* No room, return immediately... */ + + /* + * Figure out how much room is needed... + */ + + srclen = strlen(src); + + /* + * Copy the appropriate amount... + */ + + if (srclen > size) srclen = size; + + memcpy(dst + dstlen, src, srclen); + dst[dstlen + srclen] = '\0'; + + return (dstlen + srclen); +} + + +/* + * 'fl_strlcpy()' - Safely copy two strings. + */ + +size_t /* O - Length of string */ +fl_strlcpy(char *dst, /* O - Destination string */ + const char *src, /* I - Source string */ + size_t size) { /* I - Size of destination string buffer */ + size_t srclen; /* Length of source string */ + + + /* + * Figure out how much room is needed... + */ + + size --; + + srclen = strlen(src); + + /* + * Copy the appropriate amount... + */ + + if (srclen > size) srclen = size; + + memcpy(dst, src, srclen); + dst[srclen] = '\0'; + + return (srclen); +} + + +/* + * End of "$Id: flstring.c 4288 2005-04-16 00:13:17Z mike $". + */ diff --git a/plugins/zynaddsubfx/fltk/src/flstring.h b/plugins/zynaddsubfx/fltk/src/flstring.h new file mode 100644 index 000000000..9455a7c5d --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/flstring.h @@ -0,0 +1,115 @@ +/* + * "$Id: flstring.h 5701 2007-02-20 18:43:10Z mike $" + * + * Common string header file for the Fast Light Tool Kit (FLTK). + * + * Copyright 1998-2007 by Bill Spitzak and others. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems on the following page: + * + * http://www.fltk.org/str.php + */ + +#ifndef flstring_h +# define flstring_h + +# include +# include +# include +# include +# include +# ifdef HAVE_STRINGS_H +# include +# endif /* HAVE_STRINGS_H */ +# include + +/* + * Apparently Unixware defines "index" to strchr (!) rather than + * providing a proper entry point or not providing the (obsolete) + * BSD function. Make sure index is not defined... + */ + +# ifdef index +# undef index +# endif /* index */ + +# if defined(WIN32) && !defined(__CYGWIN__) +# define strcasecmp(s,t) _stricmp((s), (t)) +# define strncasecmp(s,t,n) _strnicmp((s), (t), (n)) +// Visual C++ 2005 incorrectly displays a warning about the use of POSIX APIs +// on Windows, which is supposed to be POSIX compliant... Some of these +// functions are also defined in ISO C99... +# ifndef __WATCOMC__ +# define strdup _strdup +# define unlink _unlink +# endif // !__WATCOMC__ +# elif defined(__EMX__) +# define strcasecmp(s,t) stricmp((s), (t)) +# define strncasecmp(s,t,n) strnicmp((s), (t), (n)) +# endif /* WIN32 */ + +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ + +/* + * MetroWerks' CodeWarrior put thes "non-standard" functions in + * which unfortunatly does not play well otherwise + * when included - to be resolved... + */ + +# if defined(__APPLE__) && defined(__MWERKS__) && defined(_MSL_USING_MW_C_HEADERS) +int strcasecmp(const char*,const char*); +int strncasecmp(const char*,const char*,int); +char *strdup(const char*); +# endif + +FL_EXPORT extern int fl_snprintf(char *, size_t, const char *, ...); +# if !HAVE_SNPRINTF +# define snprintf fl_snprintf +# endif /* !HAVE_SNPRINTF */ + +FL_EXPORT extern int fl_vsnprintf(char *, size_t, const char *, va_list ap); +# if !HAVE_VSNPRINTF +# define vsnprintf fl_vsnprintf +# endif /* !HAVE_VSNPRINTF */ + +/* + * strlcpy() and strlcat() are some really useful BSD string functions + * that work the way strncpy() and strncat() *should* have worked. + */ + +FL_EXPORT extern size_t fl_strlcat(char *, const char *, size_t); +# if !HAVE_STRLCAT +# define strlcat fl_strlcat +# endif /* !HAVE_STRLCAT */ + +FL_EXPORT extern size_t fl_strlcpy(char *, const char *, size_t); +# if !HAVE_STRLCPY +# define strlcpy fl_strlcpy +# endif /* !HAVE_STRLCPY */ + +# ifdef __cplusplus +} +# endif /* __cplusplus */ +#endif /* !flstring_h */ + + +/* + * End of "$Id: flstring.h 5701 2007-02-20 18:43:10Z mike $". + */ diff --git a/plugins/zynaddsubfx/fltk/src/mediumarrow.h b/plugins/zynaddsubfx/fltk/src/mediumarrow.h new file mode 100644 index 000000000..8a1fe8cbc --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/mediumarrow.h @@ -0,0 +1,6 @@ +#define mediumarrow_width 16 +#define mediumarrow_height 16 +static unsigned char mediumarrow_bits[] = { + 0x40, 0x00, 0x60, 0x00, 0x70, 0x00, 0x78, 0x00, 0xfc, 0x3f, 0x78, 0x00, + 0x70, 0x00, 0x60, 0x02, 0x40, 0x06, 0x00, 0x0e, 0x00, 0x1e, 0xfc, 0x3f, + 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x06, 0x00, 0x02}; diff --git a/plugins/zynaddsubfx/fltk/src/numericsort.c b/plugins/zynaddsubfx/fltk/src/numericsort.c new file mode 100644 index 000000000..97c6d1ea3 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/numericsort.c @@ -0,0 +1,111 @@ +/* + * "$Id: numericsort.c 4288 2005-04-16 00:13:17Z mike $" + * + * Numeric sorting routine for the Fast Light Tool Kit (FLTK). + * + * Copyright 1998-2005 by Bill Spitzak and others. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems on the following page: + * + * http://www.fltk.org/str.php + */ + +/* My own scandir sorting function, useful for the film industry where + we have many files with numbers in their names: */ + +#include +#include +#include +#include + +#include + +#if !defined(WIN32) || defined(__CYGWIN__) +# ifdef HAVE_DIRENT_H +# include +# else +# define dirent direct +# if HAVE_SYS_NDIR_H +# include +# endif /* HAVE_SYS_NDIR_H */ +# if HAVE_SYS_DIR_H +# include +# endif /* HAVE_SYS_DIR_H */ +# if HAVE_NDIR_H +# include +# endif /* HAVE_NDIR_H */ +# endif /* HAVE_DIRENT_H */ +#endif /* !WIN32 || __CYGWIN__ */ + +/* + * 'numericsort()' - Compare two directory entries, possibly with + * a case-insensitive comparison... + */ + +static int numericsort(struct dirent **A, struct dirent **B, int cs) { + const char* a = (*A)->d_name; + const char* b = (*B)->d_name; + int ret = 0; + for (;;) { + if (isdigit(*a & 255) && isdigit(*b & 255)) { + int diff,magdiff; + while (*a == '0') a++; + while (*b == '0') b++; + while (isdigit(*a & 255) && *a == *b) {a++; b++;} + diff = (isdigit(*a & 255) && isdigit(*b & 255)) ? *a - *b : 0; + magdiff = 0; + while (isdigit(*a & 255)) {magdiff++; a++;} + while (isdigit(*b & 255)) {magdiff--; b++;} + if (magdiff) {ret = magdiff; break;} /* compare # of significant digits*/ + if (diff) {ret = diff; break;} /* compare first non-zero digit */ + } else { + if (cs) { + /* compare case-sensitive */ + if ((ret = *a-*b)) break; + } else { + /* compare case-insensitve */ + if ((ret = tolower(*a & 255)-tolower(*b & 255))) break; + } + + if (!*a) break; + a++; b++; + } + } + if (!ret) return 0; + else return (ret < 0) ? -1 : 1; +} + +/* + * 'fl_casenumericsort()' - Compare directory entries with case-sensitivity. + */ + +int fl_casenumericsort(struct dirent **A, struct dirent **B) { + return numericsort(A, B, 0); +} + +/* + * 'fl_numericsort()' - Compare directory entries with case-sensitivity. + */ + +int fl_numericsort(struct dirent **A, struct dirent **B) { + return numericsort(A, B, 1); +} + +/* + * End of "$Id: numericsort.c 4288 2005-04-16 00:13:17Z mike $". + */ diff --git a/plugins/zynaddsubfx/fltk/src/scandir.c b/plugins/zynaddsubfx/fltk/src/scandir.c new file mode 100644 index 000000000..79a4dbec2 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/scandir.c @@ -0,0 +1,124 @@ +/* Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library 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 +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +USA. */ + +#if defined(WIN32) && !defined(__CYGWIN__) +# include "scandir_win32.c" +#else + +# include "flstring.h" + +# if !HAVE_SCANDIR +# include +# include +# include + +# if HAVE_DIRENT_H +# include +# define NAMLEN(dirent) strlen((dirent)->d_name) +# else +# define dirent direct +# define NAMLEN(dirent) (dirent)->d_namlen +# if HAVE_SYS_NDIR_H +# include +# endif +# if HAVE_SYS_DIR_H +# include +# endif +# if HAVE_NDIR_H +# include +# endif +# endif + +int +fl_scandir(const char *dir, struct dirent ***namelist, + int (*select)(struct dirent *), + int (*compar)(struct dirent **, struct dirent **)) +{ + DIR *dp = opendir (dir); + struct dirent **v = NULL; + size_t vsize = 0, i; + struct dirent *d; + int save; + + if (dp == NULL) + return -1; + + save = errno; + errno = 0; + + i = 0; + while ((d = readdir (dp)) != NULL) + if (select == NULL || (*select) (d)) + { + size_t dsize; + + if (i == vsize) + { + struct dirent **newv; + if (vsize == 0) + vsize = 10; + else + vsize *= 2; + newv = (struct dirent **) realloc (v, vsize * sizeof (*v)); + if (newv == NULL) + { + lose: + errno = ENOMEM; + break; + } + v = newv; + } + +# define _D_EXACT_NAMLEN(d) (strlen ((d)->d_name)) +# define _D_ALLOC_NAMLEN(d) (sizeof (d)->d_name > 1 ? sizeof (d)->d_name : \ + _D_EXACT_NAMLEN (d) + 1) + + dsize = &d->d_name[_D_ALLOC_NAMLEN (d)] - (char *) d; + v[i] = (struct dirent *) malloc (dsize); + if (v[i] == NULL) + goto lose; + + memcpy (v[i++], d, dsize); + } + + if (errno != 0) + { + save = errno; + (void) closedir (dp); + while (i > 0) + free (v[--i]); + free (v); + errno = save; + return -1; + } + + (void) closedir (dp); + errno = save; + + /* Sort the list if we have a comparison function to sort with. */ + if (compar) qsort (v, i, sizeof (*v), (int (*)(const void *, const void *))compar); + *namelist = v; + return i; +} + +# endif +#endif + +/* + * End of "$Id: scandir.c 4052 2005-02-24 21:55:12Z mike $". + */ diff --git a/plugins/zynaddsubfx/fltk/src/scandir_win32.c b/plugins/zynaddsubfx/fltk/src/scandir_win32.c new file mode 100644 index 000000000..34475095a --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/scandir_win32.c @@ -0,0 +1,115 @@ +/* + * "$Id: scandir_win32.c 4548 2005-08-29 20:16:36Z matt $" + * + * WIN32 scandir function for the Fast Light Tool Kit (FLTK). + * + * Copyright 1998-2005 by Bill Spitzak and others. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems on the following page: + * + * http://www.fltk.org/str.php + */ + +#ifndef __CYGWIN__ +/* Emulation of posix scandir() call */ + +#include +#include "flstring.h" +#include +#include + +int fl_scandir(const char *dirname, struct dirent ***namelist, + int (*select)(struct dirent *), + int (*compar)(struct dirent **, struct dirent **)) { + int len; + char *findIn, *d, is_dir = 0; + WIN32_FIND_DATA find; + HANDLE h; + int nDir = 0, NDir = 0; + struct dirent **dir = 0, *selectDir; + unsigned long ret; + + len = strlen(dirname); + findIn = (char *)malloc((size_t)(len+5)); + + if (!findIn) return -1; + + strcpy(findIn, dirname); + for (d = findIn; *d; d++) if (*d=='/') *d='\\'; + if ((len==0)) { strcpy(findIn, ".\\*"); } + if ((len==2)&&findIn[1]==':'&&isalpha(findIn[0])) { *d++ = '\\'; *d = 0; } + if ((len==1)&& (d[-1]=='.')) { strcpy(findIn, ".\\*"); is_dir = 1; } + if ((len>0) && (d[-1]=='\\')) { *d++ = '*'; *d = 0; is_dir = 1; } + if ((len>1) && (d[-1]=='.') && (d[-2]=='\\')) { d[-1] = '*'; is_dir = 1; } + if (!is_dir) { /* this file may still be a directory that we need to list */ + DWORD attr = GetFileAttributes(findIn); + if (attr&FILE_ATTRIBUTE_DIRECTORY) + strcpy(d, "\\*"); + } + if ((h=FindFirstFile(findIn, &find))==INVALID_HANDLE_VALUE) { + free(findIn); + ret = GetLastError(); + if (ret != ERROR_NO_MORE_FILES) { + nDir = -1; + } + *namelist = dir; + return nDir; + } + do { + selectDir=(struct dirent*)malloc(sizeof(struct dirent)+strlen(find.cFileName)+2); + strcpy(selectDir->d_name, find.cFileName); + if (find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + /* Append a trailing slash to directory names... */ + strcat(selectDir->d_name, "/"); + } + if (!select || (*select)(selectDir)) { + if (nDir==NDir) { + struct dirent **tempDir = (struct dirent **)calloc(sizeof(struct dirent*), (size_t)(NDir+33)); + if (NDir) memcpy(tempDir, dir, sizeof(struct dirent*)*NDir); + if (dir) free(dir); + dir = tempDir; + NDir += 32; + } + dir[nDir] = selectDir; + nDir++; + dir[nDir] = 0; + } else { + free(selectDir); + } + } while (FindNextFile(h, &find)); + ret = GetLastError(); + if (ret != ERROR_NO_MORE_FILES) { + /* don't return an error code, because the dir list may still be valid + up to this point */ + } + FindClose(h); + + free (findIn); + + if (compar) qsort(dir, (size_t)nDir, sizeof(*dir), + (int(*)(const void*, const void*))compar); + + *namelist = dir; + return nDir; +} + +#endif + +/* + * End of "$Id: scandir_win32.c 4548 2005-08-29 20:16:36Z matt $". + */ diff --git a/plugins/zynaddsubfx/fltk/src/screen_xywh.cxx b/plugins/zynaddsubfx/fltk/src/screen_xywh.cxx new file mode 100644 index 000000000..d67019708 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/screen_xywh.cxx @@ -0,0 +1,256 @@ +// +// "$Id: screen_xywh.cxx 5848 2007-05-20 16:18:31Z mike $" +// +// Screen/monitor bounding box API for the Fast Light Tool Kit (FLTK). +// +// Copyright 1998-2005 by Bill Spitzak and others. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// +// Please report all bugs and problems on the following page: +// +// http://www.fltk.org/str.php +// + + +#include +#include +#include + + +// Number of screens... +static int num_screens = 0; + +#ifdef WIN32 +# if !defined(HMONITOR_DECLARED) && (_WIN32_WINNT < 0x0500) +# define COMPILE_MULTIMON_STUBS +# include +# endif // !HMONITOR_DECLARED && _WIN32_WINNT < 0x0500 + +// We go the much more difficult route of individually picking some multi-screen +// functions from the USER32.DLL . If these functions are not available, we +// will gracefully fall back to single monitor support. +// +// If we were to insist on the existence of "EnumDisplayMonitors" and +// "GetMonitorInfoA", it would be impossible to use FLTK on Windows 2000 +// before SP2 or earlier. + +// BOOL EnumDisplayMonitors(HDC, LPCRECT, MONITORENUMPROC, LPARAM) +typedef BOOL (WINAPI* fl_edm_func)(HDC, LPCRECT, MONITORENUMPROC, LPARAM); +// BOOL GetMonitorInfo(HMONITOR, LPMONITORINFO) +typedef BOOL (WINAPI* fl_gmi_func)(HMONITOR, LPMONITORINFO); + +static fl_gmi_func fl_gmi = NULL; // used to get a proc pointer for GetMonitorInfoA + +static RECT screens[16]; + +static BOOL CALLBACK screen_cb(HMONITOR mon, HDC, LPRECT r, LPARAM) { + if (num_screens >= 16) return TRUE; + + MONITORINFO mi; + mi.cbSize = sizeof(mi); + +// GetMonitorInfo(mon, &mi); +// (but we use our self-aquired function pointer instead) + if (fl_gmi(mon, &mi)) { + screens[num_screens] = mi.rcWork; + num_screens ++; + } + return TRUE; +} + +static void screen_init() { + // Since not all versions of Windows include multiple monitor support, + // we do a run-time check for the required functions... + HMODULE hMod = GetModuleHandle("USER32.DLL"); + + if (hMod) { + // check that EnumDisplayMonitors is available + fl_edm_func fl_edm = (fl_edm_func)GetProcAddress(hMod, "EnumDisplayMonitors"); + + if (fl_edm) { + // We do have EnumDisplayMonitors, so lets find out how many monitors... + num_screens = GetSystemMetrics(SM_CMONITORS); + + if (num_screens > 1) { + // If there is more than 1 monitor, enumerate them... + fl_gmi = (fl_gmi_func)GetProcAddress(hMod, "GetMonitorInfoA"); + + if (fl_gmi) { + // We have GetMonitorInfoA, enumerate all the screens... + num_screens = 0; +// EnumDisplayMonitors(0,0,screen_cb,0); +// (but we use our self-aquired function pointer instead) + fl_edm(0, 0, screen_cb, 0); + return; + } + } + } + } + + // If we get here, assume we have 1 monitor... + num_screens = 1; +} +#elif defined(__APPLE__) +XRectangle screens[16]; + +static void screen_init() { + GDHandle gd; + + for (gd = GetDeviceList(), num_screens = 0; gd; gd = GetNextDevice(gd)) { + GDPtr gp = *gd; + screens[num_screens].x = gp->gdRect.left; + screens[num_screens].y = gp->gdRect.top; + screens[num_screens].width = gp->gdRect.right - gp->gdRect.left; + screens[num_screens].height = gp->gdRect.bottom - gp->gdRect.top; + + num_screens ++; + if (num_screens >= 16) break; + } +} +#elif HAVE_XINERAMA +# include + +// Screen data... +static XineramaScreenInfo *screens; + +static void screen_init() { + if (!fl_display) fl_open_display(); + + if (XineramaIsActive(fl_display)) { + screens = XineramaQueryScreens(fl_display, &num_screens); + } else num_screens = 1; +} +#else +static void screen_init() { + num_screens = 1; +} +#endif // WIN32 + + +// Return the number of screens... +int Fl::screen_count() { + if (!num_screens) screen_init(); + + return num_screens; +} + +// Return the screen bounding rect for the given mouse position... +void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my) { + if (!num_screens) screen_init(); + +#ifdef WIN32 + if (num_screens > 1) { + int i; + + for (i = 0; i < num_screens; i ++) { + if (mx >= screens[i].left && mx < screens[i].right && + my >= screens[i].top && my < screens[i].bottom) { + X = screens[i].left; + Y = screens[i].top; + W = screens[i].right - screens[i].left; + H = screens[i].bottom - screens[i].top; + return; + } + } + } +#elif defined(__APPLE__) + if (num_screens > 1) { + int i; + + for (i = 0; i < num_screens; i ++) { + if (mx >= screens[i].x && + mx < (screens[i].x + screens[i].width) && + my >= screens[i].y && + my < (screens[i].y + screens[i].height)) { + X = screens[i].x; + Y = screens[i].y; + W = screens[i].width; + H = screens[i].height; + return; + } + } + } +#elif HAVE_XINERAMA + if (num_screens > 1) { + int i; + + for (i = 0; i < num_screens; i ++) { + if (mx >= screens[i].x_org && + mx < (screens[i].x_org + screens[i].width) && + my >= screens[i].y_org && + my < (screens[i].y_org + screens[i].height)) { + X = screens[i].x_org; + Y = screens[i].y_org; + W = screens[i].width; + H = screens[i].height; + return; + } + } + } +#else + (void)mx; + (void)my; +#endif // WIN32 + + X = Fl::x(); + Y = Fl::y(); + W = Fl::w(); + H = Fl::h(); +} + +// Return the screen bounding rect for the given screen... +void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int n) { + if (!num_screens) screen_init(); + +#ifdef WIN32 + if (num_screens > 1 && n >= 0 && n < num_screens) { + X = screens[n].left; + Y = screens[n].top; + W = screens[n].right - screens[n].left; + H = screens[n].bottom - screens[n].top; + return; + } +#elif defined(__APPLE__) + if (num_screens > 1 && n >= 0 && n < num_screens) { + X = screens[n].x; + Y = screens[n].y; + W = screens[n].width; + H = screens[n].height; + return; + } +#elif HAVE_XINERAMA + if (num_screens > 1 && n >= 0 && n < num_screens) { + X = screens[n].x_org; + Y = screens[n].y_org; + W = screens[n].width; + H = screens[n].height; + return; + } +#else + (void)n; +#endif // WIN32 + + X = Fl::x(); + Y = Fl::y(); + W = Fl::w(); + H = Fl::h(); +} + + +// +// End of "$Id: screen_xywh.cxx 5848 2007-05-20 16:18:31Z mike $". +// diff --git a/plugins/zynaddsubfx/fltk/src/slowarrow.h b/plugins/zynaddsubfx/fltk/src/slowarrow.h new file mode 100644 index 000000000..46a572c97 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/slowarrow.h @@ -0,0 +1,6 @@ +#define slowarrow_width 16 +#define slowarrow_height 16 +static unsigned char slowarrow_bits[] = { + 0x40, 0x00, 0x40, 0x00, 0x60, 0x00, 0x60, 0x00, 0xf0, 0x0f, 0x60, 0x00, + 0x60, 0x00, 0x40, 0x02, 0x40, 0x02, 0x00, 0x06, 0x00, 0x06, 0xf0, 0x0f, + 0x00, 0x06, 0x00, 0x06, 0x00, 0x02, 0x00, 0x02}; diff --git a/plugins/zynaddsubfx/fltk/src/tile.xpm b/plugins/zynaddsubfx/fltk/src/tile.xpm new file mode 100644 index 000000000..872e0f70c --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/tile.xpm @@ -0,0 +1,91 @@ +/* XPM */ +static char tile_cmap[3][32] = { +"O c #FFFFFF", +"o c #EFEFEF", +". c #E8E8E8" +}; +static const char * tile_xpm[] = { +"64 64 3 1", +tile_cmap[0], +tile_cmap[1], +tile_cmap[2], + +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"................................................................", +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", + +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"................................................................", +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", + +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"................................................................", +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", + +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"................................................................", +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", + +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"................................................................", +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", + +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"................................................................", +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", + +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"................................................................", +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", + +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"................................................................", +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", + +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"................................................................", +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", + +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"................................................................", +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", + +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"................................................................", +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", + +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"................................................................", +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", + +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"................................................................", +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", + +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"................................................................", +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", + +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"................................................................", +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", + +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"................................................................", +"oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO"}; diff --git a/plugins/zynaddsubfx/fltk/src/vsnprintf.c b/plugins/zynaddsubfx/fltk/src/vsnprintf.c new file mode 100644 index 000000000..f768236c2 --- /dev/null +++ b/plugins/zynaddsubfx/fltk/src/vsnprintf.c @@ -0,0 +1,281 @@ +/* + * "$Id: vsnprintf.c 5850 2007-05-21 15:56:17Z matt $" + * + * snprintf() and vsnprintf() functions for the Fast Light Tool Kit (FLTK). + * + * Copyright 1998-2007 by Bill Spitzak and others. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA. + * + * Please report all bugs and problems on the following page: + * + * http://www.fltk.org/str.php + */ + +#include +#include "flstring.h" + +#ifdef HAVE_SYS_STDTYPES_H +# include +#endif /* HAVE_SYS_STDTYPES_H */ + +#ifdef __cplusplus +extern "C" { +#endif + +int fl_vsnprintf(char* buffer, size_t bufsize, const char* format, va_list ap) { + char *bufptr, /* Pointer to position in buffer */ + *bufend, /* Pointer to end of buffer */ + sign, /* Sign of format width */ + size, /* Size character (h, l, L) */ + type; /* Format type character */ + int width, /* Width of field */ + prec; /* Number of characters of precision */ + char tformat[100], /* Temporary format string for sprintf() */ + *tptr, /* Pointer into temporary format */ + temp[1024]; /* Buffer for formatted numbers */ + char *s; /* Pointer to string */ + int slen; /* Length of string */ + int bytes; /* Total number of bytes needed */ + + + /* + * Loop through the format string, formatting as needed... + */ + + bufptr = buffer; + bufend = buffer + bufsize - 1; + bytes = 0; + + while (*format) { + if (*format == '%') { + tptr = tformat; + *tptr++ = *format++; + + if (*format == '%') { + if (bufptr && bufptr < bufend) *bufptr++ = *format; + bytes ++; + format ++; + continue; + } else if (strchr(" -+#\'", *format)) { + *tptr++ = *format; + sign = *format++; + } else sign = 0; + + if (*format == '*') { + /* Get width from argument... */ + format ++; + width = va_arg(ap, int); + snprintf(tptr, sizeof(tformat) - (tptr - tformat), "%d", width); + tptr += strlen(tptr); + } else { + width = 0; + while (isdigit(*format & 255)) { + if (tptr < (tformat + sizeof(tformat) - 1)) *tptr++ = *format; + width = width * 10 + *format++ - '0'; + } + } + + if (*format == '.') { + if (tptr < (tformat + sizeof(tformat) - 1)) *tptr++ = *format; + format ++; + + if (*format == '*') { + /* Get precision from argument... */ + format ++; + prec = va_arg(ap, int); + snprintf(tptr, sizeof(tformat) - (tptr - tformat), "%d", prec); + tptr += strlen(tptr); + } else { + prec = 0; + while (isdigit(*format & 255)) { + if (tptr < (tformat + sizeof(tformat) - 1)) *tptr++ = *format; + prec = prec * 10 + *format++ - '0'; + } + } + } else prec = -1; + + size = '\0'; + + if (*format == 'l' && format[1] == 'l') { + size = 'L'; + if (tptr < (tformat + sizeof(tformat) - 2)) { + *tptr++ = 'l'; + *tptr++ = 'l'; + } + format += 2; + } else if (*format == 'h' || *format == 'l' || *format == 'L') { + if (tptr < (tformat + sizeof(tformat) - 1)) *tptr++ = *format; + size = *format++; + } + + if (!*format) break; + + if (tptr < (tformat + sizeof(tformat) - 1)) *tptr++ = *format; + type = *format++; + *tptr = '\0'; + + switch (type) { + case 'E' : /* Floating point formats */ + case 'G' : + case 'e' : + case 'f' : + case 'g' : + if ((width + 2) > sizeof(temp)) break; + + sprintf(temp, tformat, va_arg(ap, double)); + + bytes += strlen(temp); + + if (bufptr) { + if ((bufptr + strlen(temp)) > bufend) { + strncpy(bufptr, temp, (size_t)(bufend - bufptr)); + bufptr = bufend; + } else { + strcpy(bufptr, temp); + bufptr += strlen(temp); + } + } + break; + + case 'B' : /* Integer formats */ + case 'X' : + case 'b' : + case 'd' : + case 'i' : + case 'o' : + case 'u' : + case 'x' : + if ((width + 2) > sizeof(temp)) break; + +#ifdef HAVE_LONG_LONG + if (size == 'L') + sprintf(temp, tformat, va_arg(ap, long long)); + else +#endif /* HAVE_LONG_LONG */ + if (size == 'l') + sprintf(temp, tformat, va_arg(ap, long)); + else + sprintf(temp, tformat, va_arg(ap, int)); + + bytes += strlen(temp); + + if (bufptr) { + if ((bufptr + strlen(temp)) > bufend) { + strncpy(bufptr, temp, (size_t)(bufend - bufptr)); + bufptr = bufend; + } else { + strcpy(bufptr, temp); + bufptr += strlen(temp); + } + } + break; + + case 'p' : /* Pointer value */ + if ((width + 2) > sizeof(temp)) break; + + sprintf(temp, tformat, va_arg(ap, void *)); + + bytes += strlen(temp); + + if (bufptr) { + if ((bufptr + strlen(temp)) > bufend) { + strncpy(bufptr, temp, (size_t)(bufend - bufptr)); + bufptr = bufend; + } else { + strcpy(bufptr, temp); + bufptr += strlen(temp); + } + } + break; + + case 'c' : /* Character or character array */ + bytes += width; + + if (bufptr) { + if (width <= 1) *bufptr++ = va_arg(ap, int); + else { + if ((bufptr + width) > bufend) width = bufend - bufptr; + + memcpy(bufptr, va_arg(ap, char *), (size_t)width); + bufptr += width; + } + } + break; + + case 's' : /* String */ + if ((s = va_arg(ap, char *)) == NULL) s = "(null)"; + + slen = strlen(s); + if (slen > width && prec != width) width = slen; + + bytes += width; + + if (bufptr) { + if ((bufptr + width) > bufend) width = bufend - bufptr; + + if (slen > width) slen = width; + + if (sign == '-') { + strncpy(bufptr, s, (size_t)slen); + memset(bufptr + slen, ' ', (size_t)(width - slen)); + } else { + memset(bufptr, ' ', (size_t)(width - slen)); + strncpy(bufptr + width - slen, s, (size_t)slen); + } + + bufptr += width; + } + break; + + case 'n' : /* Output number of chars so far */ + *(va_arg(ap, int *)) = bytes; + break; + } + } else { + bytes ++; + + if (bufptr && bufptr < bufend) *bufptr++ = *format; + format ++; + } + } + + /* + * Nul-terminate the string and return the number of characters needed. + */ + + if (bufptr) *bufptr = '\0'; + + return (bytes); +} + +int fl_snprintf(char* str, size_t size, const char* fmt, ...) { + int ret; + va_list ap; + va_start(ap, fmt); + ret = vsnprintf(str, size, fmt, ap); + va_end(ap); + return ret; +} + +#ifdef __cplusplus +} +#endif + +/* + * End of "$Id: vsnprintf.c 5850 2007-05-21 15:56:17Z matt $". + */ + diff --git a/plugins/zynaddsubfx/logo.png b/plugins/zynaddsubfx/logo.png new file mode 100644 index 000000000..1b0fdc261 Binary files /dev/null and b/plugins/zynaddsubfx/logo.png differ diff --git a/plugins/zynaddsubfx/mxml/CHANGES b/plugins/zynaddsubfx/mxml/CHANGES new file mode 100644 index 000000000..956d5c5e0 --- /dev/null +++ b/plugins/zynaddsubfx/mxml/CHANGES @@ -0,0 +1,305 @@ +CHANGES - 2008-01-28 +-------------------- + +CHANGES IN Mini-XML 2.5 + + - The mxmldoc program now makes greater use of CSS and + supports a --css option to embed an alternate stylesheet. + - The mxmldoc program now supports --header and --footer + options to insert documentation content before and + after the generated content. + - The mxmldoc program now supports a --framed option to + generate framed HTML output. + - The mxmldoc program now creates a table of contents + including any headings in the --intro file when + generating HTML output. + - The man pages and man page output from mxmldoc did + not use "\-" for dashes (STR #68) + - The debug version of the Mini-XML DLL could not be + built (STR #65) + - Processing instructions and directives did not work + when not at the top level of a document (STR #67) + - Spaces around the "=" in attributes were not supported + (STR #67) + + +CHANGES IN Mini-XML 2.4 + + - Fixed shared library build problems on HP-UX and Mac OS X. + - The mxmldoc program did not output argument descriptions + for functions properly. + - All global settings (custom, error, and entity callbacks + and the wrap margin) are now managed separately for each + thread. + - Added mxmlElementDeleteAttr() function (STR #59) + - mxmlElementSetAttrf() did not work (STR #57) + - mxmlLoad*() incorrectly treated declarations as parent + elements (STR #56) + - mxmlLoad*() incorrectly allowed attributes without values + (STR #47) + - Fixed Visual C++ build problems (STR #49) + - mxmlLoad*() did not return NULL when an element contained + an error (STR #46) + - Added support for the apos character entity (STR #54) + - Fixed whitespace detection with Unicode characters (STR + #48) + - mxmlWalkNext() and mxmlWalkPrev() did not work correctly + when called with a node with no children as the top node + (STR #53) + + +CHANGES IN Mini-XML 2.3 + + - Added two exceptions to the LGPL to support static + linking of applications against Mini-XML + - The mxmldoc utility can now generate man pages, too. + - Added a mxmlNewXML() function + - Added a mxmlElementSetAttrf() function (STR #43) + - Added snprintf() emulation function for test program (STR + #32) + - Added the _CRT_SECURE_NO_DEPRECATE definition when + building on VC++ 2005 (STR #36) + - mxmlLoad*() did not detect missing > characters in + elements (STR #41) + - mxmlLoad*() did not detect missing close tags at the end + of an XML document (STR #45) + - Added user_data and ref_count members to mxml_node_t + structure + - Added mxmlReleaseNode() and mxmlRetainNode() APIs for + reference-counted nodes + - Added mxmlSetWrapMargin() to control the wrapping of XML + output + - Added conditional check for EINTR error code for + certain Windows compilers that do not define it (STR + #33) + - The mxmldoc program now generates correct HTML 4.0 + output - previously it generated invalid XHTML + - The mxmldoc program now supports "@deprecated@, + "@private@", and "@since version@" comments + - Fixed function and enumeration type bugs in mxmldoc. + - Fixed the XML schema for mxmldoc + - The mxmldoc program now supports --intro, --section, + and --title options + - The mxmlLoad*() functions could leak a node on an error + (STR #27) + - The mxml_vsnprintf() function could get in an infinite + loop on a buffer overflow (STR #25) + - Added new mxmlNewCDATA() and mxmlSetCDATA() functions + to create and set CDATA nodes, which are really just + special element nodes + - Added new MXML_IGNORE type and MXML_IGNORE_CB callback + to ignore non-element nodes, e.g. whitespace + - mxmlLoad*() crashed when reporting an error in some + invalid XML (STR #23) + + +CHANGES IN Mini-XML 2.2.2 + + - mxmlLoad*() did not treat custom data as opaque, so + whitespace characters would be lost. + + +CHANGES IN Mini-XML 2.2.1 + + - mxmlLoadFd(), mxmlLoadFile(), and mxmlLoadString() now + correctly return NULL on error (STR #21) + - mxmlNewInteger(), mxmlNewOpaque(), mxmlNewReal(), + mxmlNewText(), and mxmlNewTextf() incorrectly required + a parent node (STR #22) + - Fixed an XML output bug in mxmldoc. + - The "make install" target now uses the install command + to set the proper permissions on UNIX/Linux/OSX. + - Fixed a MingW/Cygwin compilation problem (STR #18) + + +CHANGES IN Mini-XML 2.2 + + - Added shared library support (STR #17) + - mxmlLoad*() now returns an error when an XML stream + contains illegal control characters (STR #10) + - mxmlLoad*() now returns an error when an element + contains two attributes with the same name in + conformance with the XML spec (STR #16) + - Added support for CDATA (STR #14, STR #15) + - Updated comment and processing instruction handling - + no entity support per XML specification. + - Added checking for invalid comment termination ("--->" + is not allowed) + + +CHANGES IN Mini-XML 2.1 + + - Added support for custom data nodes (STR #6) + - Now treat UTF-8 sequences which are longer than + necessary as an error (STR #4) + - Fixed entity number support (STR #8) + - Fixed mxmlLoadString() bug with UTF-8 (STR #7) + - Fixed entity lookup bug (STR #5) + - Added mxmlLoadFd() and mxmlSaveFd() functions. + - Fixed multi-word UTF-16 handling. + + +CHANGES IN Mini-XML 2.0 + + - New programmers manual. + - Added Visual C++ project files for Microsoft Windows + users. + - Added optimizations to mxmldoc, mxmlSaveFile(), and + mxmlIndexNew() (STR #2) + - mxmlEntityAddCallback() now returns an integer status + (STR #2) + - Added UTF-16 support (input only; all output is UTF-8) + - Added index functions to build a searchable index of + XML nodes. + - Added character entity callback interface to support + additional character entities beyond those defined in + the XHTML specification. + - Added support for XHTML character entities. + - The mxmldoc utility now produces XML output which + conforms to an updated XML schema, described in the file + "doc/mxmldoc.xsd". + - Changed the whitespace callback interface to return + strings instead of a single character, allowing for + greater control over the formatting of XML files + written using Mini-XML. THIS CHANGE WILL REQUIRE + CHANGES TO YOUR 1.x CODE IF YOU USE WHITESPACE + CALLBACKS. + - The mxmldoc utility is now capable of documenting C++ + classes, functions, and structures, and correctly + handles C++ comments. + - Added new modular tests for mxmldoc. + - Updated the mxmldoc output to be more compatible with + embedding in manuals produced with HTMLDOC. + - The makefile incorrectly included a "/" separator + between the destination path and install path. This + caused problems when building and installing with + MingW. + + +CHANGES IN Mini-XML 1.3 + + - Fixes for mxmldoc. + - Added support for reading standard HTML entity names. + - mxmlLoadString/File() did not decode character + entities in element names, attribute names, or + attribute values. + - mxmlLoadString/File() would crash when loading non- + conformant XML data under an existing parent (top) + node. + - Fixed several bugs in the mxmldoc utility. + - Added new error callback function to catch a variety + of errors and log them to someplace other than stderr. + - The mxmlElementSetAttr() function now allows for NULL + attribute values. + - The load and save functions now properly handle quoted + element and attribute name strings properly, e.g. for + !DOCTYPE declarations. + + +CHANGES IN Mini-XML 1.2 + + - Added new "set" methods to set the value of a node. + - Added new formatted text methods mxmlNewTextf() and + mxmlSetTextf() to create/set a text node value using + printf-style formats. + - Added new standard callbacks for use with the mxmlLoad + functions. + - Updated the HTML documentation to include examples of + the walk and load function output. + - Added --with/without-ansi configure option to control + the strdup() function check. + - Added --with/without-snprintf configure option to + control the snprintf() and vsnprintf() function + checks. + + +CHANGES IN Mini-XML 1.1.2 + + - The mxml(3) man page wasn't updated for the string + functions. + - mxmlSaveString() returned the wrong number of + characters. + - mxml_add_char() updated the buffer pointer in the + wrong place. + + +CHANGES IN Mini-XML 1.1.1 + + - The private mxml_add_ch() function did not update the + start-of-buffer pointer which could cause a crash when + using mxmlSaveString(). + - The private mxml_write_ws() function called putc() + instead of using the proper callback which could cause + a crash when using mxmlSaveString(). + - Added a mxmlSaveAllocString() convenience function for + saving an XML node tree to an allocated string. + + +CHANGES IN Mini-XML 1.1 + + - The mxmlLoadFile() function now uses dynamically + allocated string buffers for element names, attribute + names, and attribute values. Previously they were + capped at 16383, 255, and 255 bytes, respectively. + - Added a new mxmlLoadString() function for loading an + XML node tree from a string. + - Added a new mxmlSaveString() function for saving an + XML node tree to a string. + - Add emulation of strdup() if the local platform does + not provide the function. + + +CHANGES IN Mini-XML 1.0 + + - The mxmldoc program now handles function arguments, + structures, unions, enumerations, classes, and + typedefs properly. + - Documentation provided via mxmldoc and more in-line + comments in the code. + - Added man pages and packaging files. + + +CHANGES IN Mini-XML 0.93 + + - New mxmldoc example program that is also used to + create and update code documentation using XML and + produce HTML reference pages. + - Added mxmlAdd() and mxmlRemove() functions to add and + remove nodes from a tree. This provides more + flexibility over where the nodes are inserted and + allows nodes to be moved within the tree as needed. + - mxmlLoadFile() now correctly handles comments. + - mxmlLoadFile() now supports the required "gt", "quot", + and "nbsp" character entities. + - mxmlSaveFile() now uses newlines as whitespace + when valid to do so. + - mxmlFindElement() now also takes attribute name and + attribute value string arguments to limit the search + to specific elements with attributes and/or values. + NULL pointers can be used as "wildcards". + - Added uninstall target to makefile, and auto-reconfig + if Makefile.in or configure.in are changed. + - mxmlFindElement(), mxmlWalkNext(), and mxmlWalkPrev() + now all provide "descend" arguments to control whether + they descend into child nodes in the tree. + - Fixed some whitespace issues in mxmlLoadFile(). + - Fixed Unicode output and whitespace issues in + mxmlSaveFile(). + - mxmlSaveFile() now supports a whitespace callback to + provide more human-readable XML output under program + control. + + +CHANGES IN Mini-XML 0.92 + + - mxmlSaveFile() didn't return a value on success. + + +CHANGES IN Mini-XML 0.91 + + - mxmlWalkNext() would go into an infinite loop. + + +CHANGES IN Mini-XML 0.9 + + - Initial public release. diff --git a/plugins/zynaddsubfx/mxml/COPYING b/plugins/zynaddsubfx/mxml/COPYING new file mode 100644 index 000000000..fd9d3532a --- /dev/null +++ b/plugins/zynaddsubfx/mxml/COPYING @@ -0,0 +1,507 @@ + Mini-XML License + October 18, 2005 + + +The Mini-XML library and included programs are provided under the +terms of the GNU Library General Public License (LGPL) with the +following exceptions: + + 1. Static linking of applications to the Mini-XML library + does not constitute a derivative work and does not require + the author to provide source code for the application, use + the shared Mini-XML libraries, or link their applications + against a user-supplied version of Mini-XML. + + If you link the application to a modified version of + Mini-XML, then the changes to Mini-XML must be provided + under the terms of the LGPL in sections 1, 2, and 4. + + 2. You do not have to provide a copy of the Mini-XML license + with programs that are linked to the Mini-XML library, nor + do you have to identify the Mini-XML license in your + program or documentation as required by section 6 of the + LGPL. + + + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + [This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/plugins/zynaddsubfx/mxml/README b/plugins/zynaddsubfx/mxml/README new file mode 100644 index 000000000..3b880417d --- /dev/null +++ b/plugins/zynaddsubfx/mxml/README @@ -0,0 +1,204 @@ +README - 2008-01-28 +------------------- + + +INTRODUCTION + + This README file describes the Mini-XML library version 2.5. + + Mini-XML is a small XML parsing library that you can use to + read XML and XML-like data files in your application without + requiring large non-standard libraries. Mini-XML only + requires an ANSI C compatible compiler (GCC works, as do + most vendors' ANSI C compilers) and a "make" program. + + Mini-XML provides the following functionality: + + - Reading of UTF-8 and UTF-16 and writing of UTF-8 + encoded XML files and strings. + - Data is stored in a linked-list tree structure, + preserving the XML data hierarchy. + - Supports arbitrary element names, attributes, and + attribute values with no preset limits, just available + memory. + - Supports integer, real, opaque ("cdata"), and text + data types in "leaf" nodes. + - Functions for creating and managing trees of data. + - "Find" and "walk" functions for easily locating and + navigating trees of data. + + Mini-XML doesn't do validation or other types of processing + on the data based upon schema files or other sources of + definition information. + + +BUILDING Mini-XML + + Mini-XML comes with an autoconf-based configure script; just + type the following command to get things going: + + ./configure + + The default install prefix is /usr/local, which can be + overridden using the --prefix option: + + ./configure --prefix=/foo + + Other configure options can be found using the --help + option: + + ./configure --help + + Once you have configured the software, type "make" to do the + build and run the test program to verify that things are + working, as follows: + + make + + If you are using Mini-XML under Microsoft Windows with + Visual C++, use the included project files in the "vcnet" + subdirectory to build the library instead. + + +INSTALLING Mini-XML + + The "install" target will install Mini-XML in the lib and + include directories: + + make install + + Once you have installed it, use the "-lmxml" option to link + your application against it. + + +DOCUMENTATION + + The documentation is available in the "doc" subdirectory in + the files "mxml.html" (HTML) and "mxml.pdf" (PDF). You can + also look at the "testmxml.c" and "mxmldoc.c" source files + for examples of using Mini-XML. + + Mini-XML provides a single header file which you include: + + #include + + Nodes are defined by the "mxml_node_t" structure; the "type" + member defines the node type (element, integer, opaque, + real, or text) which determines which value you want to look + at in the "value" union. New nodes can be created using the + "mxmlNewElement()", "mxmlNewInteger()", "mxmlNewOpaque()", + "mxmlNewReal()", and "mxmlNewText()" functions. Only + elements can have child nodes, and the top node must be an + element, usually "?xml". + + You load an XML file using the "mxmlLoadFile()" function: + + FILE *fp; + mxml_node_t *tree; + + fp = fopen("filename.xml", "r"); + tree = mxmlLoadFile(NULL, fp, MXML_NO_CALLBACK); + fclose(fp); + + Similarly, you save an XML file using the "mxmlSaveFile()" + function: + + FILE *fp; + mxml_node_t *tree; + + fp = fopen("filename.xml", "w"); + mxmlSaveFile(tree, fp, MXML_NO_CALLBACK); + fclose(fp); + + The "mxmlLoadString()", "mxmlSaveAllocString()", and + "mxmlSaveString()" functions load XML node trees from and + save XML node trees to strings: + + char buffer[8192]; + char *ptr; + mxml_node_t *tree; + + ... + tree = mxmlLoadString(NULL, buffer, MXML_NO_CALLBACK); + + ... + mxmlSaveString(tree, buffer, sizeof(buffer), MXML_NO_CALLBACK); + + ... + ptr = mxmlSaveAllocString(tree, MXML_NO_CALLBACK); + + You can find a named element/node using the + "mxmlFindElement()" function: + + mxml_node_t *node = mxmlFindElement(tree, tree, "name", "attr", + "value", MXML_DESCEND); + + The "name", "attr", and "value" arguments can be passed as + NULL to act as wildcards, e.g.: + + /* Find the first "a" element */ + node = mxmlFindElement(tree, tree, "a", NULL, NULL, MXML_DESCEND); + + /* Find the first "a" element with "href" attribute */ + node = mxmlFindElement(tree, tree, "a", "href", NULL, MXML_DESCEND); + + /* Find the first "a" element with "href" to a URL */ + node = mxmlFindElement(tree, tree, "a", "href", + "http://www.easysw.com/~mike/mxml/", + MXML_DESCEND); + + /* Find the first element with a "src" attribute*/ + node = mxmlFindElement(tree, tree, NULL, "src", NULL, MXML_DESCEND); + + /* Find the first element with a "src" = "foo.jpg" */ + node = mxmlFindElement(tree, tree, NULL, "src", "foo.jpg", + MXML_DESCEND); + + You can also iterate with the same function: + + mxml_node_t *node; + + for (node = mxmlFindElement(tree, tree, "name", NULL, NULL, + MXML_DESCEND); + node != NULL; + node = mxmlFindElement(node, tree, "name", NULL, NULL, + MXML_DESCEND)) + { + ... do something ... + } + + Finally, once you are done with the XML data, use the + "mxmlDelete()" function to recursively free the memory that + is used for a particular node or the entire tree: + + mxmlDelete(tree); + + +GETTING HELP AND REPORTING PROBLEMS + + The Mini-XML web site provides access to a discussion forum + and bug reporting page: + + http://www.minixml.org/ + + +LEGAL STUFF + + The Mini-XML library is Copyright 2003-2008 by Michael Sweet. + + This library is free software; you can redistribute it + and/or modify it under the terms of the GNU Library General + Public License as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any + later version. + + This library 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 Library General Public License for + more details. + + You should have received a copy of the GNU Library General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA + 02139, USA. diff --git a/plugins/zynaddsubfx/mxml/mxml-attr.c b/plugins/zynaddsubfx/mxml/mxml-attr.c new file mode 100644 index 000000000..3b9ba69d3 --- /dev/null +++ b/plugins/zynaddsubfx/mxml/mxml-attr.c @@ -0,0 +1,321 @@ +/* + * "$Id: mxml-attr.c 308 2007-09-15 20:04:56Z mike $" + * + * Attribute support code for Mini-XML, a small XML-like file parsing library. + * + * Copyright 2003-2007 by Michael Sweet. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2, 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. + * + * Contents: + * + * mxmlElementDeleteAttr() - Delete an attribute. + * mxmlElementGetAttr() - Get an attribute. + * mxmlElementSetAttr() - Set an attribute. + * mxmlElementSetAttrf() - Set an attribute with a formatted value. + * mxml_set_attr() - Set or add an attribute name/value pair. + */ + +/* + * Include necessary headers... + */ + +#include "mxml-config.h" +#include "mxml.h" + + +/* + * Local functions... + */ + +static int mxml_set_attr(mxml_node_t *node, const char *name, + char *value); + + +/* + * 'mxmlElementDeleteAttr()' - Delete an attribute. + * + * @since Mini-XML 2.4@ + */ + +void +mxmlElementDeleteAttr(mxml_node_t *node,/* I - Element */ + const char *name)/* I - Attribute name */ +{ + int i; /* Looping var */ + mxml_attr_t *attr; /* Cirrent attribute */ + + +#ifdef DEBUG + fprintf(stderr, "mxmlElementDeleteAttr(node=%p, name=\"%s\")\n", + node, name ? name : "(null)"); +#endif /* DEBUG */ + + /* + * Range check input... + */ + + if (!node || node->type != MXML_ELEMENT || !name) + return; + + /* + * Look for the attribute... + */ + + for (i = node->value.element.num_attrs, attr = node->value.element.attrs; + i > 0; + i --, attr ++) + { +#ifdef DEBUG + printf(" %s=\"%s\"\n", attr->name, attr->value); +#endif /* DEBUG */ + + if (!strcmp(attr->name, name)) + { + /* + * Delete this attribute... + */ + + free(attr->name); + free(attr->value); + + i --; + if (i > 0) + memmove(attr, attr + 1, i * sizeof(mxml_attr_t)); + + node->value.element.num_attrs --; + return; + } + } +} + + +/* + * 'mxmlElementGetAttr()' - Get an attribute. + * + * This function returns NULL if the node is not an element or the + * named attribute does not exist. + */ + +const char * /* O - Attribute value or NULL */ +mxmlElementGetAttr(mxml_node_t *node, /* I - Element node */ + const char *name) /* I - Name of attribute */ +{ + int i; /* Looping var */ + mxml_attr_t *attr; /* Cirrent attribute */ + + +#ifdef DEBUG + fprintf(stderr, "mxmlElementGetAttr(node=%p, name=\"%s\")\n", + node, name ? name : "(null)"); +#endif /* DEBUG */ + + /* + * Range check input... + */ + + if (!node || node->type != MXML_ELEMENT || !name) + return (NULL); + + /* + * Look for the attribute... + */ + + for (i = node->value.element.num_attrs, attr = node->value.element.attrs; + i > 0; + i --, attr ++) + { +#ifdef DEBUG + printf(" %s=\"%s\"\n", attr->name, attr->value); +#endif /* DEBUG */ + + if (!strcmp(attr->name, name)) + { +#ifdef DEBUG + printf(" Returning \"%s\"!\n", attr->value); +#endif /* DEBUG */ + return (attr->value); + } + } + + /* + * Didn't find attribute, so return NULL... + */ + +#ifdef DEBUG + puts(" Returning NULL!\n"); +#endif /* DEBUG */ + + return (NULL); +} + + +/* + * 'mxmlElementSetAttr()' - Set an attribute. + * + * If the named attribute already exists, the value of the attribute + * is replaced by the new string value. The string value is copied + * into the element node. This function does nothing if the node is + * not an element. + */ + +void +mxmlElementSetAttr(mxml_node_t *node, /* I - Element node */ + const char *name, /* I - Name of attribute */ + const char *value) /* I - Attribute value */ +{ + char *valuec; /* Copy of value */ + + +#ifdef DEBUG + fprintf(stderr, "mxmlElementSetAttr(node=%p, name=\"%s\", value=\"%s\")\n", + node, name ? name : "(null)", value ? value : "(null)"); +#endif /* DEBUG */ + + /* + * Range check input... + */ + + if (!node || node->type != MXML_ELEMENT || !name) + return; + + if (value) + valuec = strdup(value); + else + valuec = NULL; + + if (mxml_set_attr(node, name, valuec)) + free(valuec); +} + + +/* + * 'mxmlElementSetAttrf()' - Set an attribute with a formatted value. + * + * If the named attribute already exists, the value of the attribute + * is replaced by the new formatted string. The formatted string value is + * copied into the element node. This function does nothing if the node + * is not an element. + * + * @since Mini-XML 2.3@ + */ + +void +mxmlElementSetAttrf(mxml_node_t *node, /* I - Element node */ + const char *name, /* I - Name of attribute */ + const char *format,/* I - Printf-style attribute value */ + ...) /* I - Additional arguments as needed */ +{ + va_list ap; /* Argument pointer */ + char *value; /* Value */ + + +#ifdef DEBUG + fprintf(stderr, + "mxmlElementSetAttrf(node=%p, name=\"%s\", format=\"%s\", ...)\n", + node, name ? name : "(null)", format ? format : "(null)"); +#endif /* DEBUG */ + + /* + * Range check input... + */ + + if (!node || node->type != MXML_ELEMENT || !name || !format) + return; + + /* + * Format the value... + */ + + va_start(ap, format); + value = _mxml_vstrdupf(format, ap); + va_end(ap); + + if (!value) + mxml_error("Unable to allocate memory for attribute '%s' in element %s!", + name, node->value.element.name); + else if (mxml_set_attr(node, name, value)) + free(value); +} + + +/* + * 'mxml_set_attr()' - Set or add an attribute name/value pair. + */ + +static int /* O - 0 on success, -1 on failure */ +mxml_set_attr(mxml_node_t *node, /* I - Element node */ + const char *name, /* I - Attribute name */ + char *value) /* I - Attribute value */ +{ + int i; /* Looping var */ + mxml_attr_t *attr; /* New attribute */ + + + /* + * Look for the attribute... + */ + + for (i = node->value.element.num_attrs, attr = node->value.element.attrs; + i > 0; + i --, attr ++) + if (!strcmp(attr->name, name)) + { + /* + * Free the old value as needed... + */ + + if (attr->value) + free(attr->value); + + attr->value = value; + + return (0); + } + + /* + * Add a new attribute... + */ + + if (node->value.element.num_attrs == 0) + attr = malloc(sizeof(mxml_attr_t)); + else + attr = realloc(node->value.element.attrs, + (node->value.element.num_attrs + 1) * sizeof(mxml_attr_t)); + + if (!attr) + { + mxml_error("Unable to allocate memory for attribute '%s' in element %s!", + name, node->value.element.name); + return (-1); + } + + node->value.element.attrs = attr; + attr += node->value.element.num_attrs; + + if ((attr->name = strdup(name)) == NULL) + { + mxml_error("Unable to allocate memory for attribute '%s' in element %s!", + name, node->value.element.name); + return (-1); + } + + attr->value = value; + + node->value.element.num_attrs ++; + + return (0); +} + + +/* + * End of "$Id: mxml-attr.c 308 2007-09-15 20:04:56Z mike $". + */ diff --git a/plugins/zynaddsubfx/mxml/mxml-config.h b/plugins/zynaddsubfx/mxml/mxml-config.h new file mode 100644 index 000000000..a0577b083 --- /dev/null +++ b/plugins/zynaddsubfx/mxml/mxml-config.h @@ -0,0 +1,91 @@ +/* config.h. Generated from config.h.in by configure. */ +/* + * "$Id: config.h.in 310 2007-09-22 21:00:56Z mike $" + * + * Configuration file for Mini-XML, a small XML-like file parsing library. + * + * Copyright 2003-2007 by Michael Sweet. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2, 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. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include +#include + + +/* + * Version number... + */ + +#define MXML_VERSION "Mini-XML v2.5" + + +/* + * Inline function support... + */ + +#define inline + + +/* + * Do we have the snprintf() and vsnprintf() functions? + */ + +#define HAVE_SNPRINTF 1 +#define HAVE_VSNPRINTF 1 + + +/* + * Do we have the strXXX() functions? + */ + +#define HAVE_STRDUP 1 + + +/* + * Do we have threading support? + */ + +#undef HAVE_PTHREAD_H + + +/* + * Define prototypes for string functions as needed... + */ + +# ifndef HAVE_STRDUP +extern char *_mxml_strdup(const char *); +# define strdup _mxml_strdup +# endif /* !HAVE_STRDUP */ + +extern char *_mxml_strdupf(const char *, ...); +extern char *_mxml_vstrdupf(const char *, va_list); + +# ifndef HAVE_SNPRINTF +extern int _mxml_snprintf(char *, size_t, const char *, ...); +# define snprintf _mxml_snprintf +# endif /* !HAVE_SNPRINTF */ + +# ifndef HAVE_VSNPRINTF +extern int _mxml_vsnprintf(char *, size_t, const char *, va_list); +# define vsnprintf _mxml_vsnprintf +# endif /* !HAVE_VSNPRINTF */ + +/* + * End of "$Id: config.h.in 310 2007-09-22 21:00:56Z mike $". + */ diff --git a/plugins/zynaddsubfx/mxml/mxml-entity.c b/plugins/zynaddsubfx/mxml/mxml-entity.c new file mode 100644 index 000000000..89f154234 --- /dev/null +++ b/plugins/zynaddsubfx/mxml/mxml-entity.c @@ -0,0 +1,462 @@ +/* + * "$Id: mxml-entity.c 309 2007-09-21 04:46:02Z mike $" + * + * Character entity support code for Mini-XML, a small XML-like + * file parsing library. + * + * Copyright 2003-2007 by Michael Sweet. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2, 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. + * + * Contents: + * + * mxmlEntityAddCallback() - Add a callback to convert entities to + * Unicode. + * mxmlEntityGetName() - Get the name that corresponds to the + * character value. + * mxmlEntityGetValue() - Get the character corresponding to a named + * entity. + * mxmlEntityRemoveCallback() - Remove a callback. + * _mxml_entity_cb() - Lookup standard (X)HTML entities. + */ + +/* + * Include necessary headers... + */ + +#include "mxml-private.h" + + +/* + * 'mxmlEntityAddCallback()' - Add a callback to convert entities to Unicode. + */ + +int /* O - 0 on success, -1 on failure */ +mxmlEntityAddCallback( + int (*cb)(const char *name)) /* I - Callback function to add */ +{ + _mxml_global_t *global = _mxml_global(); + /* Global data */ + + + if (global->num_entity_cbs < (int)(sizeof(global->entity_cbs) / sizeof(global->entity_cbs[0]))) + { + global->entity_cbs[global->num_entity_cbs] = cb; + global->num_entity_cbs ++; + + return (0); + } + else + { + mxml_error("Unable to add entity callback!"); + + return (-1); + } +} + + +/* + * 'mxmlEntityGetName()' - Get the name that corresponds to the character value. + * + * If val does not need to be represented by a named entity, NULL is returned. + */ + +const char * /* O - Entity name or NULL */ +mxmlEntityGetName(int val) /* I - Character value */ +{ + switch (val) + { + case '&' : + return ("amp"); + + case '<' : + return ("lt"); + + case '>' : + return ("gt"); + + case '\"' : + return ("quot"); + + default : + return (NULL); + } +} + + +/* + * 'mxmlEntityGetValue()' - Get the character corresponding to a named entity. + * + * The entity name can also be a numeric constant. -1 is returned if the + * name is not known. + */ + +int /* O - Character value or -1 on error */ +mxmlEntityGetValue(const char *name) /* I - Entity name */ +{ + int i; /* Looping var */ + int ch; /* Character value */ + _mxml_global_t *global = _mxml_global(); + /* Global data */ + + + for (i = 0; i < global->num_entity_cbs; i ++) + if ((ch = (global->entity_cbs[i])(name)) >= 0) + return (ch); + + return (-1); +} + + +/* + * 'mxmlEntityRemoveCallback()' - Remove a callback. + */ + +void +mxmlEntityRemoveCallback(int (*cb)(const char *name)) + /* I - Callback function to remove */ +{ + int i; /* Looping var */ + _mxml_global_t *global = _mxml_global(); + /* Global data */ + + + for (i = 0; i < global->num_entity_cbs; i ++) + if (cb == global->entity_cbs[i]) + { + /* + * Remove the callback... + */ + + global->num_entity_cbs --; + + if (i < global->num_entity_cbs) + memmove(global->entity_cbs + i, global->entity_cbs + i + 1, + (global->num_entity_cbs - i) * sizeof(global->entity_cbs[0])); + + return; + } +} + + +/* + * '_mxml_entity_cb()' - Lookup standard (X)HTML entities. + */ + +int /* O - Unicode value or -1 */ +_mxml_entity_cb(const char *name) /* I - Entity name */ +{ + int diff, /* Difference between names */ + current, /* Current entity in search */ + first, /* First entity in search */ + last; /* Last entity in search */ + static const struct + { + const char *name; /* Entity name */ + int val; /* Character value */ + } entities[] = + { + { "AElig", 198 }, + { "Aacute", 193 }, + { "Acirc", 194 }, + { "Agrave", 192 }, + { "Alpha", 913 }, + { "Aring", 197 }, + { "Atilde", 195 }, + { "Auml", 196 }, + { "Beta", 914 }, + { "Ccedil", 199 }, + { "Chi", 935 }, + { "Dagger", 8225 }, + { "Delta", 916 }, + { "Dstrok", 208 }, + { "ETH", 208 }, + { "Eacute", 201 }, + { "Ecirc", 202 }, + { "Egrave", 200 }, + { "Epsilon", 917 }, + { "Eta", 919 }, + { "Euml", 203 }, + { "Gamma", 915 }, + { "Iacute", 205 }, + { "Icirc", 206 }, + { "Igrave", 204 }, + { "Iota", 921 }, + { "Iuml", 207 }, + { "Kappa", 922 }, + { "Lambda", 923 }, + { "Mu", 924 }, + { "Ntilde", 209 }, + { "Nu", 925 }, + { "OElig", 338 }, + { "Oacute", 211 }, + { "Ocirc", 212 }, + { "Ograve", 210 }, + { "Omega", 937 }, + { "Omicron", 927 }, + { "Oslash", 216 }, + { "Otilde", 213 }, + { "Ouml", 214 }, + { "Phi", 934 }, + { "Pi", 928 }, + { "Prime", 8243 }, + { "Psi", 936 }, + { "Rho", 929 }, + { "Scaron", 352 }, + { "Sigma", 931 }, + { "THORN", 222 }, + { "Tau", 932 }, + { "Theta", 920 }, + { "Uacute", 218 }, + { "Ucirc", 219 }, + { "Ugrave", 217 }, + { "Upsilon", 933 }, + { "Uuml", 220 }, + { "Xi", 926 }, + { "Yacute", 221 }, + { "Yuml", 376 }, + { "Zeta", 918 }, + { "aacute", 225 }, + { "acirc", 226 }, + { "acute", 180 }, + { "aelig", 230 }, + { "agrave", 224 }, + { "alefsym", 8501 }, + { "alpha", 945 }, + { "amp", '&' }, + { "and", 8743 }, + { "ang", 8736 }, + { "apos", '\'' }, + { "aring", 229 }, + { "asymp", 8776 }, + { "atilde", 227 }, + { "auml", 228 }, + { "bdquo", 8222 }, + { "beta", 946 }, + { "brkbar", 166 }, + { "brvbar", 166 }, + { "bull", 8226 }, + { "cap", 8745 }, + { "ccedil", 231 }, + { "cedil", 184 }, + { "cent", 162 }, + { "chi", 967 }, + { "circ", 710 }, + { "clubs", 9827 }, + { "cong", 8773 }, + { "copy", 169 }, + { "crarr", 8629 }, + { "cup", 8746 }, + { "curren", 164 }, + { "dArr", 8659 }, + { "dagger", 8224 }, + { "darr", 8595 }, + { "deg", 176 }, + { "delta", 948 }, + { "diams", 9830 }, + { "die", 168 }, + { "divide", 247 }, + { "eacute", 233 }, + { "ecirc", 234 }, + { "egrave", 232 }, + { "empty", 8709 }, + { "emsp", 8195 }, + { "ensp", 8194 }, + { "epsilon", 949 }, + { "equiv", 8801 }, + { "eta", 951 }, + { "eth", 240 }, + { "euml", 235 }, + { "euro", 8364 }, + { "exist", 8707 }, + { "fnof", 402 }, + { "forall", 8704 }, + { "frac12", 189 }, + { "frac14", 188 }, + { "frac34", 190 }, + { "frasl", 8260 }, + { "gamma", 947 }, + { "ge", 8805 }, + { "gt", '>' }, + { "hArr", 8660 }, + { "harr", 8596 }, + { "hearts", 9829 }, + { "hellip", 8230 }, + { "hibar", 175 }, + { "iacute", 237 }, + { "icirc", 238 }, + { "iexcl", 161 }, + { "igrave", 236 }, + { "image", 8465 }, + { "infin", 8734 }, + { "int", 8747 }, + { "iota", 953 }, + { "iquest", 191 }, + { "isin", 8712 }, + { "iuml", 239 }, + { "kappa", 954 }, + { "lArr", 8656 }, + { "lambda", 955 }, + { "lang", 9001 }, + { "laquo", 171 }, + { "larr", 8592 }, + { "lceil", 8968 }, + { "ldquo", 8220 }, + { "le", 8804 }, + { "lfloor", 8970 }, + { "lowast", 8727 }, + { "loz", 9674 }, + { "lrm", 8206 }, + { "lsaquo", 8249 }, + { "lsquo", 8216 }, + { "lt", '<' }, + { "macr", 175 }, + { "mdash", 8212 }, + { "micro", 181 }, + { "middot", 183 }, + { "minus", 8722 }, + { "mu", 956 }, + { "nabla", 8711 }, + { "nbsp", 160 }, + { "ndash", 8211 }, + { "ne", 8800 }, + { "ni", 8715 }, + { "not", 172 }, + { "notin", 8713 }, + { "nsub", 8836 }, + { "ntilde", 241 }, + { "nu", 957 }, + { "oacute", 243 }, + { "ocirc", 244 }, + { "oelig", 339 }, + { "ograve", 242 }, + { "oline", 8254 }, + { "omega", 969 }, + { "omicron", 959 }, + { "oplus", 8853 }, + { "or", 8744 }, + { "ordf", 170 }, + { "ordm", 186 }, + { "oslash", 248 }, + { "otilde", 245 }, + { "otimes", 8855 }, + { "ouml", 246 }, + { "para", 182 }, + { "part", 8706 }, + { "permil", 8240 }, + { "perp", 8869 }, + { "phi", 966 }, + { "pi", 960 }, + { "piv", 982 }, + { "plusmn", 177 }, + { "pound", 163 }, + { "prime", 8242 }, + { "prod", 8719 }, + { "prop", 8733 }, + { "psi", 968 }, + { "quot", '\"' }, + { "rArr", 8658 }, + { "radic", 8730 }, + { "rang", 9002 }, + { "raquo", 187 }, + { "rarr", 8594 }, + { "rceil", 8969 }, + { "rdquo", 8221 }, + { "real", 8476 }, + { "reg", 174 }, + { "rfloor", 8971 }, + { "rho", 961 }, + { "rlm", 8207 }, + { "rsaquo", 8250 }, + { "rsquo", 8217 }, + { "sbquo", 8218 }, + { "scaron", 353 }, + { "sdot", 8901 }, + { "sect", 167 }, + { "shy", 173 }, + { "sigma", 963 }, + { "sigmaf", 962 }, + { "sim", 8764 }, + { "spades", 9824 }, + { "sub", 8834 }, + { "sube", 8838 }, + { "sum", 8721 }, + { "sup", 8835 }, + { "sup1", 185 }, + { "sup2", 178 }, + { "sup3", 179 }, + { "supe", 8839 }, + { "szlig", 223 }, + { "tau", 964 }, + { "there4", 8756 }, + { "theta", 952 }, + { "thetasym", 977 }, + { "thinsp", 8201 }, + { "thorn", 254 }, + { "tilde", 732 }, + { "times", 215 }, + { "trade", 8482 }, + { "uArr", 8657 }, + { "uacute", 250 }, + { "uarr", 8593 }, + { "ucirc", 251 }, + { "ugrave", 249 }, + { "uml", 168 }, + { "upsih", 978 }, + { "upsilon", 965 }, + { "uuml", 252 }, + { "weierp", 8472 }, + { "xi", 958 }, + { "yacute", 253 }, + { "yen", 165 }, + { "yuml", 255 }, + { "zeta", 950 }, + { "zwj", 8205 }, + { "zwnj", 8204 } + }; + + + /* + * Do a binary search for the named entity... + */ + + first = 0; + last = (int)(sizeof(entities) / sizeof(entities[0]) - 1); + + while ((last - first) > 1) + { + current = (first + last) / 2; + + if ((diff = strcmp(name, entities[current].name)) == 0) + return (entities[current].val); + else if (diff < 0) + last = current; + else + first = current; + } + + /* + * If we get here, there is a small chance that there is still + * a match; check first and last... + */ + + if (!strcmp(name, entities[first].name)) + return (entities[first].val); + else if (!strcmp(name, entities[last].name)) + return (entities[last].val); + else + return (-1); +} + + +/* + * End of "$Id: mxml-entity.c 309 2007-09-21 04:46:02Z mike $". + */ diff --git a/plugins/zynaddsubfx/mxml/mxml-file.c b/plugins/zynaddsubfx/mxml/mxml-file.c new file mode 100644 index 000000000..dc51d766d --- /dev/null +++ b/plugins/zynaddsubfx/mxml/mxml-file.c @@ -0,0 +1,3124 @@ +/* + * "$Id: mxml-file.c 329 2008-01-13 00:42:35Z mike $" + * + * File loading code for Mini-XML, a small XML-like file parsing library. + * + * Copyright 2003-2008 by Michael Sweet. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2, 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. + * + * Contents: + * + * mxmlLoadFd() - Load a file descriptor into an XML node tree. + * mxmlLoadFile() - Load a file into an XML node tree. + * mxmlLoadString() - Load a string into an XML node tree. + * mxmlSaveAllocString() - Save an XML node tree to an allocated string. + * mxmlSaveFd() - Save an XML tree to a file descriptor. + * mxmlSaveFile() - Save an XML tree to a file. + * mxmlSaveString() - Save an XML node tree to a string. + * mxmlSAXLoadFd() - Load a file descriptor into an XML node tree + * using a SAX callback. + * mxmlSAXLoadFile() - Load a file into an XML node tree + * using a SAX callback. + * mxmlSAXLoadString() - Load a string into an XML node tree + * using a SAX callback. + * mxmlSetCustomHandlers() - Set the handling functions for custom data. + * mxmlSetErrorCallback() - Set the error message callback. + * mxmlSetWrapMargin() - Set the the wrap margin when saving XML data. + * mxml_add_char() - Add a character to a buffer, expanding as needed. + * mxml_fd_getc() - Read a character from a file descriptor. + * mxml_fd_putc() - Write a character to a file descriptor. + * mxml_fd_read() - Read a buffer of data from a file descriptor. + * mxml_fd_write() - Write a buffer of data to a file descriptor. + * mxml_file_getc() - Get a character from a file. + * mxml_file_putc() - Write a character to a file. + * mxml_get_entity() - Get the character corresponding to an entity... + * mxml_load_data() - Load data into an XML node tree. + * mxml_parse_element() - Parse an element for any attributes... + * mxml_string_getc() - Get a character from a string. + * mxml_string_putc() - Write a character to a string. + * mxml_write_name() - Write a name string. + * mxml_write_node() - Save an XML node to a file. + * mxml_write_string() - Write a string, escaping & and < as needed. + * mxml_write_ws() - Do whitespace callback... + */ + +/* + * Include necessary headers... + */ + +#include "mxml-private.h" +#ifdef WIN32 +# include +#else +# include +#endif /* WIN32 */ + + +/* + * Character encoding... + */ + +#define ENCODE_UTF8 0 /* UTF-8 */ +#define ENCODE_UTF16BE 1 /* UTF-16 Big-Endian */ +#define ENCODE_UTF16LE 2 /* UTF-16 Little-Endian */ + + +/* + * Macro to test for a bad XML character... + */ + +#define mxml_bad_char(ch) ((ch) < ' ' && (ch) != '\n' && (ch) != '\r' && (ch) != '\t') + + +/* + * Types and structures... + */ + +typedef int (*_mxml_getc_cb_t)(void *, int *); +typedef int (*_mxml_putc_cb_t)(int, void *); + +typedef struct _mxml_fdbuf_s /**** File descriptor buffer ****/ +{ + int fd; /* File descriptor */ + unsigned char *current, /* Current position in buffer */ + *end, /* End of buffer */ + buffer[8192]; /* Character buffer */ +} _mxml_fdbuf_t; + + +/* + * Local functions... + */ + +static int mxml_add_char(int ch, char **ptr, char **buffer, + int *bufsize); +static int mxml_fd_getc(void *p, int *encoding); +static int mxml_fd_putc(int ch, void *p); +static int mxml_fd_read(_mxml_fdbuf_t *buf); +static int mxml_fd_write(_mxml_fdbuf_t *buf); +static int mxml_file_getc(void *p, int *encoding); +static int mxml_file_putc(int ch, void *p); +static int mxml_get_entity(mxml_node_t *parent, void *p, + int *encoding, + _mxml_getc_cb_t getc_cb); +static inline int mxml_isspace(int ch) + { + return (ch == ' ' || ch == '\t' || ch == '\r' || + ch == '\n'); + } +static mxml_node_t *mxml_load_data(mxml_node_t *top, void *p, + mxml_load_cb_t cb, + _mxml_getc_cb_t getc_cb, + mxml_sax_cb_t sax_cb, void *sax_data); +static int mxml_parse_element(mxml_node_t *node, void *p, + int *encoding, + _mxml_getc_cb_t getc_cb); +static int mxml_string_getc(void *p, int *encoding); +static int mxml_string_putc(int ch, void *p); +static int mxml_write_name(const char *s, void *p, + _mxml_putc_cb_t putc_cb); +static int mxml_write_node(mxml_node_t *node, void *p, + mxml_save_cb_t cb, int col, + _mxml_putc_cb_t putc_cb, + _mxml_global_t *global); +static int mxml_write_string(const char *s, void *p, + _mxml_putc_cb_t putc_cb); +static int mxml_write_ws(mxml_node_t *node, void *p, + mxml_save_cb_t cb, int ws, + int col, _mxml_putc_cb_t putc_cb); + + +/* + * 'mxmlLoadFd()' - Load a file descriptor into an XML node tree. + * + * The nodes in the specified file are added to the specified top node. + * If no top node is provided, the XML file MUST be well-formed with a + * single parent node like for the entire file. The callback + * function returns the value type that should be used for child nodes. + * If MXML_NO_CALLBACK is specified then all child nodes will be either + * MXML_ELEMENT or MXML_TEXT nodes. + * + * The constants MXML_INTEGER_CALLBACK, MXML_OPAQUE_CALLBACK, + * MXML_REAL_CALLBACK, and MXML_TEXT_CALLBACK are defined for loading + * child nodes of the specified type. + */ + +mxml_node_t * /* O - First node or NULL if the file could not be read. */ +mxmlLoadFd(mxml_node_t *top, /* I - Top node */ + int fd, /* I - File descriptor to read from */ + mxml_load_cb_t cb) /* I - Callback function or MXML_NO_CALLBACK */ +{ + _mxml_fdbuf_t buf; /* File descriptor buffer */ + + + /* + * Initialize the file descriptor buffer... + */ + + buf.fd = fd; + buf.current = buf.buffer; + buf.end = buf.buffer; + + /* + * Read the XML data... + */ + + return (mxml_load_data(top, &buf, cb, mxml_fd_getc, MXML_NO_CALLBACK, NULL)); +} + + +/* + * 'mxmlLoadFile()' - Load a file into an XML node tree. + * + * The nodes in the specified file are added to the specified top node. + * If no top node is provided, the XML file MUST be well-formed with a + * single parent node like for the entire file. The callback + * function returns the value type that should be used for child nodes. + * If MXML_NO_CALLBACK is specified then all child nodes will be either + * MXML_ELEMENT or MXML_TEXT nodes. + * + * The constants MXML_INTEGER_CALLBACK, MXML_OPAQUE_CALLBACK, + * MXML_REAL_CALLBACK, and MXML_TEXT_CALLBACK are defined for loading + * child nodes of the specified type. + */ + +mxml_node_t * /* O - First node or NULL if the file could not be read. */ +mxmlLoadFile(mxml_node_t *top, /* I - Top node */ + FILE *fp, /* I - File to read from */ + mxml_load_cb_t cb) /* I - Callback function or MXML_NO_CALLBACK */ +{ + /* + * Read the XML data... + */ + + return (mxml_load_data(top, fp, cb, mxml_file_getc, MXML_NO_CALLBACK, NULL)); +} + + +/* + * 'mxmlLoadString()' - Load a string into an XML node tree. + * + * The nodes in the specified string are added to the specified top node. + * If no top node is provided, the XML string MUST be well-formed with a + * single parent node like for the entire string. The callback + * function returns the value type that should be used for child nodes. + * If MXML_NO_CALLBACK is specified then all child nodes will be either + * MXML_ELEMENT or MXML_TEXT nodes. + * + * The constants MXML_INTEGER_CALLBACK, MXML_OPAQUE_CALLBACK, + * MXML_REAL_CALLBACK, and MXML_TEXT_CALLBACK are defined for loading + * child nodes of the specified type. + */ + +mxml_node_t * /* O - First node or NULL if the string has errors. */ +mxmlLoadString(mxml_node_t *top, /* I - Top node */ + const char *s, /* I - String to load */ + mxml_load_cb_t cb) /* I - Callback function or MXML_NO_CALLBACK */ +{ + /* + * Read the XML data... + */ + + return (mxml_load_data(top, (void *)&s, cb, mxml_string_getc, MXML_NO_CALLBACK, + NULL)); +} + + +/* + * 'mxmlSaveAllocString()' - Save an XML node tree to an allocated string. + * + * This function returns a pointer to a string containing the textual + * representation of the XML node tree. The string should be freed + * using the free() function when you are done with it. NULL is returned + * if the node would produce an empty string or if the string cannot be + * allocated. + * + * The callback argument specifies a function that returns a whitespace + * string or NULL before and after each element. If MXML_NO_CALLBACK + * is specified, whitespace will only be added before MXML_TEXT nodes + * with leading whitespace and before attribute names inside opening + * element tags. + */ + +char * /* O - Allocated string or NULL */ +mxmlSaveAllocString( + mxml_node_t *node, /* I - Node to write */ + mxml_save_cb_t cb) /* I - Whitespace callback or MXML_NO_CALLBACK */ +{ + int bytes; /* Required bytes */ + char buffer[8192]; /* Temporary buffer */ + char *s; /* Allocated string */ + + + /* + * Write the node to the temporary buffer... + */ + + bytes = mxmlSaveString(node, buffer, sizeof(buffer), cb); + + if (bytes <= 0) + return (NULL); + + if (bytes < (int)(sizeof(buffer) - 1)) + { + /* + * Node fit inside the buffer, so just duplicate that string and + * return... + */ + + return (strdup(buffer)); + } + + /* + * Allocate a buffer of the required size and save the node to the + * new buffer... + */ + + if ((s = malloc(bytes + 1)) == NULL) + return (NULL); + + mxmlSaveString(node, s, bytes + 1, cb); + + /* + * Return the allocated string... + */ + + return (s); +} + + +/* + * 'mxmlSaveFd()' - Save an XML tree to a file descriptor. + * + * The callback argument specifies a function that returns a whitespace + * string or NULL before and after each element. If MXML_NO_CALLBACK + * is specified, whitespace will only be added before MXML_TEXT nodes + * with leading whitespace and before attribute names inside opening + * element tags. + */ + +int /* O - 0 on success, -1 on error. */ +mxmlSaveFd(mxml_node_t *node, /* I - Node to write */ + int fd, /* I - File descriptor to write to */ + mxml_save_cb_t cb) /* I - Whitespace callback or MXML_NO_CALLBACK */ +{ + int col; /* Final column */ + _mxml_fdbuf_t buf; /* File descriptor buffer */ + _mxml_global_t *global = _mxml_global(); + /* Global data */ + + + /* + * Initialize the file descriptor buffer... + */ + + buf.fd = fd; + buf.current = buf.buffer; + buf.end = buf.buffer + sizeof(buf.buffer) - 4; + + /* + * Write the node... + */ + + if ((col = mxml_write_node(node, &buf, cb, 0, mxml_fd_putc, global)) < 0) + return (-1); + + if (col > 0) + if (mxml_fd_putc('\n', &buf) < 0) + return (-1); + + /* + * Flush and return... + */ + + return (mxml_fd_write(&buf)); +} + + +/* + * 'mxmlSaveFile()' - Save an XML tree to a file. + * + * The callback argument specifies a function that returns a whitespace + * string or NULL before and after each element. If MXML_NO_CALLBACK + * is specified, whitespace will only be added before MXML_TEXT nodes + * with leading whitespace and before attribute names inside opening + * element tags. + */ + +int /* O - 0 on success, -1 on error. */ +mxmlSaveFile(mxml_node_t *node, /* I - Node to write */ + FILE *fp, /* I - File to write to */ + mxml_save_cb_t cb) /* I - Whitespace callback or MXML_NO_CALLBACK */ +{ + int col; /* Final column */ + _mxml_global_t *global = _mxml_global(); + /* Global data */ + + + /* + * Write the node... + */ + + if ((col = mxml_write_node(node, fp, cb, 0, mxml_file_putc, global)) < 0) + return (-1); + + if (col > 0) + if (putc('\n', fp) < 0) + return (-1); + + /* + * Return 0 (success)... + */ + + return (0); +} + + +/* + * 'mxmlSaveString()' - Save an XML node tree to a string. + * + * This function returns the total number of bytes that would be + * required for the string but only copies (bufsize - 1) characters + * into the specified buffer. + * + * The callback argument specifies a function that returns a whitespace + * string or NULL before and after each element. If MXML_NO_CALLBACK + * is specified, whitespace will only be added before MXML_TEXT nodes + * with leading whitespace and before attribute names inside opening + * element tags. + */ + +int /* O - Size of string */ +mxmlSaveString(mxml_node_t *node, /* I - Node to write */ + char *buffer, /* I - String buffer */ + int bufsize, /* I - Size of string buffer */ + mxml_save_cb_t cb) /* I - Whitespace callback or MXML_NO_CALLBACK */ +{ + int col; /* Final column */ + char *ptr[2]; /* Pointers for putc_cb */ + _mxml_global_t *global = _mxml_global(); + /* Global data */ + + + /* + * Write the node... + */ + + ptr[0] = buffer; + ptr[1] = buffer + bufsize; + + if ((col = mxml_write_node(node, ptr, cb, 0, mxml_string_putc, global)) < 0) + return (-1); + + if (col > 0) + mxml_string_putc('\n', ptr); + + /* + * Nul-terminate the buffer... + */ + + if (ptr[0] >= ptr[1]) + buffer[bufsize - 1] = '\0'; + else + ptr[0][0] = '\0'; + + /* + * Return the number of characters... + */ + + return (ptr[0] - buffer); +} + + +/* + * 'mxmlSAXLoadFd()' - Load a file descriptor into an XML node tree + * using a SAX callback. + * + * The nodes in the specified file are added to the specified top node. + * If no top node is provided, the XML file MUST be well-formed with a + * single parent node like for the entire file. The callback + * function returns the value type that should be used for child nodes. + * If MXML_NO_CALLBACK is specified then all child nodes will be either + * MXML_ELEMENT or MXML_TEXT nodes. + * + * The constants MXML_INTEGER_CALLBACK, MXML_OPAQUE_CALLBACK, + * MXML_REAL_CALLBACK, and MXML_TEXT_CALLBACK are defined for loading + * child nodes of the specified type. + * + * The SAX callback must call mxmlRetain() for any nodes that need to + * be kept for later use. Otherwise, nodes are deleted when the parent + * node is closed or after each data, comment, CDATA, or directive node. + * + * @since Mini-XML 2.3@ + */ + +mxml_node_t * /* O - First node or NULL if the file could not be read. */ +mxmlSAXLoadFd(mxml_node_t *top, /* I - Top node */ + int fd, /* I - File descriptor to read from */ + mxml_load_cb_t cb, /* I - Callback function or MXML_NO_CALLBACK */ + mxml_sax_cb_t sax_cb, /* I - SAX callback or MXML_NO_CALLBACK */ + void *sax_data) /* I - SAX user data */ +{ + _mxml_fdbuf_t buf; /* File descriptor buffer */ + + + /* + * Initialize the file descriptor buffer... + */ + + buf.fd = fd; + buf.current = buf.buffer; + buf.end = buf.buffer; + + /* + * Read the XML data... + */ + + return (mxml_load_data(top, &buf, cb, mxml_fd_getc, sax_cb, sax_data)); +} + + +/* + * 'mxmlSAXLoadFile()' - Load a file into an XML node tree + * using a SAX callback. + * + * The nodes in the specified file are added to the specified top node. + * If no top node is provided, the XML file MUST be well-formed with a + * single parent node like for the entire file. The callback + * function returns the value type that should be used for child nodes. + * If MXML_NO_CALLBACK is specified then all child nodes will be either + * MXML_ELEMENT or MXML_TEXT nodes. + * + * The constants MXML_INTEGER_CALLBACK, MXML_OPAQUE_CALLBACK, + * MXML_REAL_CALLBACK, and MXML_TEXT_CALLBACK are defined for loading + * child nodes of the specified type. + * + * The SAX callback must call mxmlRetain() for any nodes that need to + * be kept for later use. Otherwise, nodes are deleted when the parent + * node is closed or after each data, comment, CDATA, or directive node. + * + * @since Mini-XML 2.3@ + */ + +mxml_node_t * /* O - First node or NULL if the file could not be read. */ +mxmlSAXLoadFile( + mxml_node_t *top, /* I - Top node */ + FILE *fp, /* I - File to read from */ + mxml_load_cb_t cb, /* I - Callback function or MXML_NO_CALLBACK */ + mxml_sax_cb_t sax_cb, /* I - SAX callback or MXML_NO_CALLBACK */ + void *sax_data) /* I - SAX user data */ +{ + /* + * Read the XML data... + */ + + return (mxml_load_data(top, fp, cb, mxml_file_getc, sax_cb, sax_data)); +} + + +/* + * 'mxmlSAXLoadString()' - Load a string into an XML node tree + * using a SAX callback. + * + * The nodes in the specified string are added to the specified top node. + * If no top node is provided, the XML string MUST be well-formed with a + * single parent node like for the entire string. The callback + * function returns the value type that should be used for child nodes. + * If MXML_NO_CALLBACK is specified then all child nodes will be either + * MXML_ELEMENT or MXML_TEXT nodes. + * + * The constants MXML_INTEGER_CALLBACK, MXML_OPAQUE_CALLBACK, + * MXML_REAL_CALLBACK, and MXML_TEXT_CALLBACK are defined for loading + * child nodes of the specified type. + * + * The SAX callback must call mxmlRetain() for any nodes that need to + * be kept for later use. Otherwise, nodes are deleted when the parent + * node is closed or after each data, comment, CDATA, or directive node. + * + * @since Mini-XML 2.3@ + */ + +mxml_node_t * /* O - First node or NULL if the string has errors. */ +mxmlSAXLoadString( + mxml_node_t *top, /* I - Top node */ + const char *s, /* I - String to load */ + mxml_load_cb_t cb, /* I - Callback function or MXML_NO_CALLBACK */ + mxml_sax_cb_t sax_cb, /* I - SAX callback or MXML_NO_CALLBACK */ + void *sax_data) /* I - SAX user data */ +{ + /* + * Read the XML data... + */ + + return (mxml_load_data(top, (void *)&s, cb, mxml_string_getc, sax_cb, sax_data)); +} + + +/* + * 'mxmlSetCustomHandlers()' - Set the handling functions for custom data. + * + * The load function accepts a node pointer and a data string and must + * return 0 on success and non-zero on error. + * + * The save function accepts a node pointer and must return a malloc'd + * string on success and NULL on error. + * + */ + +void +mxmlSetCustomHandlers( + mxml_custom_load_cb_t load, /* I - Load function */ + mxml_custom_save_cb_t save) /* I - Save function */ +{ + _mxml_global_t *global = _mxml_global(); + /* Global data */ + + + global->custom_load_cb = load; + global->custom_save_cb = save; +} + + +/* + * 'mxmlSetErrorCallback()' - Set the error message callback. + */ + +void +mxmlSetErrorCallback(mxml_error_cb_t cb)/* I - Error callback function */ +{ + _mxml_global_t *global = _mxml_global(); + /* Global data */ + + + global->error_cb = cb; +} + + +/* + * 'mxmlSetWrapMargin()' - Set the the wrap margin when saving XML data. + * + * Wrapping is disabled when "column" is <= 0. + * + * @since Mini-XML 2.3@ + */ + +void +mxmlSetWrapMargin(int column) /* I - Column for wrapping */ +{ + _mxml_global_t *global = _mxml_global(); + /* Global data */ + + + if (column <= 0) + global->wrap = 2147483647; + else + global->wrap = column; +} + + +/* + * 'mxml_add_char()' - Add a character to a buffer, expanding as needed. + */ + +static int /* O - 0 on success, -1 on error */ +mxml_add_char(int ch, /* I - Character to add */ + char **bufptr, /* IO - Current position in buffer */ + char **buffer, /* IO - Current buffer */ + int *bufsize) /* IO - Current buffer size */ +{ + char *newbuffer; /* New buffer value */ + + + if (*bufptr >= (*buffer + *bufsize - 4)) + { + /* + * Increase the size of the buffer... + */ + + if (*bufsize < 1024) + (*bufsize) *= 2; + else + (*bufsize) += 1024; + + if ((newbuffer = realloc(*buffer, *bufsize)) == NULL) + { + free(*buffer); + + mxml_error("Unable to expand string buffer to %d bytes!", *bufsize); + + return (-1); + } + + *bufptr = newbuffer + (*bufptr - *buffer); + *buffer = newbuffer; + } + + if (ch < 0x80) + { + /* + * Single byte ASCII... + */ + + *(*bufptr)++ = ch; + } + else if (ch < 0x800) + { + /* + * Two-byte UTF-8... + */ + + *(*bufptr)++ = 0xc0 | (ch >> 6); + *(*bufptr)++ = 0x80 | (ch & 0x3f); + } + else if (ch < 0x10000) + { + /* + * Three-byte UTF-8... + */ + + *(*bufptr)++ = 0xe0 | (ch >> 12); + *(*bufptr)++ = 0x80 | ((ch >> 6) & 0x3f); + *(*bufptr)++ = 0x80 | (ch & 0x3f); + } + else + { + /* + * Four-byte UTF-8... + */ + + *(*bufptr)++ = 0xf0 | (ch >> 18); + *(*bufptr)++ = 0x80 | ((ch >> 12) & 0x3f); + *(*bufptr)++ = 0x80 | ((ch >> 6) & 0x3f); + *(*bufptr)++ = 0x80 | (ch & 0x3f); + } + + return (0); +} + + +/* + * 'mxml_fd_getc()' - Read a character from a file descriptor. + */ + +static int /* O - Character or EOF */ +mxml_fd_getc(void *p, /* I - File descriptor buffer */ + int *encoding) /* IO - Encoding */ +{ + _mxml_fdbuf_t *buf; /* File descriptor buffer */ + int ch, /* Current character */ + temp; /* Temporary character */ + + + /* + * Grab the next character in the buffer... + */ + + buf = (_mxml_fdbuf_t *)p; + + if (buf->current >= buf->end) + if (mxml_fd_read(buf) < 0) + return (EOF); + + ch = *(buf->current)++; + + switch (*encoding) + { + case ENCODE_UTF8 : + /* + * Got a UTF-8 character; convert UTF-8 to Unicode and return... + */ + + if (!(ch & 0x80)) + { +#if DEBUG > 1 + printf("mxml_fd_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch); +#endif /* DEBUG > 1 */ + + if (mxml_bad_char(ch)) + { + mxml_error("Bad control character 0x%02x not allowed by XML standard!", + ch); + return (EOF); + } + + return (ch); + } + else if (ch == 0xfe) + { + /* + * UTF-16 big-endian BOM? + */ + + if (buf->current >= buf->end) + if (mxml_fd_read(buf) < 0) + return (EOF); + + ch = *(buf->current)++; + + if (ch != 0xff) + return (EOF); + + *encoding = ENCODE_UTF16BE; + + return (mxml_fd_getc(p, encoding)); + } + else if (ch == 0xff) + { + /* + * UTF-16 little-endian BOM? + */ + + if (buf->current >= buf->end) + if (mxml_fd_read(buf) < 0) + return (EOF); + + ch = *(buf->current)++; + + if (ch != 0xfe) + return (EOF); + + *encoding = ENCODE_UTF16LE; + + return (mxml_fd_getc(p, encoding)); + } + else if ((ch & 0xe0) == 0xc0) + { + /* + * Two-byte value... + */ + + if (buf->current >= buf->end) + if (mxml_fd_read(buf) < 0) + return (EOF); + + temp = *(buf->current)++; + + if ((temp & 0xc0) != 0x80) + return (EOF); + + ch = ((ch & 0x1f) << 6) | (temp & 0x3f); + + if (ch < 0x80) + return (EOF); + } + else if ((ch & 0xf0) == 0xe0) + { + /* + * Three-byte value... + */ + + if (buf->current >= buf->end) + if (mxml_fd_read(buf) < 0) + return (EOF); + + temp = *(buf->current)++; + + if ((temp & 0xc0) != 0x80) + return (EOF); + + ch = ((ch & 0x0f) << 6) | (temp & 0x3f); + + if (buf->current >= buf->end) + if (mxml_fd_read(buf) < 0) + return (EOF); + + temp = *(buf->current)++; + + if ((temp & 0xc0) != 0x80) + return (EOF); + + ch = (ch << 6) | (temp & 0x3f); + + if (ch < 0x800) + return (EOF); + } + else if ((ch & 0xf8) == 0xf0) + { + /* + * Four-byte value... + */ + + if (buf->current >= buf->end) + if (mxml_fd_read(buf) < 0) + return (EOF); + + temp = *(buf->current)++; + + if ((temp & 0xc0) != 0x80) + return (EOF); + + ch = ((ch & 0x07) << 6) | (temp & 0x3f); + + if (buf->current >= buf->end) + if (mxml_fd_read(buf) < 0) + return (EOF); + + temp = *(buf->current)++; + + if ((temp & 0xc0) != 0x80) + return (EOF); + + ch = (ch << 6) | (temp & 0x3f); + + if (buf->current >= buf->end) + if (mxml_fd_read(buf) < 0) + return (EOF); + + temp = *(buf->current)++; + + if ((temp & 0xc0) != 0x80) + return (EOF); + + ch = (ch << 6) | (temp & 0x3f); + + if (ch < 0x10000) + return (EOF); + } + else + return (EOF); + break; + + case ENCODE_UTF16BE : + /* + * Read UTF-16 big-endian char... + */ + + if (buf->current >= buf->end) + if (mxml_fd_read(buf) < 0) + return (EOF); + + temp = *(buf->current)++; + + ch = (ch << 8) | temp; + + if (mxml_bad_char(ch)) + { + mxml_error("Bad control character 0x%02x not allowed by XML standard!", + ch); + return (EOF); + } + else if (ch >= 0xd800 && ch <= 0xdbff) + { + /* + * Multi-word UTF-16 char... + */ + + int lch; + + if (buf->current >= buf->end) + if (mxml_fd_read(buf) < 0) + return (EOF); + + lch = *(buf->current)++; + + if (buf->current >= buf->end) + if (mxml_fd_read(buf) < 0) + return (EOF); + + temp = *(buf->current)++; + + lch = (lch << 8) | temp; + + if (lch < 0xdc00 || lch >= 0xdfff) + return (EOF); + + ch = (((ch & 0x3ff) << 10) | (lch & 0x3ff)) + 0x10000; + } + break; + + case ENCODE_UTF16LE : + /* + * Read UTF-16 little-endian char... + */ + + if (buf->current >= buf->end) + if (mxml_fd_read(buf) < 0) + return (EOF); + + temp = *(buf->current)++; + + ch |= (temp << 8); + + if (mxml_bad_char(ch)) + { + mxml_error("Bad control character 0x%02x not allowed by XML standard!", + ch); + return (EOF); + } + else if (ch >= 0xd800 && ch <= 0xdbff) + { + /* + * Multi-word UTF-16 char... + */ + + int lch; + + if (buf->current >= buf->end) + if (mxml_fd_read(buf) < 0) + return (EOF); + + lch = *(buf->current)++; + + if (buf->current >= buf->end) + if (mxml_fd_read(buf) < 0) + return (EOF); + + temp = *(buf->current)++; + + lch |= (temp << 8); + + if (lch < 0xdc00 || lch >= 0xdfff) + return (EOF); + + ch = (((ch & 0x3ff) << 10) | (lch & 0x3ff)) + 0x10000; + } + break; + } + +#if DEBUG > 1 + printf("mxml_fd_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch); +#endif /* DEBUG > 1 */ + + return (ch); +} + + +/* + * 'mxml_fd_putc()' - Write a character to a file descriptor. + */ + +static int /* O - 0 on success, -1 on error */ +mxml_fd_putc(int ch, /* I - Character */ + void *p) /* I - File descriptor buffer */ +{ + _mxml_fdbuf_t *buf; /* File descriptor buffer */ + + + /* + * Flush the write buffer as needed - note above that "end" still leaves + * 4 characters at the end so that we can avoid a lot of extra tests... + */ + + buf = (_mxml_fdbuf_t *)p; + + if (buf->current >= buf->end) + if (mxml_fd_write(buf) < 0) + return (-1); + + if (ch < 0x80) + { + /* + * Write ASCII character directly... + */ + + *(buf->current)++ = ch; + } + else if (ch < 0x800) + { + /* + * Two-byte UTF-8 character... + */ + + *(buf->current)++ = 0xc0 | (ch >> 6); + *(buf->current)++ = 0x80 | (ch & 0x3f); + } + else if (ch < 0x10000) + { + /* + * Three-byte UTF-8 character... + */ + + *(buf->current)++ = 0xe0 | (ch >> 12); + *(buf->current)++ = 0x80 | ((ch >> 6) & 0x3f); + *(buf->current)++ = 0x80 | (ch & 0x3f); + } + else + { + /* + * Four-byte UTF-8 character... + */ + + *(buf->current)++ = 0xf0 | (ch >> 18); + *(buf->current)++ = 0x80 | ((ch >> 12) & 0x3f); + *(buf->current)++ = 0x80 | ((ch >> 6) & 0x3f); + *(buf->current)++ = 0x80 | (ch & 0x3f); + } + + /* + * Return successfully... + */ + + return (0); +} + + +/* + * 'mxml_fd_read()' - Read a buffer of data from a file descriptor. + */ + +static int /* O - 0 on success, -1 on error */ +mxml_fd_read(_mxml_fdbuf_t *buf) /* I - File descriptor buffer */ +{ + int bytes; /* Bytes read... */ + + + /* + * Range check input... + */ + + if (!buf) + return (-1); + + /* + * Read from the file descriptor... + */ + + while ((bytes = read(buf->fd, buf->buffer, sizeof(buf->buffer))) < 0) +#ifdef EINTR + if (errno != EAGAIN && errno != EINTR) +#else + if (errno != EAGAIN) +#endif /* EINTR */ + return (-1); + + if (bytes == 0) + return (-1); + + /* + * Update the pointers and return success... + */ + + buf->current = buf->buffer; + buf->end = buf->buffer + bytes; + + return (0); +} + + +/* + * 'mxml_fd_write()' - Write a buffer of data to a file descriptor. + */ + +static int /* O - 0 on success, -1 on error */ +mxml_fd_write(_mxml_fdbuf_t *buf) /* I - File descriptor buffer */ +{ + int bytes; /* Bytes written */ + unsigned char *ptr; /* Pointer into buffer */ + + + /* + * Range check... + */ + + if (!buf) + return (-1); + + /* + * Return 0 if there is nothing to write... + */ + + if (buf->current == buf->buffer) + return (0); + + /* + * Loop until we have written everything... + */ + + for (ptr = buf->buffer; ptr < buf->current; ptr += bytes) + if ((bytes = write(buf->fd, ptr, buf->current - ptr)) < 0) + return (-1); + + /* + * All done, reset pointers and return success... + */ + + buf->current = buf->buffer; + + return (0); +} + + +/* + * 'mxml_file_getc()' - Get a character from a file. + */ + +static int /* O - Character or EOF */ +mxml_file_getc(void *p, /* I - Pointer to file */ + int *encoding) /* IO - Encoding */ +{ + int ch, /* Character from file */ + temp; /* Temporary character */ + FILE *fp; /* Pointer to file */ + + + /* + * Read a character from the file and see if it is EOF or ASCII... + */ + + fp = (FILE *)p; + ch = getc(fp); + + if (ch == EOF) + return (EOF); + + switch (*encoding) + { + case ENCODE_UTF8 : + /* + * Got a UTF-8 character; convert UTF-8 to Unicode and return... + */ + + if (!(ch & 0x80)) + { + if (mxml_bad_char(ch)) + { + mxml_error("Bad control character 0x%02x not allowed by XML standard!", + ch); + return (EOF); + } + +#if DEBUG > 1 + printf("mxml_file_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch); +#endif /* DEBUG > 1 */ + + return (ch); + } + else if (ch == 0xfe) + { + /* + * UTF-16 big-endian BOM? + */ + + ch = getc(fp); + if (ch != 0xff) + return (EOF); + + *encoding = ENCODE_UTF16BE; + + return (mxml_file_getc(p, encoding)); + } + else if (ch == 0xff) + { + /* + * UTF-16 little-endian BOM? + */ + + ch = getc(fp); + if (ch != 0xfe) + return (EOF); + + *encoding = ENCODE_UTF16LE; + + return (mxml_file_getc(p, encoding)); + } + else if ((ch & 0xe0) == 0xc0) + { + /* + * Two-byte value... + */ + + if ((temp = getc(fp)) == EOF || (temp & 0xc0) != 0x80) + return (EOF); + + ch = ((ch & 0x1f) << 6) | (temp & 0x3f); + + if (ch < 0x80) + return (EOF); + } + else if ((ch & 0xf0) == 0xe0) + { + /* + * Three-byte value... + */ + + if ((temp = getc(fp)) == EOF || (temp & 0xc0) != 0x80) + return (EOF); + + ch = ((ch & 0x0f) << 6) | (temp & 0x3f); + + if ((temp = getc(fp)) == EOF || (temp & 0xc0) != 0x80) + return (EOF); + + ch = (ch << 6) | (temp & 0x3f); + + if (ch < 0x800) + return (EOF); + } + else if ((ch & 0xf8) == 0xf0) + { + /* + * Four-byte value... + */ + + if ((temp = getc(fp)) == EOF || (temp & 0xc0) != 0x80) + return (EOF); + + ch = ((ch & 0x07) << 6) | (temp & 0x3f); + + if ((temp = getc(fp)) == EOF || (temp & 0xc0) != 0x80) + return (EOF); + + ch = (ch << 6) | (temp & 0x3f); + + if ((temp = getc(fp)) == EOF || (temp & 0xc0) != 0x80) + return (EOF); + + ch = (ch << 6) | (temp & 0x3f); + + if (ch < 0x10000) + return (EOF); + } + else + return (EOF); + break; + + case ENCODE_UTF16BE : + /* + * Read UTF-16 big-endian char... + */ + + ch = (ch << 8) | getc(fp); + + if (mxml_bad_char(ch)) + { + mxml_error("Bad control character 0x%02x not allowed by XML standard!", + ch); + return (EOF); + } + else if (ch >= 0xd800 && ch <= 0xdbff) + { + /* + * Multi-word UTF-16 char... + */ + + int lch = (getc(fp) << 8) | getc(fp); + + if (lch < 0xdc00 || lch >= 0xdfff) + return (EOF); + + ch = (((ch & 0x3ff) << 10) | (lch & 0x3ff)) + 0x10000; + } + break; + + case ENCODE_UTF16LE : + /* + * Read UTF-16 little-endian char... + */ + + ch |= (getc(fp) << 8); + + if (mxml_bad_char(ch)) + { + mxml_error("Bad control character 0x%02x not allowed by XML standard!", + ch); + return (EOF); + } + else if (ch >= 0xd800 && ch <= 0xdbff) + { + /* + * Multi-word UTF-16 char... + */ + + int lch = getc(fp) | (getc(fp) << 8); + + if (lch < 0xdc00 || lch >= 0xdfff) + return (EOF); + + ch = (((ch & 0x3ff) << 10) | (lch & 0x3ff)) + 0x10000; + } + break; + } + +#if DEBUG > 1 + printf("mxml_file_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch); +#endif /* DEBUG > 1 */ + + return (ch); +} + + +/* + * 'mxml_file_putc()' - Write a character to a file. + */ + +static int /* O - 0 on success, -1 on failure */ +mxml_file_putc(int ch, /* I - Character to write */ + void *p) /* I - Pointer to file */ +{ + char buffer[4], /* Buffer for character */ + *bufptr; /* Pointer into buffer */ + int buflen; /* Number of bytes to write */ + + + if (ch < 0x80) + return (putc(ch, (FILE *)p) == EOF ? -1 : 0); + + bufptr = buffer; + + if (ch < 0x800) + { + /* + * Two-byte UTF-8 character... + */ + + *bufptr++ = 0xc0 | (ch >> 6); + *bufptr++ = 0x80 | (ch & 0x3f); + } + else if (ch < 0x10000) + { + /* + * Three-byte UTF-8 character... + */ + + *bufptr++ = 0xe0 | (ch >> 12); + *bufptr++ = 0x80 | ((ch >> 6) & 0x3f); + *bufptr++ = 0x80 | (ch & 0x3f); + } + else + { + /* + * Four-byte UTF-8 character... + */ + + *bufptr++ = 0xf0 | (ch >> 18); + *bufptr++ = 0x80 | ((ch >> 12) & 0x3f); + *bufptr++ = 0x80 | ((ch >> 6) & 0x3f); + *bufptr++ = 0x80 | (ch & 0x3f); + } + + buflen = bufptr - buffer; + + return (fwrite(buffer, 1, buflen, (FILE *)p) < buflen ? -1 : 0); +} + + +/* + * 'mxml_get_entity()' - Get the character corresponding to an entity... + */ + +static int /* O - Character value or EOF on error */ +mxml_get_entity(mxml_node_t *parent, /* I - Parent node */ + void *p, /* I - Pointer to source */ + int *encoding, /* IO - Character encoding */ + int (*getc_cb)(void *, int *)) + /* I - Get character function */ +{ + int ch; /* Current character */ + char entity[64], /* Entity string */ + *entptr; /* Pointer into entity */ + + + entptr = entity; + + while ((ch = (*getc_cb)(p, encoding)) != EOF) + if (ch > 126 || (!isalnum(ch) && ch != '#')) + break; + else if (entptr < (entity + sizeof(entity) - 1)) + *entptr++ = ch; + else + { + mxml_error("Entity name too long under parent <%s>!", + parent ? parent->value.element.name : "null"); + break; + } + + *entptr = '\0'; + + if (ch != ';') + { + mxml_error("Character entity \"%s\" not terminated under parent <%s>!", + entity, parent ? parent->value.element.name : "null"); + return (EOF); + } + + if (entity[0] == '#') + { + if (entity[1] == 'x') + ch = strtol(entity + 2, NULL, 16); + else + ch = strtol(entity + 1, NULL, 10); + } + else if ((ch = mxmlEntityGetValue(entity)) < 0) + mxml_error("Entity name \"%s;\" not supported under parent <%s>!", + entity, parent ? parent->value.element.name : "null"); + + if (mxml_bad_char(ch)) + { + mxml_error("Bad control character 0x%02x under parent <%s> not allowed by XML standard!", + ch, parent ? parent->value.element.name : "null"); + return (EOF); + } + + return (ch); +} + + +/* + * 'mxml_load_data()' - Load data into an XML node tree. + */ + +static mxml_node_t * /* O - First node or NULL if the file could not be read. */ +mxml_load_data( + mxml_node_t *top, /* I - Top node */ + void *p, /* I - Pointer to data */ + mxml_load_cb_t cb, /* I - Callback function or MXML_NO_CALLBACK */ + _mxml_getc_cb_t getc_cb, /* I - Read function */ + mxml_sax_cb_t sax_cb, /* I - SAX callback or MXML_NO_CALLBACK */ + void *sax_data) /* I - SAX user data */ +{ + mxml_node_t *node, /* Current node */ + *first, /* First node added */ + *parent; /* Current parent node */ + int ch, /* Character from file */ + whitespace; /* Non-zero if whitespace seen */ + char *buffer, /* String buffer */ + *bufptr; /* Pointer into buffer */ + int bufsize; /* Size of buffer */ + mxml_type_t type; /* Current node type */ + int encoding; /* Character encoding */ + _mxml_global_t *global = _mxml_global(); + /* Global data */ + static const char * const types[] = /* Type strings... */ + { + "MXML_ELEMENT", /* XML element with attributes */ + "MXML_INTEGER", /* Integer value */ + "MXML_OPAQUE", /* Opaque string */ + "MXML_REAL", /* Real value */ + "MXML_TEXT", /* Text fragment */ + "MXML_CUSTOM" /* Custom data */ + }; + + + /* + * Read elements and other nodes from the file... + */ + + if ((buffer = malloc(64)) == NULL) + { + mxml_error("Unable to allocate string buffer!"); + return (NULL); + } + + bufsize = 64; + bufptr = buffer; + parent = top; + first = NULL; + whitespace = 0; + encoding = ENCODE_UTF8; + + if (cb && parent) + type = (*cb)(parent); + else + type = MXML_TEXT; + + while ((ch = (*getc_cb)(p, &encoding)) != EOF) + { + if ((ch == '<' || + (mxml_isspace(ch) && type != MXML_OPAQUE && type != MXML_CUSTOM)) && + bufptr > buffer) + { + /* + * Add a new value node... + */ + + *bufptr = '\0'; + + switch (type) + { + case MXML_INTEGER : + node = mxmlNewInteger(parent, strtol(buffer, &bufptr, 0)); + break; + + case MXML_OPAQUE : + node = mxmlNewOpaque(parent, buffer); + break; + + case MXML_REAL : + node = mxmlNewReal(parent, strtod(buffer, &bufptr)); + break; + + case MXML_TEXT : + node = mxmlNewText(parent, whitespace, buffer); + break; + + case MXML_CUSTOM : + if (global->custom_load_cb) + { + /* + * Use the callback to fill in the custom data... + */ + + node = mxmlNewCustom(parent, NULL, NULL); + + if ((*global->custom_load_cb)(node, buffer)) + { + mxml_error("Bad custom value '%s' in parent <%s>!", + buffer, parent ? parent->value.element.name : "null"); + mxmlDelete(node); + node = NULL; + } + break; + } + + default : /* Ignore... */ + node = NULL; + break; + } + + if (*bufptr) + { + /* + * Bad integer/real number value... + */ + + mxml_error("Bad %s value '%s' in parent <%s>!", + type == MXML_INTEGER ? "integer" : "real", buffer, + parent ? parent->value.element.name : "null"); + break; + } + + bufptr = buffer; + whitespace = mxml_isspace(ch) && type == MXML_TEXT; + + if (!node && type != MXML_IGNORE) + { + /* + * Print error and return... + */ + + mxml_error("Unable to add value node of type %s to parent <%s>!", + types[type], parent ? parent->value.element.name : "null"); + goto error; + } + + if (sax_cb) + { + (*sax_cb)(node, MXML_SAX_DATA, sax_data); + + if (!mxmlRelease(node)) + node = NULL; + } + + if (!first && node) + first = node; + } + else if (mxml_isspace(ch) && type == MXML_TEXT) + whitespace = 1; + + /* + * Add lone whitespace node if we have an element and existing + * whitespace... + */ + + if (ch == '<' && whitespace && type == MXML_TEXT) + { + node = mxmlNewText(parent, whitespace, ""); + + if (sax_cb) + { + (*sax_cb)(node, MXML_SAX_DATA, sax_data); + + if (!mxmlRelease(node)) + node = NULL; + } + + if (!first && node) + first = node; + + whitespace = 0; + } + + if (ch == '<') + { + /* + * Start of open/close tag... + */ + + bufptr = buffer; + + while ((ch = (*getc_cb)(p, &encoding)) != EOF) + if (mxml_isspace(ch) || ch == '>' || (ch == '/' && bufptr > buffer)) + break; + else if (ch == '<') + { + mxml_error("Bare < in element!"); + goto error; + } + else if (ch == '&') + { + if ((ch = mxml_get_entity(parent, p, &encoding, getc_cb)) == EOF) + goto error; + + if (mxml_add_char(ch, &bufptr, &buffer, &bufsize)) + goto error; + } + else if (mxml_add_char(ch, &bufptr, &buffer, &bufsize)) + goto error; + else if (((bufptr - buffer) == 1 && buffer[0] == '?') || + ((bufptr - buffer) == 3 && !strncmp(buffer, "!--", 3)) || + ((bufptr - buffer) == 8 && !strncmp(buffer, "![CDATA[", 8))) + break; + + *bufptr = '\0'; + + if (!strcmp(buffer, "!--")) + { + /* + * Gather rest of comment... + */ + + while ((ch = (*getc_cb)(p, &encoding)) != EOF) + { + if (ch == '>' && bufptr > (buffer + 4) && + bufptr[-3] != '-' && bufptr[-2] == '-' && bufptr[-1] == '-') + break; + else if (mxml_add_char(ch, &bufptr, &buffer, &bufsize)) + goto error; + } + + /* + * Error out if we didn't get the whole comment... + */ + + if (ch != '>') + { + /* + * Print error and return... + */ + + mxml_error("Early EOF in comment node!"); + goto error; + } + + + /* + * Otherwise add this as an element under the current parent... + */ + + *bufptr = '\0'; + + if ((node = mxmlNewElement(parent, buffer)) == NULL) + { + /* + * Just print error for now... + */ + + mxml_error("Unable to add comment node to parent <%s>!", + parent ? parent->value.element.name : "null"); + break; + } + + if (sax_cb) + { + (*sax_cb)(node, MXML_SAX_COMMENT, sax_data); + + if (!mxmlRelease(node)) + node = NULL; + } + + if (node && !first) + first = node; + } + else if (!strcmp(buffer, "![CDATA[")) + { + /* + * Gather CDATA section... + */ + + while ((ch = (*getc_cb)(p, &encoding)) != EOF) + { + if (ch == '>' && !strncmp(bufptr - 2, "]]", 2)) + break; + else if (mxml_add_char(ch, &bufptr, &buffer, &bufsize)) + goto error; + } + + /* + * Error out if we didn't get the whole comment... + */ + + if (ch != '>') + { + /* + * Print error and return... + */ + + mxml_error("Early EOF in CDATA node!"); + goto error; + } + + + /* + * Otherwise add this as an element under the current parent... + */ + + *bufptr = '\0'; + + if ((node = mxmlNewElement(parent, buffer)) == NULL) + { + /* + * Print error and return... + */ + + mxml_error("Unable to add CDATA node to parent <%s>!", + parent ? parent->value.element.name : "null"); + goto error; + } + + if (sax_cb) + { + (*sax_cb)(node, MXML_SAX_CDATA, sax_data); + + if (!mxmlRelease(node)) + node = NULL; + } + + if (node && !first) + first = node; + } + else if (buffer[0] == '?') + { + /* + * Gather rest of processing instruction... + */ + + while ((ch = (*getc_cb)(p, &encoding)) != EOF) + { + if (ch == '>' && bufptr > buffer && bufptr[-1] == '?') + break; + else if (mxml_add_char(ch, &bufptr, &buffer, &bufsize)) + goto error; + } + + /* + * Error out if we didn't get the whole processing instruction... + */ + + if (ch != '>') + { + /* + * Print error and return... + */ + + mxml_error("Early EOF in processing instruction node!"); + goto error; + } + + /* + * Otherwise add this as an element under the current parent... + */ + + *bufptr = '\0'; + + if ((node = mxmlNewElement(parent, buffer)) == NULL) + { + /* + * Print error and return... + */ + + mxml_error("Unable to add processing instruction node to parent <%s>!", + parent ? parent->value.element.name : "null"); + goto error; + } + + if (sax_cb) + { + (*sax_cb)(node, MXML_SAX_DIRECTIVE, sax_data); + + if (!mxmlRelease(node)) + node = NULL; + } + + if (node) + { + if (!first) + first = node; + + if (!parent) + { + parent = node; + + if (cb) + type = (*cb)(parent); + } + } + } + else if (buffer[0] == '!') + { + /* + * Gather rest of declaration... + */ + + do + { + if (ch == '>') + break; + else + { + if (ch == '&') + if ((ch = mxml_get_entity(parent, p, &encoding, getc_cb)) == EOF) + goto error; + + if (mxml_add_char(ch, &bufptr, &buffer, &bufsize)) + goto error; + } + } + while ((ch = (*getc_cb)(p, &encoding)) != EOF); + + /* + * Error out if we didn't get the whole declaration... + */ + + if (ch != '>') + { + /* + * Print error and return... + */ + + mxml_error("Early EOF in declaration node!"); + goto error; + } + + /* + * Otherwise add this as an element under the current parent... + */ + + *bufptr = '\0'; + + if ((node = mxmlNewElement(parent, buffer)) == NULL) + { + /* + * Print error and return... + */ + + mxml_error("Unable to add declaration node to parent <%s>!", + parent ? parent->value.element.name : "null"); + goto error; + } + + if (sax_cb) + { + (*sax_cb)(node, MXML_SAX_DIRECTIVE, sax_data); + + if (!mxmlRelease(node)) + node = NULL; + } + + if (node) + { + if (!first) + first = node; + + if (!parent) + { + parent = node; + + if (cb) + type = (*cb)(parent); + } + } + } + else if (buffer[0] == '/') + { + /* + * Handle close tag... + */ + + if (!parent || strcmp(buffer + 1, parent->value.element.name)) + { + /* + * Close tag doesn't match tree; print an error for now... + */ + + mxml_error("Mismatched close tag <%s> under parent <%s>!", + buffer, parent ? parent->value.element.name : "(null)"); + goto error; + } + + /* + * Keep reading until we see >... + */ + + while (ch != '>' && ch != EOF) + ch = (*getc_cb)(p, &encoding); + + node = parent; + parent = parent->parent; + + if (sax_cb) + { + (*sax_cb)(node, MXML_SAX_ELEMENT_CLOSE, sax_data); + + mxmlRelease(node); + } + + /* + * Ascend into the parent and set the value type as needed... + */ + + if (cb && parent) + type = (*cb)(parent); + } + else + { + /* + * Handle open tag... + */ + + if ((node = mxmlNewElement(parent, buffer)) == NULL) + { + /* + * Just print error for now... + */ + + mxml_error("Unable to add element node to parent <%s>!", + parent ? parent->value.element.name : "null"); + goto error; + } + + if (mxml_isspace(ch)) + { + if ((ch = mxml_parse_element(node, p, &encoding, getc_cb)) == EOF) + goto error; + } + else if (ch == '/') + { + if ((ch = (*getc_cb)(p, &encoding)) != '>') + { + mxml_error("Expected > but got '%c' instead for element <%s/>!", + ch, buffer); + mxmlDelete(node); + goto error; + } + + ch = '/'; + } + + if (sax_cb) + (*sax_cb)(node, MXML_SAX_ELEMENT_OPEN, sax_data); + + if (!first) + first = node; + + if (ch == EOF) + break; + + if (ch != '/') + { + /* + * Descend into this node, setting the value type as needed... + */ + + parent = node; + + if (cb && parent) + type = (*cb)(parent); + } + else if (sax_cb) + { + (*sax_cb)(node, MXML_SAX_ELEMENT_CLOSE, sax_data); + + if (!mxmlRelease(node) && first == node) + first = NULL; + } + } + + bufptr = buffer; + } + else if (ch == '&') + { + /* + * Add character entity to current buffer... + */ + + if ((ch = mxml_get_entity(parent, p, &encoding, getc_cb)) == EOF) + goto error; + + if (mxml_add_char(ch, &bufptr, &buffer, &bufsize)) + goto error; + } + else if (type == MXML_OPAQUE || type == MXML_CUSTOM || !mxml_isspace(ch)) + { + /* + * Add character to current buffer... + */ + + if (mxml_add_char(ch, &bufptr, &buffer, &bufsize)) + goto error; + } + } + + /* + * Free the string buffer - we don't need it anymore... + */ + + free(buffer); + + /* + * Find the top element and return it... + */ + + if (parent) + { + node = parent; + + while (parent->parent != top && parent->parent) + parent = parent->parent; + + if (node != parent) + { + mxml_error("Missing close tag under parent <%s>!", + node->value.element.name, + node->parent ? node->parent->value.element.name : "(null)"); + + mxmlDelete(first); + + return (NULL); + } + } + + if (parent) + return (parent); + else + return (first); + + /* + * Common error return... + */ + +error: + + mxmlDelete(first); + + free(buffer); + + return (NULL); +} + + +/* + * 'mxml_parse_element()' - Parse an element for any attributes... + */ + +static int /* O - Terminating character */ +mxml_parse_element( + mxml_node_t *node, /* I - Element node */ + void *p, /* I - Data to read from */ + int *encoding, /* IO - Encoding */ + _mxml_getc_cb_t getc_cb) /* I - Data callback */ +{ + int ch, /* Current character in file */ + quote; /* Quoting character */ + char *name, /* Attribute name */ + *value, /* Attribute value */ + *ptr; /* Pointer into name/value */ + int namesize, /* Size of name string */ + valsize; /* Size of value string */ + + + /* + * Initialize the name and value buffers... + */ + + if ((name = malloc(64)) == NULL) + { + mxml_error("Unable to allocate memory for name!"); + return (EOF); + } + + namesize = 64; + + if ((value = malloc(64)) == NULL) + { + free(name); + mxml_error("Unable to allocate memory for value!"); + return (EOF); + } + + valsize = 64; + + /* + * Loop until we hit a >, /, ?, or EOF... + */ + + while ((ch = (*getc_cb)(p, encoding)) != EOF) + { +#if DEBUG > 1 + fprintf(stderr, "parse_element: ch='%c'\n", ch); +#endif /* DEBUG > 1 */ + + /* + * Skip leading whitespace... + */ + + if (mxml_isspace(ch)) + continue; + + /* + * Stop at /, ?, or >... + */ + + if (ch == '/' || ch == '?') + { + /* + * Grab the > character and print an error if it isn't there... + */ + + quote = (*getc_cb)(p, encoding); + + if (quote != '>') + { + mxml_error("Expected '>' after '%c' for element %s, but got '%c'!", + ch, node->value.element.name, quote); + goto error; + } + + break; + } + else if (ch == '<') + { + mxml_error("Bare < in element %s!", node->value.element.name); + goto error; + } + else if (ch == '>') + break; + + /* + * Read the attribute name... + */ + + name[0] = ch; + ptr = name + 1; + + if (ch == '\"' || ch == '\'') + { + /* + * Name is in quotes, so get a quoted string... + */ + + quote = ch; + + while ((ch = (*getc_cb)(p, encoding)) != EOF) + { + if (ch == '&') + if ((ch = mxml_get_entity(node, p, encoding, getc_cb)) == EOF) + goto error; + + if (mxml_add_char(ch, &ptr, &name, &namesize)) + goto error; + + if (ch == quote) + break; + } + } + else + { + /* + * Grab an normal, non-quoted name... + */ + + while ((ch = (*getc_cb)(p, encoding)) != EOF) + if (mxml_isspace(ch) || ch == '=' || ch == '/' || ch == '>' || + ch == '?') + break; + else + { + if (ch == '&') + if ((ch = mxml_get_entity(node, p, encoding, getc_cb)) == EOF) + goto error; + + if (mxml_add_char(ch, &ptr, &name, &namesize)) + goto error; + } + } + + *ptr = '\0'; + + if (mxmlElementGetAttr(node, name)) + goto error; + + while (ch != EOF && mxml_isspace(ch)) + ch = (*getc_cb)(p, encoding); + + if (ch == '=') + { + /* + * Read the attribute value... + */ + + while ((ch = (*getc_cb)(p, encoding)) != EOF && mxml_isspace(ch)); + + if (ch == EOF) + { + mxml_error("Missing value for attribute '%s' in element %s!", + name, node->value.element.name); + goto error; + } + + if (ch == '\'' || ch == '\"') + { + /* + * Read quoted value... + */ + + quote = ch; + ptr = value; + + while ((ch = (*getc_cb)(p, encoding)) != EOF) + if (ch == quote) + break; + else + { + if (ch == '&') + if ((ch = mxml_get_entity(node, p, encoding, getc_cb)) == EOF) + goto error; + + if (mxml_add_char(ch, &ptr, &value, &valsize)) + goto error; + } + + *ptr = '\0'; + } + else + { + /* + * Read unquoted value... + */ + + value[0] = ch; + ptr = value + 1; + + while ((ch = (*getc_cb)(p, encoding)) != EOF) + if (mxml_isspace(ch) || ch == '=' || ch == '/' || ch == '>') + break; + else + { + if (ch == '&') + if ((ch = mxml_get_entity(node, p, encoding, getc_cb)) == EOF) + goto error; + + if (mxml_add_char(ch, &ptr, &value, &valsize)) + goto error; + } + + *ptr = '\0'; + } + + /* + * Set the attribute with the given string value... + */ + + mxmlElementSetAttr(node, name, value); + } + else + { + mxml_error("Missing value for attribute '%s' in element %s!", + name, node->value.element.name); + goto error; + } + + /* + * Check the end character... + */ + + if (ch == '/' || ch == '?') + { + /* + * Grab the > character and print an error if it isn't there... + */ + + quote = (*getc_cb)(p, encoding); + + if (quote != '>') + { + mxml_error("Expected '>' after '%c' for element %s, but got '%c'!", + ch, node->value.element.name, quote); + ch = EOF; + } + + break; + } + else if (ch == '>') + break; + } + + /* + * Free the name and value buffers and return... + */ + + free(name); + free(value); + + return (ch); + + /* + * Common error return point... + */ + +error: + + free(name); + free(value); + + return (EOF); +} + + +/* + * 'mxml_string_getc()' - Get a character from a string. + */ + +static int /* O - Character or EOF */ +mxml_string_getc(void *p, /* I - Pointer to file */ + int *encoding) /* IO - Encoding */ +{ + int ch; /* Character */ + const char **s; /* Pointer to string pointer */ + + + s = (const char **)p; + + if ((ch = (*s)[0] & 255) != 0 || *encoding == ENCODE_UTF16LE) + { + /* + * Got character; convert UTF-8 to integer and return... + */ + + (*s)++; + + switch (*encoding) + { + case ENCODE_UTF8 : + if (!(ch & 0x80)) + { +#if DEBUG > 1 + printf("mxml_string_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch); +#endif /* DEBUG > 1 */ + + if (mxml_bad_char(ch)) + { + mxml_error("Bad control character 0x%02x not allowed by XML standard!", + ch); + return (EOF); + } + + return (ch); + } + else if (ch == 0xfe) + { + /* + * UTF-16 big-endian BOM? + */ + + if (((*s)[0] & 255) != 0xff) + return (EOF); + + *encoding = ENCODE_UTF16BE; + (*s)++; + + return (mxml_string_getc(p, encoding)); + } + else if (ch == 0xff) + { + /* + * UTF-16 little-endian BOM? + */ + + if (((*s)[0] & 255) != 0xfe) + return (EOF); + + *encoding = ENCODE_UTF16LE; + (*s)++; + + return (mxml_string_getc(p, encoding)); + } + else if ((ch & 0xe0) == 0xc0) + { + /* + * Two-byte value... + */ + + if (((*s)[0] & 0xc0) != 0x80) + return (EOF); + + ch = ((ch & 0x1f) << 6) | ((*s)[0] & 0x3f); + + (*s)++; + + if (ch < 0x80) + return (EOF); + +#if DEBUG > 1 + printf("mxml_string_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch); +#endif /* DEBUG > 1 */ + + return (ch); + } + else if ((ch & 0xf0) == 0xe0) + { + /* + * Three-byte value... + */ + + if (((*s)[0] & 0xc0) != 0x80 || + ((*s)[1] & 0xc0) != 0x80) + return (EOF); + + ch = ((((ch & 0x0f) << 6) | ((*s)[0] & 0x3f)) << 6) | ((*s)[1] & 0x3f); + + (*s) += 2; + + if (ch < 0x800) + return (EOF); + +#if DEBUG > 1 + printf("mxml_string_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch); +#endif /* DEBUG > 1 */ + + return (ch); + } + else if ((ch & 0xf8) == 0xf0) + { + /* + * Four-byte value... + */ + + if (((*s)[0] & 0xc0) != 0x80 || + ((*s)[1] & 0xc0) != 0x80 || + ((*s)[2] & 0xc0) != 0x80) + return (EOF); + + ch = ((((((ch & 0x07) << 6) | ((*s)[0] & 0x3f)) << 6) | + ((*s)[1] & 0x3f)) << 6) | ((*s)[2] & 0x3f); + + (*s) += 3; + + if (ch < 0x10000) + return (EOF); + +#if DEBUG > 1 + printf("mxml_string_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch); +#endif /* DEBUG > 1 */ + + return (ch); + } + else + return (EOF); + + case ENCODE_UTF16BE : + /* + * Read UTF-16 big-endian char... + */ + + ch = (ch << 8) | ((*s)[0] & 255); + (*s) ++; + + if (mxml_bad_char(ch)) + { + mxml_error("Bad control character 0x%02x not allowed by XML standard!", + ch); + return (EOF); + } + else if (ch >= 0xd800 && ch <= 0xdbff) + { + /* + * Multi-word UTF-16 char... + */ + + int lch; /* Lower word */ + + + if (!(*s)[0]) + return (EOF); + + lch = (((*s)[0] & 255) << 8) | ((*s)[1] & 255); + (*s) += 2; + + if (lch < 0xdc00 || lch >= 0xdfff) + return (EOF); + + ch = (((ch & 0x3ff) << 10) | (lch & 0x3ff)) + 0x10000; + } + +#if DEBUG > 1 + printf("mxml_string_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch); +#endif /* DEBUG > 1 */ + + return (ch); + + case ENCODE_UTF16LE : + /* + * Read UTF-16 little-endian char... + */ + + ch = ch | (((*s)[0] & 255) << 8); + + if (!ch) + { + (*s) --; + return (EOF); + } + + (*s) ++; + + if (mxml_bad_char(ch)) + { + mxml_error("Bad control character 0x%02x not allowed by XML standard!", + ch); + return (EOF); + } + else if (ch >= 0xd800 && ch <= 0xdbff) + { + /* + * Multi-word UTF-16 char... + */ + + int lch; /* Lower word */ + + + if (!(*s)[1]) + return (EOF); + + lch = (((*s)[1] & 255) << 8) | ((*s)[0] & 255); + (*s) += 2; + + if (lch < 0xdc00 || lch >= 0xdfff) + return (EOF); + + ch = (((ch & 0x3ff) << 10) | (lch & 0x3ff)) + 0x10000; + } + +#if DEBUG > 1 + printf("mxml_string_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch); +#endif /* DEBUG > 1 */ + + return (ch); + } + } + + return (EOF); +} + + +/* + * 'mxml_string_putc()' - Write a character to a string. + */ + +static int /* O - 0 on success, -1 on failure */ +mxml_string_putc(int ch, /* I - Character to write */ + void *p) /* I - Pointer to string pointers */ +{ + char **pp; /* Pointer to string pointers */ + + + pp = (char **)p; + + if (ch < 0x80) + { + /* + * Plain ASCII doesn't need special encoding... + */ + + if (pp[0] < pp[1]) + pp[0][0] = ch; + + pp[0] ++; + } + else if (ch < 0x800) + { + /* + * Two-byte UTF-8 character... + */ + + if ((pp[0] + 1) < pp[1]) + { + pp[0][0] = 0xc0 | (ch >> 6); + pp[0][1] = 0x80 | (ch & 0x3f); + } + + pp[0] += 2; + } + else if (ch < 0x10000) + { + /* + * Three-byte UTF-8 character... + */ + + if ((pp[0] + 2) < pp[1]) + { + pp[0][0] = 0xe0 | (ch >> 12); + pp[0][1] = 0x80 | ((ch >> 6) & 0x3f); + pp[0][2] = 0x80 | (ch & 0x3f); + } + + pp[0] += 3; + } + else + { + /* + * Four-byte UTF-8 character... + */ + + if ((pp[0] + 2) < pp[1]) + { + pp[0][0] = 0xf0 | (ch >> 18); + pp[0][1] = 0x80 | ((ch >> 12) & 0x3f); + pp[0][2] = 0x80 | ((ch >> 6) & 0x3f); + pp[0][3] = 0x80 | (ch & 0x3f); + } + + pp[0] += 4; + } + + return (0); +} + + +/* + * 'mxml_write_name()' - Write a name string. + */ + +static int /* O - 0 on success, -1 on failure */ +mxml_write_name(const char *s, /* I - Name to write */ + void *p, /* I - Write pointer */ + int (*putc_cb)(int, void *)) + /* I - Write callback */ +{ + char quote; /* Quote character */ + const char *name; /* Entity name */ + + + if (*s == '\"' || *s == '\'') + { + /* + * Write a quoted name string... + */ + + if ((*putc_cb)(*s, p) < 0) + return (-1); + + quote = *s++; + + while (*s && *s != quote) + { + if ((name = mxmlEntityGetName(*s)) != NULL) + { + if ((*putc_cb)('&', p) < 0) + return (-1); + + while (*name) + { + if ((*putc_cb)(*name, p) < 0) + return (-1); + + name ++; + } + + if ((*putc_cb)(';', p) < 0) + return (-1); + } + else if ((*putc_cb)(*s, p) < 0) + return (-1); + + s ++; + } + + /* + * Write the end quote... + */ + + if ((*putc_cb)(quote, p) < 0) + return (-1); + } + else + { + /* + * Write a non-quoted name string... + */ + + while (*s) + { + if ((*putc_cb)(*s, p) < 0) + return (-1); + + s ++; + } + } + + return (0); +} + + +/* + * 'mxml_write_node()' - Save an XML node to a file. + */ + +static int /* O - Column or -1 on error */ +mxml_write_node(mxml_node_t *node, /* I - Node to write */ + void *p, /* I - File to write to */ + mxml_save_cb_t cb, /* I - Whitespace callback */ + int col, /* I - Current column */ + _mxml_putc_cb_t putc_cb,/* I - Output callback */ + _mxml_global_t *global)/* I - Global data */ +{ + int i, /* Looping var */ + width; /* Width of attr + value */ + mxml_attr_t *attr; /* Current attribute */ + char s[255]; /* Temporary string */ + + + while (node != NULL) + { + /* + * Print the node value... + */ + + switch (node->type) + { + case MXML_ELEMENT : + col = mxml_write_ws(node, p, cb, MXML_WS_BEFORE_OPEN, col, putc_cb); + + if ((*putc_cb)('<', p) < 0) + return (-1); + if (node->value.element.name[0] == '?' || + !strncmp(node->value.element.name, "!--", 3) || + !strncmp(node->value.element.name, "![CDATA[", 8)) + { + /* + * Comments, CDATA, and processing instructions do not + * use character entities. + */ + + const char *ptr; /* Pointer into name */ + + + for (ptr = node->value.element.name; *ptr; ptr ++) + if ((*putc_cb)(*ptr, p) < 0) + return (-1); + + /* + * Prefer a newline for whitespace after ?xml... + */ + + if (!strncmp(node->value.element.name, "?xml", 4)) + col = global->wrap; + } + else if (mxml_write_name(node->value.element.name, p, putc_cb) < 0) + return (-1); + + col += strlen(node->value.element.name) + 1; + + for (i = node->value.element.num_attrs, attr = node->value.element.attrs; + i > 0; + i --, attr ++) + { + width = strlen(attr->name); + + if (attr->value) + width += strlen(attr->value) + 3; + + if ((col + width) > global->wrap) + { + if ((*putc_cb)('\n', p) < 0) + return (-1); + + col = 0; + } + else + { + if ((*putc_cb)(' ', p) < 0) + return (-1); + + col ++; + } + + if (mxml_write_name(attr->name, p, putc_cb) < 0) + return (-1); + + if (attr->value) + { + if ((*putc_cb)('=', p) < 0) + return (-1); + if ((*putc_cb)('\"', p) < 0) + return (-1); + if (mxml_write_string(attr->value, p, putc_cb) < 0) + return (-1); + if ((*putc_cb)('\"', p) < 0) + return (-1); + } + + col += width; + } + + if (node->child) + { + /* + * Write children... + */ + + if ((*putc_cb)('>', p) < 0) + return (-1); + else + col ++; + + col = mxml_write_ws(node, p, cb, MXML_WS_AFTER_OPEN, col, putc_cb); + + if ((col = mxml_write_node(node->child, p, cb, col, putc_cb, + global)) < 0) + return (-1); + + /* + * The ? and ! elements are special-cases and have no end tags... + */ + + if (node->value.element.name[0] != '!' && + node->value.element.name[0] != '?') + { + col = mxml_write_ws(node, p, cb, MXML_WS_BEFORE_CLOSE, col, putc_cb); + + if ((*putc_cb)('<', p) < 0) + return (-1); + if ((*putc_cb)('/', p) < 0) + return (-1); + if (mxml_write_string(node->value.element.name, p, putc_cb) < 0) + return (-1); + if ((*putc_cb)('>', p) < 0) + return (-1); + + col += strlen(node->value.element.name) + 3; + + col = mxml_write_ws(node, p, cb, MXML_WS_AFTER_CLOSE, col, putc_cb); + } + } + else if (node->value.element.name[0] == '!' || + node->value.element.name[0] == '?') + { + /* + * The ? and ! elements are special-cases... + */ + + if ((*putc_cb)('>', p) < 0) + return (-1); + else + col ++; + + col = mxml_write_ws(node, p, cb, MXML_WS_AFTER_OPEN, col, putc_cb); + } + else + { + if ((*putc_cb)(' ', p) < 0) + return (-1); + if ((*putc_cb)('/', p) < 0) + return (-1); + if ((*putc_cb)('>', p) < 0) + return (-1); + + col += 3; + + col = mxml_write_ws(node, p, cb, MXML_WS_AFTER_OPEN, col, putc_cb); + } + break; + + case MXML_INTEGER : + if (node->prev) + { + if (col > global->wrap) + { + if ((*putc_cb)('\n', p) < 0) + return (-1); + + col = 0; + } + else if ((*putc_cb)(' ', p) < 0) + return (-1); + else + col ++; + } + + sprintf(s, "%d", node->value.integer); + if (mxml_write_string(s, p, putc_cb) < 0) + return (-1); + + col += strlen(s); + break; + + case MXML_OPAQUE : + if (mxml_write_string(node->value.opaque, p, putc_cb) < 0) + return (-1); + + col += strlen(node->value.opaque); + break; + + case MXML_REAL : + if (node->prev) + { + if (col > global->wrap) + { + if ((*putc_cb)('\n', p) < 0) + return (-1); + + col = 0; + } + else if ((*putc_cb)(' ', p) < 0) + return (-1); + else + col ++; + } + + sprintf(s, "%f", node->value.real); + if (mxml_write_string(s, p, putc_cb) < 0) + return (-1); + + col += strlen(s); + break; + + case MXML_TEXT : + if (node->value.text.whitespace && col > 0) + { + if (col > global->wrap) + { + if ((*putc_cb)('\n', p) < 0) + return (-1); + + col = 0; + } + else if ((*putc_cb)(' ', p) < 0) + return (-1); + else + col ++; + } + + if (mxml_write_string(node->value.text.string, p, putc_cb) < 0) + return (-1); + + col += strlen(node->value.text.string); + break; + + case MXML_CUSTOM : + if (global->custom_save_cb) + { + char *data; /* Custom data string */ + const char *newline; /* Last newline in string */ + + + if ((data = (*global->custom_save_cb)(node)) == NULL) + return (-1); + + if (mxml_write_string(data, p, putc_cb) < 0) + return (-1); + + if ((newline = strrchr(data, '\n')) == NULL) + col += strlen(data); + else + col = strlen(newline); + + free(data); + break; + } + + default : /* Should never happen */ + return (-1); + } + + /* + * Next node... + */ + + node = node->next; + } + + return (col); +} + + +/* + * 'mxml_write_string()' - Write a string, escaping & and < as needed. + */ + +static int /* O - 0 on success, -1 on failure */ +mxml_write_string( + const char *s, /* I - String to write */ + void *p, /* I - Write pointer */ + _mxml_putc_cb_t putc_cb) /* I - Write callback */ +{ + const char *name; /* Entity name, if any */ + + + while (*s) + { + if ((name = mxmlEntityGetName(*s)) != NULL) + { + if ((*putc_cb)('&', p) < 0) + return (-1); + + while (*name) + { + if ((*putc_cb)(*name, p) < 0) + return (-1); + name ++; + } + + if ((*putc_cb)(';', p) < 0) + return (-1); + } + else if ((*putc_cb)(*s, p) < 0) + return (-1); + + s ++; + } + + return (0); +} + + +/* + * 'mxml_write_ws()' - Do whitespace callback... + */ + +static int /* O - New column */ +mxml_write_ws(mxml_node_t *node, /* I - Current node */ + void *p, /* I - Write pointer */ + mxml_save_cb_t cb, /* I - Callback function */ + int ws, /* I - Where value */ + int col, /* I - Current column */ + _mxml_putc_cb_t putc_cb) /* I - Write callback */ +{ + const char *s; /* Whitespace string */ + + + if (cb && (s = (*cb)(node, ws)) != NULL) + { + while (*s) + { + if ((*putc_cb)(*s, p) < 0) + return (-1); + else if (*s == '\n') + col = 0; + else if (*s == '\t') + { + col += MXML_TAB; + col = col - (col % MXML_TAB); + } + else + col ++; + + s ++; + } + } + + return (col); +} + + +/* + * End of "$Id: mxml-file.c 329 2008-01-13 00:42:35Z mike $". + */ diff --git a/plugins/zynaddsubfx/mxml/mxml-index.c b/plugins/zynaddsubfx/mxml/mxml-index.c new file mode 100644 index 000000000..f8a7c0fcb --- /dev/null +++ b/plugins/zynaddsubfx/mxml/mxml-index.c @@ -0,0 +1,649 @@ +/* + * "$Id: mxml-index.c 184 2005-01-29 07:21:44Z mike $" + * + * Index support code for Mini-XML, a small XML-like file parsing library. + * + * Copyright 2003-2005 by Michael Sweet. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2, 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. + * + * Contents: + * + * mxmlIndexDelete() - Delete an index. + * mxmlIndexEnum() - Return the next node in the index. + * mxmlIndexFind() - Find the next matching node. + * mxmlIndexNew() - Create a new index. + * mxmlIndexReset() - Reset the enumeration/find pointer in the index and + * return the first node in the index. + * index_compare() - Compare two nodes. + * index_find() - Compare a node with index values. + * index_sort() - Sort the nodes in the index... + */ + +/* + * Include necessary headers... + */ + +#include "mxml-config.h" +#include "mxml.h" + + +/* + * Sort functions... + */ + +static int index_compare(mxml_index_t *ind, mxml_node_t *first, + mxml_node_t *second); +static int index_find(mxml_index_t *ind, const char *element, + const char *value, mxml_node_t *node); +static void index_sort(mxml_index_t *ind, int left, int right); + + +/* + * 'mxmlIndexDelete()' - Delete an index. + */ + +void +mxmlIndexDelete(mxml_index_t *ind) /* I - Index to delete */ +{ + /* + * Range check input.. + */ + + if (!ind) + return; + + /* + * Free memory... + */ + + if (ind->attr) + free(ind->attr); + + if (ind->alloc_nodes) + free(ind->nodes); + + free(ind); +} + + +/* + * 'mxmlIndexEnum()' - Return the next node in the index. + * + * Nodes are returned in the sorted order of the index. + */ + +mxml_node_t * /* O - Next node or NULL if there is none */ +mxmlIndexEnum(mxml_index_t *ind) /* I - Index to enumerate */ +{ + /* + * Range check input... + */ + + if (!ind) + return (NULL); + + /* + * Return the next node... + */ + + if (ind->cur_node < ind->num_nodes) + return (ind->nodes[ind->cur_node ++]); + else + return (NULL); +} + + +/* + * 'mxmlIndexFind()' - Find the next matching node. + * + * You should call mxmlIndexReset() prior to using this function for + * the first time with a particular set of "element" and "value" + * strings. Passing NULL for both "element" and "value" is equivalent + * to calling mxmlIndexEnum(). + */ + +mxml_node_t * /* O - Node or NULL if none found */ +mxmlIndexFind(mxml_index_t *ind, /* I - Index to search */ + const char *element, /* I - Element name to find, if any */ + const char *value) /* I - Attribute value, if any */ +{ + int diff, /* Difference between names */ + current, /* Current entity in search */ + first, /* First entity in search */ + last; /* Last entity in search */ + + +#ifdef DEBUG + printf("mxmlIndexFind(ind=%p, element=\"%s\", value=\"%s\")\n", + ind, element ? element : "(null)", value ? value : "(null)"); +#endif /* DEBUG */ + + /* + * Range check input... + */ + + if (!ind || (!ind->attr && value)) + { +#ifdef DEBUG + puts(" returning NULL..."); + printf(" ind->attr=\"%s\"\n", ind->attr ? ind->attr : "(null)"); +#endif /* DEBUG */ + + return (NULL); + } + + /* + * If both element and value are NULL, just enumerate the nodes in the + * index... + */ + + if (!element && !value) + return (mxmlIndexEnum(ind)); + + /* + * If there are no nodes in the index, return NULL... + */ + + if (!ind->num_nodes) + { +#ifdef DEBUG + puts(" returning NULL..."); + puts(" no nodes!"); +#endif /* DEBUG */ + + return (NULL); + } + + /* + * If cur_node == 0, then find the first matching node... + */ + + if (ind->cur_node == 0) + { + /* + * Find the first node using a modified binary search algorithm... + */ + + first = 0; + last = ind->num_nodes - 1; + +#ifdef DEBUG + printf(" find first time, num_nodes=%d...\n", ind->num_nodes); +#endif /* DEBUG */ + + while ((last - first) > 1) + { + current = (first + last) / 2; + +#ifdef DEBUG + printf(" first=%d, last=%d, current=%d\n", first, last, current); +#endif /* DEBUG */ + + if ((diff = index_find(ind, element, value, ind->nodes[current])) == 0) + { + /* + * Found a match, move back to find the first... + */ + +#ifdef DEBUG + puts(" match!"); +#endif /* DEBUG */ + + while (current > 0 && + !index_find(ind, element, value, ind->nodes[current - 1])) + current --; + +#ifdef DEBUG + printf(" returning first match=%d\n", current); +#endif /* DEBUG */ + + /* + * Return the first match and save the index to the next... + */ + + ind->cur_node = current + 1; + + return (ind->nodes[current]); + } + else if (diff < 0) + last = current; + else + first = current; + +#ifdef DEBUG + printf(" diff=%d\n", diff); +#endif /* DEBUG */ + } + + /* + * If we get this far, then we found exactly 0 or 1 matches... + */ + + for (current = first; current <= last; current ++) + if (!index_find(ind, element, value, ind->nodes[current])) + { + /* + * Found exactly one (or possibly two) match... + */ + +#ifdef DEBUG + printf(" returning only match %d...\n", current); +#endif /* DEBUG */ + + ind->cur_node = current + 1; + + return (ind->nodes[current]); + } + + /* + * No matches... + */ + + ind->cur_node = ind->num_nodes; + +#ifdef DEBUG + puts(" returning NULL..."); +#endif /* DEBUG */ + + return (NULL); + } + else if (ind->cur_node < ind->num_nodes && + !index_find(ind, element, value, ind->nodes[ind->cur_node])) + { + /* + * Return the next matching node... + */ + +#ifdef DEBUG + printf(" returning next match %d...\n", ind->cur_node); +#endif /* DEBUG */ + + return (ind->nodes[ind->cur_node ++]); + } + + /* + * If we get this far, then we have no matches... + */ + + ind->cur_node = ind->num_nodes; + +#ifdef DEBUG + puts(" returning NULL..."); +#endif /* DEBUG */ + + return (NULL); +} + + +/* + * 'mxmlIndexNew()' - Create a new index. + * + * The index will contain all nodes that contain the named element and/or + * attribute. If both "element" and "attr" are NULL, then the index will + * contain a sorted list of the elements in the node tree. Nodes are + * sorted by element name and optionally by attribute value if the "attr" + * argument is not NULL. + */ + +mxml_index_t * /* O - New index */ +mxmlIndexNew(mxml_node_t *node, /* I - XML node tree */ + const char *element, /* I - Element to index or NULL for all */ + const char *attr) /* I - Attribute to index or NULL for none */ +{ + mxml_index_t *ind; /* New index */ + mxml_node_t *current, /* Current node in index */ + **temp; /* Temporary node pointer array */ + + + /* + * Range check input... + */ + +#ifdef DEBUG + printf("mxmlIndexNew(node=%p, element=\"%s\", attr=\"%s\")\n", + node, element ? element : "(null)", attr ? attr : "(null)"); +#endif /* DEBUG */ + + if (!node) + return (NULL); + + /* + * Create a new index... + */ + + if ((ind = calloc(1, sizeof(mxml_index_t))) == NULL) + { + mxml_error("Unable to allocate %d bytes for index - %s", + sizeof(mxml_index_t), strerror(errno)); + return (NULL); + } + + if (attr) + ind->attr = strdup(attr); + + if (!element && !attr) + current = node; + else + current = mxmlFindElement(node, node, element, attr, NULL, MXML_DESCEND); + + while (current) + { + if (ind->num_nodes >= ind->alloc_nodes) + { + if (!ind->alloc_nodes) + temp = malloc(64 * sizeof(mxml_node_t *)); + else + temp = realloc(ind->nodes, (ind->alloc_nodes + 64) * sizeof(mxml_node_t *)); + + if (!temp) + { + /* + * Unable to allocate memory for the index, so abort... + */ + + mxml_error("Unable to allocate %d bytes for index: %s", + (ind->alloc_nodes + 64) * sizeof(mxml_node_t *), + strerror(errno)); + + mxmlIndexDelete(ind); + return (NULL); + } + + ind->nodes = temp; + ind->alloc_nodes += 64; + } + + ind->nodes[ind->num_nodes ++] = current; + + current = mxmlFindElement(current, node, element, attr, NULL, MXML_DESCEND); + } + + /* + * Sort nodes based upon the search criteria... + */ + +#ifdef DEBUG + { + int i; /* Looping var */ + + + printf("%d node(s) in index.\n\n", ind->num_nodes); + + if (attr) + { + printf("Node Address Element %s\n", attr); + puts("-------- -------- -------------- ------------------------------"); + + for (i = 0; i < ind->num_nodes; i ++) + printf("%8d %-8p %-14.14s %s\n", i, ind->nodes[i], + ind->nodes[i]->value.element.name, + mxmlElementGetAttr(ind->nodes[i], attr)); + } + else + { + puts("Node Address Element"); + puts("-------- -------- --------------"); + + for (i = 0; i < ind->num_nodes; i ++) + printf("%8d %-8p %s\n", i, ind->nodes[i], + ind->nodes[i]->value.element.name); + } + + putchar('\n'); + } +#endif /* DEBUG */ + + if (ind->num_nodes > 1) + index_sort(ind, 0, ind->num_nodes - 1); + +#ifdef DEBUG + { + int i; /* Looping var */ + + + puts("After sorting:\n"); + + if (attr) + { + printf("Node Address Element %s\n", attr); + puts("-------- -------- -------------- ------------------------------"); + + for (i = 0; i < ind->num_nodes; i ++) + printf("%8d %-8p %-14.14s %s\n", i, ind->nodes[i], + ind->nodes[i]->value.element.name, + mxmlElementGetAttr(ind->nodes[i], attr)); + } + else + { + puts("Node Address Element"); + puts("-------- -------- --------------"); + + for (i = 0; i < ind->num_nodes; i ++) + printf("%8d %-8p %s\n", i, ind->nodes[i], + ind->nodes[i]->value.element.name); + } + + putchar('\n'); + } +#endif /* DEBUG */ + + /* + * Return the new index... + */ + + return (ind); +} + + +/* + * 'mxmlIndexReset()' - Reset the enumeration/find pointer in the index and + * return the first node in the index. + * + * This function should be called prior to using mxmlIndexEnum() or + * mxmlIndexFind() for the first time. + */ + +mxml_node_t * /* O - First node or NULL if there is none */ +mxmlIndexReset(mxml_index_t *ind) /* I - Index to reset */ +{ +#ifdef DEBUG + printf("mxmlIndexReset(ind=%p)\n", ind); +#endif /* DEBUG */ + + /* + * Range check input... + */ + + if (!ind) + return (NULL); + + /* + * Set the index to the first element... + */ + + ind->cur_node = 0; + + /* + * Return the first node... + */ + + if (ind->num_nodes) + return (ind->nodes[0]); + else + return (NULL); +} + + +/* + * 'index_compare()' - Compare two nodes. + */ + +static int /* O - Result of comparison */ +index_compare(mxml_index_t *ind, /* I - Index */ + mxml_node_t *first, /* I - First node */ + mxml_node_t *second) /* I - Second node */ +{ + int diff; /* Difference */ + + + /* + * Check the element name... + */ + + if ((diff = strcmp(first->value.element.name, + second->value.element.name)) != 0) + return (diff); + + /* + * Check the attribute value... + */ + + if (ind->attr) + { + if ((diff = strcmp(mxmlElementGetAttr(first, ind->attr), + mxmlElementGetAttr(second, ind->attr))) != 0) + return (diff); + } + + /* + * No difference, return 0... + */ + + return (0); +} + + +/* + * 'index_find()' - Compare a node with index values. + */ + +static int /* O - Result of comparison */ +index_find(mxml_index_t *ind, /* I - Index */ + const char *element, /* I - Element name or NULL */ + const char *value, /* I - Attribute value or NULL */ + mxml_node_t *node) /* I - Node */ +{ + int diff; /* Difference */ + + + /* + * Check the element name... + */ + + if (element) + { + if ((diff = strcmp(element, node->value.element.name)) != 0) + return (diff); + } + + /* + * Check the attribute value... + */ + + if (value) + { + if ((diff = strcmp(value, mxmlElementGetAttr(node, ind->attr))) != 0) + return (diff); + } + + /* + * No difference, return 0... + */ + + return (0); +} + + +/* + * 'index_sort()' - Sort the nodes in the index... + * + * This function implements the classic quicksort algorithm... + */ + +static void +index_sort(mxml_index_t *ind, /* I - Index to sort */ + int left, /* I - Left node in partition */ + int right) /* I - Right node in partition */ +{ + mxml_node_t *pivot, /* Pivot node */ + *temp; /* Swap node */ + int templ, /* Temporary left node */ + tempr; /* Temporary right node */ + + + /* + * Loop until we have sorted all the way to the right... + */ + + do + { + /* + * Sort the pivot in the current partition... + */ + + pivot = ind->nodes[left]; + + for (templ = left, tempr = right; templ < tempr;) + { + /* + * Move left while left node <= pivot node... + */ + + while ((templ < right) && + index_compare(ind, ind->nodes[templ], pivot) <= 0) + templ ++; + + /* + * Move right while right node > pivot node... + */ + + while ((tempr > left) && + index_compare(ind, ind->nodes[tempr], pivot) > 0) + tempr --; + + /* + * Swap nodes if needed... + */ + + if (templ < tempr) + { + temp = ind->nodes[templ]; + ind->nodes[templ] = ind->nodes[tempr]; + ind->nodes[tempr] = temp; + } + } + + /* + * When we get here, the right (tempr) node is the new position for the + * pivot node... + */ + + if (index_compare(ind, pivot, ind->nodes[tempr]) > 0) + { + ind->nodes[left] = ind->nodes[tempr]; + ind->nodes[tempr] = pivot; + } + + /* + * Recursively sort the left partition as needed... + */ + + if (left < (tempr - 1)) + index_sort(ind, left, tempr - 1); + } + while (right > (left = tempr + 1)); +} + + +/* + * End of "$Id: mxml-index.c 184 2005-01-29 07:21:44Z mike $". + */ diff --git a/plugins/zynaddsubfx/mxml/mxml-node.c b/plugins/zynaddsubfx/mxml/mxml-node.c new file mode 100644 index 000000000..56c30db05 --- /dev/null +++ b/plugins/zynaddsubfx/mxml/mxml-node.c @@ -0,0 +1,780 @@ +/* + * "$Id: mxml-node.c 270 2007-04-23 21:48:03Z mike $" + * + * Node support code for Mini-XML, a small XML-like file parsing library. + * + * Copyright 2003-2007 by Michael Sweet. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2, 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. + * + * Contents: + * + * mxmlAdd() - Add a node to a tree. + * mxmlDelete() - Delete a node and all of its children. + * mxmlNewCDATA() - Create a new CDATA node. + * mxmlNewCustom() - Create a new custom data node. + * mxmlNewElement() - Create a new element node. + * mxmlNewInteger() - Create a new integer node. + * mxmlNewOpaque() - Create a new opaque string. + * mxmlNewReal() - Create a new real number node. + * mxmlNewText() - Create a new text fragment node. + * mxmlNewTextf() - Create a new formatted text fragment node. + * mxmlNewXML() - Create a new XML document tree. + * mxmlRelease() - Release a node. + * mxmlRemove() - Remove a node from its parent. + * mxmlRetain() - Retain a node. + * mxml_new() - Create a new node. + */ + +/* + * Include necessary headers... + */ + +#include "mxml-config.h" +#include "mxml.h" + + +/* + * Local functions... + */ + +static mxml_node_t *mxml_new(mxml_node_t *parent, mxml_type_t type); + + +/* + * 'mxmlAdd()' - Add a node to a tree. + * + * Adds the specified node to the parent. If the child argument is not + * NULL, puts the new node before or after the specified child depending + * on the value of the where argument. If the child argument is NULL, + * puts the new node at the beginning of the child list (MXML_ADD_BEFORE) + * or at the end of the child list (MXML_ADD_AFTER). The constant + * MXML_ADD_TO_PARENT can be used to specify a NULL child pointer. + */ + +void +mxmlAdd(mxml_node_t *parent, /* I - Parent node */ + int where, /* I - Where to add, MXML_ADD_BEFORE or MXML_ADD_AFTER */ + mxml_node_t *child, /* I - Child node for where or MXML_ADD_TO_PARENT */ + mxml_node_t *node) /* I - Node to add */ +{ +#ifdef DEBUG + fprintf(stderr, "mxmlAdd(parent=%p, where=%d, child=%p, node=%p)\n", parent, + where, child, node); +#endif /* DEBUG */ + + /* + * Range check input... + */ + + if (!parent || !node) + return; + +#if DEBUG > 1 + fprintf(stderr, " BEFORE: node->parent=%p\n", node->parent); + if (parent) + { + fprintf(stderr, " BEFORE: parent->child=%p\n", parent->child); + fprintf(stderr, " BEFORE: parent->last_child=%p\n", parent->last_child); + fprintf(stderr, " BEFORE: parent->prev=%p\n", parent->prev); + fprintf(stderr, " BEFORE: parent->next=%p\n", parent->next); + } +#endif /* DEBUG > 1 */ + + /* + * Remove the node from any existing parent... + */ + + if (node->parent) + mxmlRemove(node); + + /* + * Reset pointers... + */ + + node->parent = parent; + + switch (where) + { + case MXML_ADD_BEFORE : + if (!child || child == parent->child || child->parent != parent) + { + /* + * Insert as first node under parent... + */ + + node->next = parent->child; + + if (parent->child) + parent->child->prev = node; + else + parent->last_child = node; + + parent->child = node; + } + else + { + /* + * Insert node before this child... + */ + + node->next = child; + node->prev = child->prev; + + if (child->prev) + child->prev->next = node; + else + parent->child = node; + + child->prev = node; + } + break; + + case MXML_ADD_AFTER : + if (!child || child == parent->last_child || child->parent != parent) + { + /* + * Insert as last node under parent... + */ + + node->parent = parent; + node->prev = parent->last_child; + + if (parent->last_child) + parent->last_child->next = node; + else + parent->child = node; + + parent->last_child = node; + } + else + { + /* + * Insert node after this child... + */ + + node->prev = child; + node->next = child->next; + + if (child->next) + child->next->prev = node; + else + parent->last_child = node; + + child->next = node; + } + break; + } + +#if DEBUG > 1 + fprintf(stderr, " AFTER: node->parent=%p\n", node->parent); + if (parent) + { + fprintf(stderr, " AFTER: parent->child=%p\n", parent->child); + fprintf(stderr, " AFTER: parent->last_child=%p\n", parent->last_child); + fprintf(stderr, " AFTER: parent->prev=%p\n", parent->prev); + fprintf(stderr, " AFTER: parent->next=%p\n", parent->next); + } +#endif /* DEBUG > 1 */ +} + + +/* + * 'mxmlDelete()' - Delete a node and all of its children. + * + * If the specified node has a parent, this function first removes the + * node from its parent using the mxmlRemove() function. + */ + +void +mxmlDelete(mxml_node_t *node) /* I - Node to delete */ +{ + int i; /* Looping var */ + + +#ifdef DEBUG + fprintf(stderr, "mxmlDelete(node=%p)\n", node); +#endif /* DEBUG */ + + /* + * Range check input... + */ + + if (!node) + return; + + /* + * Remove the node from its parent, if any... + */ + + mxmlRemove(node); + + /* + * Delete children... + */ + + while (node->child) + mxmlDelete(node->child); + + /* + * Now delete any node data... + */ + + switch (node->type) + { + case MXML_ELEMENT : + if (node->value.element.name) + free(node->value.element.name); + + if (node->value.element.num_attrs) + { + for (i = 0; i < node->value.element.num_attrs; i ++) + { + if (node->value.element.attrs[i].name) + free(node->value.element.attrs[i].name); + if (node->value.element.attrs[i].value) + free(node->value.element.attrs[i].value); + } + + free(node->value.element.attrs); + } + break; + case MXML_INTEGER : + /* Nothing to do */ + break; + case MXML_OPAQUE : + if (node->value.opaque) + free(node->value.opaque); + break; + case MXML_REAL : + /* Nothing to do */ + break; + case MXML_TEXT : + if (node->value.text.string) + free(node->value.text.string); + break; + case MXML_CUSTOM : + if (node->value.custom.data && + node->value.custom.destroy) + (*(node->value.custom.destroy))(node->value.custom.data); + break; + default : + break; + } + + /* + * Free this node... + */ + + free(node); +} + + +/* + * 'mxmlNewCDATA()' - Create a new CDATA node. + * + * The new CDATA node is added to the end of the specified parent's child + * list. The constant MXML_NO_PARENT can be used to specify that the new + * CDATA node has no parent. The data string must be nul-terminated and + * is copied into the new node. CDATA nodes use the MXML_ELEMENT type. + * + * @since Mini-XML 2.3@ + */ + +mxml_node_t * /* O - New node */ +mxmlNewCDATA(mxml_node_t *parent, /* I - Parent node or MXML_NO_PARENT */ + const char *data) /* I - Data string */ +{ + mxml_node_t *node; /* New node */ + + +#ifdef DEBUG + fprintf(stderr, "mxmlNewCDATA(parent=%p, data=\"%s\")\n", + parent, data ? data : "(null)"); +#endif /* DEBUG */ + + /* + * Range check input... + */ + + if (!data) + return (NULL); + + /* + * Create the node and set the name value... + */ + + if ((node = mxml_new(parent, MXML_ELEMENT)) != NULL) + node->value.element.name = _mxml_strdupf("![CDATA[%s]]", data); + + return (node); +} + + +/* + * 'mxmlNewCustom()' - Create a new custom data node. + * + * The new custom node is added to the end of the specified parent's child + * list. The constant MXML_NO_PARENT can be used to specify that the new + * element node has no parent. NULL can be passed when the data in the + * node is not dynamically allocated or is separately managed. + * + * @since Mini-XML 2.1@ + */ + +mxml_node_t * /* O - New node */ +mxmlNewCustom( + mxml_node_t *parent, /* I - Parent node or MXML_NO_PARENT */ + void *data, /* I - Pointer to data */ + mxml_custom_destroy_cb_t destroy) /* I - Function to destroy data */ +{ + mxml_node_t *node; /* New node */ + + +#ifdef DEBUG + fprintf(stderr, "mxmlNewCustom(parent=%p, data=%p, destroy=%p)\n", parent, + data, destroy); +#endif /* DEBUG */ + + /* + * Create the node and set the value... + */ + + if ((node = mxml_new(parent, MXML_CUSTOM)) != NULL) + { + node->value.custom.data = data; + node->value.custom.destroy = destroy; + } + + return (node); +} + + +/* + * 'mxmlNewElement()' - Create a new element node. + * + * The new element node is added to the end of the specified parent's child + * list. The constant MXML_NO_PARENT can be used to specify that the new + * element node has no parent. + */ + +mxml_node_t * /* O - New node */ +mxmlNewElement(mxml_node_t *parent, /* I - Parent node or MXML_NO_PARENT */ + const char *name) /* I - Name of element */ +{ + mxml_node_t *node; /* New node */ + + +#ifdef DEBUG + fprintf(stderr, "mxmlNewElement(parent=%p, name=\"%s\")\n", parent, + name ? name : "(null)"); +#endif /* DEBUG */ + + /* + * Range check input... + */ + + if (!name) + return (NULL); + + /* + * Create the node and set the element name... + */ + + if ((node = mxml_new(parent, MXML_ELEMENT)) != NULL) + node->value.element.name = strdup(name); + + return (node); +} + + +/* + * 'mxmlNewInteger()' - Create a new integer node. + * + * The new integer node is added to the end of the specified parent's child + * list. The constant MXML_NO_PARENT can be used to specify that the new + * integer node has no parent. + */ + +mxml_node_t * /* O - New node */ +mxmlNewInteger(mxml_node_t *parent, /* I - Parent node or MXML_NO_PARENT */ + int integer) /* I - Integer value */ +{ + mxml_node_t *node; /* New node */ + + +#ifdef DEBUG + fprintf(stderr, "mxmlNewInteger(parent=%p, integer=%d)\n", parent, integer); +#endif /* DEBUG */ + + /* + * Create the node and set the element name... + */ + + if ((node = mxml_new(parent, MXML_INTEGER)) != NULL) + node->value.integer = integer; + + return (node); +} + + +/* + * 'mxmlNewOpaque()' - Create a new opaque string. + * + * The new opaque node is added to the end of the specified parent's child + * list. The constant MXML_NO_PARENT can be used to specify that the new + * opaque node has no parent. The opaque string must be nul-terminated and + * is copied into the new node. + */ + +mxml_node_t * /* O - New node */ +mxmlNewOpaque(mxml_node_t *parent, /* I - Parent node or MXML_NO_PARENT */ + const char *opaque) /* I - Opaque string */ +{ + mxml_node_t *node; /* New node */ + + +#ifdef DEBUG + fprintf(stderr, "mxmlNewOpaque(parent=%p, opaque=\"%s\")\n", parent, + opaque ? opaque : "(null)"); +#endif /* DEBUG */ + + /* + * Range check input... + */ + + if (!opaque) + return (NULL); + + /* + * Create the node and set the element name... + */ + + if ((node = mxml_new(parent, MXML_OPAQUE)) != NULL) + node->value.opaque = strdup(opaque); + + return (node); +} + + +/* + * 'mxmlNewReal()' - Create a new real number node. + * + * The new real number node is added to the end of the specified parent's + * child list. The constant MXML_NO_PARENT can be used to specify that + * the new real number node has no parent. + */ + +mxml_node_t * /* O - New node */ +mxmlNewReal(mxml_node_t *parent, /* I - Parent node or MXML_NO_PARENT */ + double real) /* I - Real number value */ +{ + mxml_node_t *node; /* New node */ + + +#ifdef DEBUG + fprintf(stderr, "mxmlNewReal(parent=%p, real=%g)\n", parent, real); +#endif /* DEBUG */ + + /* + * Create the node and set the element name... + */ + + if ((node = mxml_new(parent, MXML_REAL)) != NULL) + node->value.real = real; + + return (node); +} + + +/* + * 'mxmlNewText()' - Create a new text fragment node. + * + * The new text node is added to the end of the specified parent's child + * list. The constant MXML_NO_PARENT can be used to specify that the new + * text node has no parent. The whitespace parameter is used to specify + * whether leading whitespace is present before the node. The text + * string must be nul-terminated and is copied into the new node. + */ + +mxml_node_t * /* O - New node */ +mxmlNewText(mxml_node_t *parent, /* I - Parent node or MXML_NO_PARENT */ + int whitespace, /* I - 1 = leading whitespace, 0 = no whitespace */ + const char *string) /* I - String */ +{ + mxml_node_t *node; /* New node */ + + +#ifdef DEBUG + fprintf(stderr, "mxmlNewText(parent=%p, whitespace=%d, string=\"%s\")\n", + parent, whitespace, string ? string : "(null)"); +#endif /* DEBUG */ + + /* + * Range check input... + */ + + if (!string) + return (NULL); + + /* + * Create the node and set the text value... + */ + + if ((node = mxml_new(parent, MXML_TEXT)) != NULL) + { + node->value.text.whitespace = whitespace; + node->value.text.string = strdup(string); + } + + return (node); +} + + +/* + * 'mxmlNewTextf()' - Create a new formatted text fragment node. + * + * The new text node is added to the end of the specified parent's child + * list. The constant MXML_NO_PARENT can be used to specify that the new + * text node has no parent. The whitespace parameter is used to specify + * whether leading whitespace is present before the node. The format + * string must be nul-terminated and is formatted into the new node. + */ + +mxml_node_t * /* O - New node */ +mxmlNewTextf(mxml_node_t *parent, /* I - Parent node or MXML_NO_PARENT */ + int whitespace, /* I - 1 = leading whitespace, 0 = no whitespace */ + const char *format, /* I - Printf-style frmat string */ + ...) /* I - Additional args as needed */ +{ + mxml_node_t *node; /* New node */ + va_list ap; /* Pointer to arguments */ + + +#ifdef DEBUG + fprintf(stderr, "mxmlNewTextf(parent=%p, whitespace=%d, format=\"%s\", ...)\n", + parent, whitespace, format ? format : "(null)"); +#endif /* DEBUG */ + + /* + * Range check input... + */ + + if (!format) + return (NULL); + + /* + * Create the node and set the text value... + */ + + if ((node = mxml_new(parent, MXML_TEXT)) != NULL) + { + va_start(ap, format); + + node->value.text.whitespace = whitespace; + node->value.text.string = _mxml_vstrdupf(format, ap); + + va_end(ap); + } + + return (node); +} + + +/* + * 'mxmlRemove()' - Remove a node from its parent. + * + * Does not free memory used by the node - use mxmlDelete() for that. + * This function does nothing if the node has no parent. + */ + +void +mxmlRemove(mxml_node_t *node) /* I - Node to remove */ +{ +#ifdef DEBUG + fprintf(stderr, "mxmlRemove(node=%p)\n", node); +#endif /* DEBUG */ + + /* + * Range check input... + */ + + if (!node || !node->parent) + return; + + /* + * Remove from parent... + */ + +#if DEBUG > 1 + fprintf(stderr, " BEFORE: node->parent=%p\n", node->parent); + if (node->parent) + { + fprintf(stderr, " BEFORE: node->parent->child=%p\n", node->parent->child); + fprintf(stderr, " BEFORE: node->parent->last_child=%p\n", node->parent->last_child); + } + fprintf(stderr, " BEFORE: node->child=%p\n", node->child); + fprintf(stderr, " BEFORE: node->last_child=%p\n", node->last_child); + fprintf(stderr, " BEFORE: node->prev=%p\n", node->prev); + fprintf(stderr, " BEFORE: node->next=%p\n", node->next); +#endif /* DEBUG > 1 */ + + if (node->prev) + node->prev->next = node->next; + else + node->parent->child = node->next; + + if (node->next) + node->next->prev = node->prev; + else + node->parent->last_child = node->prev; + + node->parent = NULL; + node->prev = NULL; + node->next = NULL; + +#if DEBUG > 1 + fprintf(stderr, " AFTER: node->parent=%p\n", node->parent); + if (node->parent) + { + fprintf(stderr, " AFTER: node->parent->child=%p\n", node->parent->child); + fprintf(stderr, " AFTER: node->parent->last_child=%p\n", node->parent->last_child); + } + fprintf(stderr, " AFTER: node->child=%p\n", node->child); + fprintf(stderr, " AFTER: node->last_child=%p\n", node->last_child); + fprintf(stderr, " AFTER: node->prev=%p\n", node->prev); + fprintf(stderr, " AFTER: node->next=%p\n", node->next); +#endif /* DEBUG > 1 */ +} + + +/* + * 'mxmlNewXML()' - Create a new XML document tree. + * + * The "version" argument specifies the version number to put in the + * ?xml element node. If NULL, version 1.0 is assumed. + * + * @since Mini-XML 2.3@ + */ + +mxml_node_t * /* O - New ?xml node */ +mxmlNewXML(const char *version) /* I - Version number to use */ +{ + char element[1024]; /* Element text */ + + + snprintf(element, sizeof(element), "?xml version=\"%s\"?", + version ? version : "1.0"); + + return (mxmlNewElement(NULL, element)); +} + + +/* + * 'mxmlRelease()' - Release a node. + * + * When the reference count reaches zero, the node (and any children) + * is deleted via mxmlDelete(). + * + * @since Mini-XML 2.3@ + */ + +int /* O - New reference count */ +mxmlRelease(mxml_node_t *node) /* I - Node */ +{ + if (node) + { + if ((-- node->ref_count) <= 0) + { + mxmlDelete(node); + return (0); + } + else + return (node->ref_count); + } + else + return (-1); +} + + +/* + * 'mxmlRetain()' - Retain a node. + * + * @since Mini-XML 2.3@ + */ + +int /* O - New reference count */ +mxmlRetain(mxml_node_t *node) /* I - Node */ +{ + if (node) + return (++ node->ref_count); + else + return (-1); +} + + +/* + * 'mxml_new()' - Create a new node. + */ + +static mxml_node_t * /* O - New node */ +mxml_new(mxml_node_t *parent, /* I - Parent node */ + mxml_type_t type) /* I - Node type */ +{ + mxml_node_t *node; /* New node */ + + +#if DEBUG > 1 + fprintf(stderr, "mxml_new(parent=%p, type=%d)\n", parent, type); +#endif /* DEBUG > 1 */ + + /* + * Allocate memory for the node... + */ + + if ((node = calloc(1, sizeof(mxml_node_t))) == NULL) + { +#if DEBUG > 1 + fputs(" returning NULL\n", stderr); +#endif /* DEBUG > 1 */ + + return (NULL); + } + +#if DEBUG > 1 + fprintf(stderr, " returning %p\n", node); +#endif /* DEBUG > 1 */ + + /* + * Set the node type... + */ + + node->type = type; + node->ref_count = 1; + + /* + * Add to the parent if present... + */ + + if (parent) + mxmlAdd(parent, MXML_ADD_AFTER, MXML_ADD_TO_PARENT, node); + + /* + * Return the new node... + */ + + return (node); +} + + +/* + * End of "$Id: mxml-node.c 270 2007-04-23 21:48:03Z mike $". + */ diff --git a/plugins/zynaddsubfx/mxml/mxml-private.c b/plugins/zynaddsubfx/mxml/mxml-private.c new file mode 100644 index 000000000..fa5258056 --- /dev/null +++ b/plugins/zynaddsubfx/mxml/mxml-private.c @@ -0,0 +1,285 @@ +/* + * "$Id: mxml-private.c 315 2007-11-22 18:01:52Z mike $" + * + * Private functions for Mini-XML, a small XML-like file parsing library. + * + * Copyright 2003-2007 by Michael Sweet. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2, 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. + * + * Contents: + * + * mxml_error() - Display an error message. + * mxml_integer_cb() - Default callback for integer values. + * mxml_opaque_cb() - Default callback for opaque values. + * mxml_real_cb() - Default callback for real number values. + * _mxml_global() - Get global data. + */ + +/* + * Include necessary headers... + */ + +#include "mxml-private.h" + + +/* + * 'mxml_error()' - Display an error message. + */ + +void +mxml_error(const char *format, /* I - Printf-style format string */ + ...) /* I - Additional arguments as needed */ +{ + va_list ap; /* Pointer to arguments */ + char s[1024]; /* Message string */ + _mxml_global_t *global = _mxml_global(); + /* Global data */ + + + /* + * Range check input... + */ + + if (!format) + return; + + /* + * Format the error message string... + */ + + va_start(ap, format); + + vsnprintf(s, sizeof(s), format, ap); + + va_end(ap); + + /* + * And then display the error message... + */ + + if (global->error_cb) + (*global->error_cb)(s); + else + fprintf(stderr, "mxml: %s\n", s); +} + + +/* + * 'mxml_ignore_cb()' - Default callback for ignored values. + */ + +mxml_type_t /* O - Node type */ +mxml_ignore_cb(mxml_node_t *node) /* I - Current node */ +{ + (void)node; + + return (MXML_IGNORE); +} + + +/* + * 'mxml_integer_cb()' - Default callback for integer values. + */ + +mxml_type_t /* O - Node type */ +mxml_integer_cb(mxml_node_t *node) /* I - Current node */ +{ + (void)node; + + return (MXML_INTEGER); +} + + +/* + * 'mxml_opaque_cb()' - Default callback for opaque values. + */ + +mxml_type_t /* O - Node type */ +mxml_opaque_cb(mxml_node_t *node) /* I - Current node */ +{ + (void)node; + + return (MXML_OPAQUE); +} + + +/* + * 'mxml_real_cb()' - Default callback for real number values. + */ + +mxml_type_t /* O - Node type */ +mxml_real_cb(mxml_node_t *node) /* I - Current node */ +{ + (void)node; + + return (MXML_REAL); +} + + +#ifdef HAVE_PTHREAD_H /**** POSIX threading ****/ +# include + +static pthread_key_t _mxml_key = -1; /* Thread local storage key */ +static pthread_once_t _mxml_key_once = PTHREAD_ONCE_INIT; + /* One-time initialization object */ +static void _mxml_init(void); +static void _mxml_destructor(void *g); + + +/* + * '_mxml_global()' - Get global data. + */ + +_mxml_global_t * /* O - Global data */ +_mxml_global(void) +{ + _mxml_global_t *global; /* Global data */ + + + pthread_once(&_mxml_key_once, _mxml_init); + + if ((global = (_mxml_global_t *)pthread_getspecific(_mxml_key)) == NULL) + { + global = (_mxml_global_t *)calloc(1, sizeof(_mxml_global_t)); + pthread_setspecific(_mxml_key, global); + + global->num_entity_cbs = 1; + global->entity_cbs[0] = _mxml_entity_cb; + global->wrap = 72; + } + + return (global); +} + + +/* + * '_mxml_init()' - Initialize global data... + */ + +static void +_mxml_init(void) +{ + pthread_key_create(&_mxml_key, _mxml_destructor); +} + + +/* + * '_mxml_destructor()' - Free memory used for globals... + */ + +static void +_mxml_destructor(void *g) /* I - Global data */ +{ + free(g); +} + + +#elif defined(WIN32) /**** WIN32 threading ****/ +# include + +static DWORD _mxml_tls_index; /* Index for global storage */ + + +/* + * 'DllMain()' - Main entry for library. + */ + +BOOL WINAPI /* O - Success/failure */ +DllMain(HINSTANCE hinst, /* I - DLL module handle */ + DWORD reason, /* I - Reason */ + LPVOID reserved) /* I - Unused */ +{ + _mxml_global_t *global; /* Global data */ + + + (void)hinst; + (void)reserved; + + switch (reason) + { + case DLL_PROCESS_ATTACH : /* Called on library initialization */ + if ((_mxml_tls_index = TlsAlloc()) == TLS_OUT_OF_INDEXES) + return (FALSE); + break; + + case DLL_THREAD_DETACH : /* Called when a thread terminates */ + if ((global = (_mxml_global_t *)TlsGetValue(_mxml_tls_index)) != NULL) + free(global); + break; + + case DLL_PROCESS_DETACH : /* Called when library is unloaded */ + if ((global = (_mxml_global_t *)TlsGetValue(_mxml_tls_index)) != NULL) + free(global); + + TlsFree(_mxml_tls_index); + break; + + default: + break; + } + + return (TRUE); +} + + +/* + * '_mxml_global()' - Get global data. + */ + +_mxml_global_t * /* O - Global data */ +_mxml_global(void) +{ + _mxml_global_t *global; /* Global data */ + + + if ((global = (_mxml_global_t *)TlsGetValue(_mxml_tls_index)) == NULL) + { + global = (_mxml_global_t *)calloc(1, sizeof(_mxml_global_t)); + + global->num_entity_cbs = 1; + global->entity_cbs[0] = _mxml_entity_cb; + global->wrap = 72; + + TlsSetValue(_mxml_tls_index, (LPVOID)global); + } + + return (global); +} + + +#else /**** No threading ****/ +/* + * '_mxml_global()' - Get global data. + */ + +_mxml_global_t * /* O - Global data */ +_mxml_global(void) +{ + static _mxml_global_t global = /* Global data */ + { + NULL, /* error_cb */ + 1, /* num_entity_cbs */ + { _mxml_entity_cb }, /* entity_cbs */ + 72, /* wrap */ + NULL, /* custom_load_cb */ + NULL /* custom_save_cb */ + }; + + + return (&global); +} +#endif /* HAVE_PTHREAD_H */ + + +/* + * End of "$Id: mxml-private.c 315 2007-11-22 18:01:52Z mike $". + */ diff --git a/plugins/zynaddsubfx/mxml/mxml-private.h b/plugins/zynaddsubfx/mxml/mxml-private.h new file mode 100644 index 000000000..82deb67cd --- /dev/null +++ b/plugins/zynaddsubfx/mxml/mxml-private.h @@ -0,0 +1,52 @@ +/* + * "$Id: mxml-private.h 309 2007-09-21 04:46:02Z mike $" + * + * Private definitions for Mini-XML, a small XML-like file parsing library. + * + * Copyright 2007 by Michael Sweet. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2, 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. + */ + +/* + * Include necessary headers... + */ + +#include "mxml-config.h" +#include "mxml.h" + + +/* + * Global, per-thread data... + */ + +typedef struct _mxml_global_s +{ + void (*error_cb)(const char *); + int num_entity_cbs; + int (*entity_cbs[100])(const char *name); + int wrap; + mxml_custom_load_cb_t custom_load_cb; + mxml_custom_save_cb_t custom_save_cb; +} _mxml_global_t; + + +/* + * Functions... + */ + +extern _mxml_global_t *_mxml_global(void); +extern int _mxml_entity_cb(const char *name); + + +/* + * End of "$Id: mxml-private.h 309 2007-09-21 04:46:02Z mike $". + */ diff --git a/plugins/zynaddsubfx/mxml/mxml-search.c b/plugins/zynaddsubfx/mxml/mxml-search.c new file mode 100644 index 000000000..72b24484e --- /dev/null +++ b/plugins/zynaddsubfx/mxml/mxml-search.c @@ -0,0 +1,201 @@ +/* + * "$Id: mxml-search.c 297 2007-09-09 07:16:52Z mike $" + * + * Search/navigation functions for Mini-XML, a small XML-like file + * parsing library. + * + * Copyright 2003-2007 by Michael Sweet. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2, 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. + * + * Contents: + * + * mxmlFindElement() - Find the named element. + * mxmlWalkNext() - Walk to the next logical node in the tree. + * mxmlWalkPrev() - Walk to the previous logical node in the tree. + */ + +/* + * Include necessary headers... + */ + +#include "mxml-config.h" +#include "mxml.h" + + +/* + * 'mxmlFindElement()' - Find the named element. + * + * The search is constrained by the name, attribute name, and value; any + * NULL names or values are treated as wildcards, so different kinds of + * searches can be implemented by looking for all elements of a given name + * or all elements with a specific attribute. The descend argument determines + * whether the search descends into child nodes; normally you will use + * MXML_DESCEND_FIRST for the initial search and MXML_NO_DESCEND to find + * additional direct descendents of the node. The top node argument + * constrains the search to a particular node's children. + */ + +mxml_node_t * /* O - Element node or NULL */ +mxmlFindElement(mxml_node_t *node, /* I - Current node */ + mxml_node_t *top, /* I - Top node */ + const char *name, /* I - Element name or NULL for any */ + const char *attr, /* I - Attribute name, or NULL for none */ + const char *value, /* I - Attribute value, or NULL for any */ + int descend) /* I - Descend into tree - MXML_DESCEND, MXML_NO_DESCEND, or MXML_DESCEND_FIRST */ +{ + const char *temp; /* Current attribute value */ + + + /* + * Range check input... + */ + + if (!node || !top || (!attr && value)) + return (NULL); + + /* + * Start with the next node... + */ + + node = mxmlWalkNext(node, top, descend); + + /* + * Loop until we find a matching element... + */ + + while (node != NULL) + { + /* + * See if this node matches... + */ + + if (node->type == MXML_ELEMENT && + node->value.element.name && + (!name || !strcmp(node->value.element.name, name))) + { + /* + * See if we need to check for an attribute... + */ + + if (!attr) + return (node); /* No attribute search, return it... */ + + /* + * Check for the attribute... + */ + + if ((temp = mxmlElementGetAttr(node, attr)) != NULL) + { + /* + * OK, we have the attribute, does it match? + */ + + if (!value || !strcmp(value, temp)) + return (node); /* Yes, return it... */ + } + } + + /* + * No match, move on to the next node... + */ + + if (descend == MXML_DESCEND) + node = mxmlWalkNext(node, top, MXML_DESCEND); + else + node = node->next; + } + + return (NULL); +} + + +/* + * 'mxmlWalkNext()' - Walk to the next logical node in the tree. + * + * The descend argument controls whether the first child is considered + * to be the next node. The top node argument constrains the walk to + * the node's children. + */ + +mxml_node_t * /* O - Next node or NULL */ +mxmlWalkNext(mxml_node_t *node, /* I - Current node */ + mxml_node_t *top, /* I - Top node */ + int descend) /* I - Descend into tree - MXML_DESCEND, MXML_NO_DESCEND, or MXML_DESCEND_FIRST */ +{ + if (!node) + return (NULL); + else if (node->child && descend) + return (node->child); + else if (node == top) + return (NULL); + else if (node->next) + return (node->next); + else if (node->parent && node->parent != top) + { + node = node->parent; + + while (!node->next) + if (node->parent == top || !node->parent) + return (NULL); + else + node = node->parent; + + return (node->next); + } + else + return (NULL); +} + + +/* + * 'mxmlWalkPrev()' - Walk to the previous logical node in the tree. + * + * The descend argument controls whether the previous node's last child + * is considered to be the previous node. The top node argument constrains + * the walk to the node's children. + */ + +mxml_node_t * /* O - Previous node or NULL */ +mxmlWalkPrev(mxml_node_t *node, /* I - Current node */ + mxml_node_t *top, /* I - Top node */ + int descend) /* I - Descend into tree - MXML_DESCEND, MXML_NO_DESCEND, or MXML_DESCEND_FIRST */ +{ + if (!node || node == top) + return (NULL); + else if (node->prev) + { + if (node->prev->last_child && descend) + { + /* + * Find the last child under the previous node... + */ + + node = node->prev->last_child; + + while (node->last_child) + node = node->last_child; + + return (node); + } + else + return (node->prev); + } + else if (node->parent != top) + return (node->parent); + else + return (NULL); +} + + +/* + * End of "$Id: mxml-search.c 297 2007-09-09 07:16:52Z mike $". + */ diff --git a/plugins/zynaddsubfx/mxml/mxml-set.c b/plugins/zynaddsubfx/mxml/mxml-set.c new file mode 100644 index 000000000..788004bf4 --- /dev/null +++ b/plugins/zynaddsubfx/mxml/mxml-set.c @@ -0,0 +1,294 @@ +/* + * "$Id: mxml-set.c 270 2007-04-23 21:48:03Z mike $" + * + * Node set functions for Mini-XML, a small XML-like file parsing library. + * + * Copyright 2003-2007 by Michael Sweet. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2, 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. + * + * Contents: + * + * mxmlSetCustom() - Set the data and destructor of a custom data node. + * mxmlSetCDATA() - Set the element name of a CDATA node. + * mxmlSetElement() - Set the name of an element node. + * mxmlSetInteger() - Set the value of an integer node. + * mxmlSetOpaque() - Set the value of an opaque node. + * mxmlSetReal() - Set the value of a real number node. + * mxmlSetText() - Set the value of a text node. + * mxmlSetTextf() - Set the value of a text node to a formatted string. + */ + +/* + * Include necessary headers... + */ + +#include "mxml-config.h" +#include "mxml.h" + + +/* + * 'mxmlSetCustom()' - Set the data and destructor of a custom data node. + * + * The node is not changed if it is not a custom node. + * + * @since Mini-XML 2.1@ + */ + +int /* O - 0 on success, -1 on failure */ +mxmlSetCustom( + mxml_node_t *node, /* I - Node to set */ + void *data, /* I - New data pointer */ + mxml_custom_destroy_cb_t destroy) /* I - New destructor function */ +{ + /* + * Range check input... + */ + + if (!node || node->type != MXML_CUSTOM) + return (-1); + + /* + * Free any old element value and set the new value... + */ + + if (node->value.custom.data && node->value.custom.destroy) + (*(node->value.custom.destroy))(node->value.custom.data); + + node->value.custom.data = data; + node->value.custom.destroy = destroy; + + return (0); +} + + +/* + * 'mxmlSetCDATA()' - Set the element name of a CDATA node. + * + * The node is not changed if it is not a CDATA element node. + * + * @since Mini-XML 2.3@ + */ + +int /* O - 0 on success, -1 on failure */ +mxmlSetCDATA(mxml_node_t *node, /* I - Node to set */ + const char *data) /* I - New data string */ +{ + /* + * Range check input... + */ + + if (!node || node->type != MXML_ELEMENT || !data || + strncmp(node->value.element.name, "![CDATA[", 8)) + return (-1); + + /* + * Free any old element value and set the new value... + */ + + if (node->value.element.name) + free(node->value.element.name); + + node->value.element.name = _mxml_strdupf("![CDATA[%s]]", data); + + return (0); +} + + +/* + * 'mxmlSetElement()' - Set the name of an element node. + * + * The node is not changed if it is not an element node. + */ + +int /* O - 0 on success, -1 on failure */ +mxmlSetElement(mxml_node_t *node, /* I - Node to set */ + const char *name) /* I - New name string */ +{ + /* + * Range check input... + */ + + if (!node || node->type != MXML_ELEMENT || !name) + return (-1); + + /* + * Free any old element value and set the new value... + */ + + if (node->value.element.name) + free(node->value.element.name); + + node->value.element.name = strdup(name); + + return (0); +} + + +/* + * 'mxmlSetInteger()' - Set the value of an integer node. + * + * The node is not changed if it is not an integer node. + */ + +int /* O - 0 on success, -1 on failure */ +mxmlSetInteger(mxml_node_t *node, /* I - Node to set */ + int integer) /* I - Integer value */ +{ + /* + * Range check input... + */ + + if (!node || node->type != MXML_INTEGER) + return (-1); + + /* + * Set the new value and return... + */ + + node->value.integer = integer; + + return (0); +} + + +/* + * 'mxmlSetOpaque()' - Set the value of an opaque node. + * + * The node is not changed if it is not an opaque node. + */ + +int /* O - 0 on success, -1 on failure */ +mxmlSetOpaque(mxml_node_t *node, /* I - Node to set */ + const char *opaque) /* I - Opaque string */ +{ + /* + * Range check input... + */ + + if (!node || node->type != MXML_OPAQUE || !opaque) + return (-1); + + /* + * Free any old opaque value and set the new value... + */ + + if (node->value.opaque) + free(node->value.opaque); + + node->value.opaque = strdup(opaque); + + return (0); +} + + +/* + * 'mxmlSetReal()' - Set the value of a real number node. + * + * The node is not changed if it is not a real number node. + */ + +int /* O - 0 on success, -1 on failure */ +mxmlSetReal(mxml_node_t *node, /* I - Node to set */ + double real) /* I - Real number value */ +{ + /* + * Range check input... + */ + + if (!node || node->type != MXML_REAL) + return (-1); + + /* + * Set the new value and return... + */ + + node->value.real = real; + + return (0); +} + + +/* + * 'mxmlSetText()' - Set the value of a text node. + * + * The node is not changed if it is not a text node. + */ + +int /* O - 0 on success, -1 on failure */ +mxmlSetText(mxml_node_t *node, /* I - Node to set */ + int whitespace, /* I - 1 = leading whitespace, 0 = no whitespace */ + const char *string) /* I - String */ +{ + /* + * Range check input... + */ + + if (!node || node->type != MXML_TEXT || !string) + return (-1); + + /* + * Free any old string value and set the new value... + */ + + if (node->value.text.string) + free(node->value.text.string); + + node->value.text.whitespace = whitespace; + node->value.text.string = strdup(string); + + return (0); +} + + +/* + * 'mxmlSetTextf()' - Set the value of a text node to a formatted string. + * + * The node is not changed if it is not a text node. + */ + +int /* O - 0 on success, -1 on failure */ +mxmlSetTextf(mxml_node_t *node, /* I - Node to set */ + int whitespace, /* I - 1 = leading whitespace, 0 = no whitespace */ + const char *format, /* I - Printf-style format string */ + ...) /* I - Additional arguments as needed */ +{ + va_list ap; /* Pointer to arguments */ + + + /* + * Range check input... + */ + + if (!node || node->type != MXML_TEXT || !format) + return (-1); + + /* + * Free any old string value and set the new value... + */ + + if (node->value.text.string) + free(node->value.text.string); + + va_start(ap, format); + + node->value.text.whitespace = whitespace; + node->value.text.string = _mxml_strdupf(format, ap); + + va_end(ap); + + return (0); +} + + +/* + * End of "$Id: mxml-set.c 270 2007-04-23 21:48:03Z mike $". + */ diff --git a/plugins/zynaddsubfx/mxml/mxml-string.c b/plugins/zynaddsubfx/mxml/mxml-string.c new file mode 100644 index 000000000..7cb30e399 --- /dev/null +++ b/plugins/zynaddsubfx/mxml/mxml-string.c @@ -0,0 +1,457 @@ +/* + * "$Id: mxml-string.c 312 2007-10-03 06:25:07Z mike $" + * + * String functions for Mini-XML, a small XML-like file parsing library. + * + * Copyright 2003-2007 by Michael Sweet. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2, 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. + * + * Contents: + * + * _mxml_snprintf() - Format a string. + * _mxml_strdup() - Duplicate a string. + * _mxml_strdupf() - Format and duplicate a string. + * _mxml_vsnprintf() - Format a string into a fixed size buffer. + * _mxml_vstrdupf() - Format and duplicate a string. + */ + +/* + * Include necessary headers... + */ + +#include "mxml-config.h" + + +#ifndef HAVE_SNPRINTF +/* + * '_mxml_snprintf()' - Format a string. + */ + +int /* O - Number of bytes formatted */ +_mxml_snprintf(char *buffer, /* I - Output buffer */ + size_t bufsize, /* I - Size of output buffer */ + const char *format, /* I - Printf-style format string */ + ...) /* I - Additional arguments as needed */ +{ + va_list ap; /* Argument list */ + int bytes; /* Number of bytes formatted */ + + + va_start(ap, format); + bytes = vsnprintf(buffer, bufsize, format, ap); + va_end(ap); + + return (bytes); +} +#endif /* !HAVE_SNPRINTF */ + + +/* + * '_mxml_strdup()' - Duplicate a string. + */ + +#ifndef HAVE_STRDUP +char * /* O - New string pointer */ +_mxml_strdup(const char *s) /* I - String to duplicate */ +{ + char *t; /* New string pointer */ + + + if (s == NULL) + return (NULL); + + if ((t = malloc(strlen(s) + 1)) == NULL) + return (NULL); + + return (strcpy(t, s)); +} +#endif /* !HAVE_STRDUP */ + + +/* + * '_mxml_strdupf()' - Format and duplicate a string. + */ + +char * /* O - New string pointer */ +_mxml_strdupf(const char *format, /* I - Printf-style format string */ + ...) /* I - Additional arguments as needed */ +{ + va_list ap; /* Pointer to additional arguments */ + char *s; /* Pointer to formatted string */ + + + /* + * Get a pointer to the additional arguments, format the string, + * and return it... + */ + + va_start(ap, format); + s = _mxml_vstrdupf(format, ap); + va_end(ap); + + return (s); +} + + +#ifndef HAVE_VSNPRINTF +/* + * '_mxml_vsnprintf()' - Format a string into a fixed size buffer. + */ + +int /* O - Number of bytes formatted */ +_mxml_vsnprintf(char *buffer, /* O - Output buffer */ + size_t bufsize, /* O - Size of output buffer */ + const char *format, /* I - Printf-style format string */ + va_list ap) /* I - Pointer to additional arguments */ +{ + char *bufptr, /* Pointer to position in buffer */ + *bufend, /* Pointer to end of buffer */ + sign, /* Sign of format width */ + size, /* Size character (h, l, L) */ + type; /* Format type character */ + int width, /* Width of field */ + prec; /* Number of characters of precision */ + char tformat[100], /* Temporary format string for sprintf() */ + *tptr, /* Pointer into temporary format */ + temp[1024]; /* Buffer for formatted numbers */ + char *s; /* Pointer to string */ + int slen; /* Length of string */ + int bytes; /* Total number of bytes needed */ + + + /* + * Loop through the format string, formatting as needed... + */ + + bufptr = buffer; + bufend = buffer + bufsize - 1; + bytes = 0; + + while (*format) + { + if (*format == '%') + { + tptr = tformat; + *tptr++ = *format++; + + if (*format == '%') + { + if (bufptr && bufptr < bufend) *bufptr++ = *format; + bytes ++; + format ++; + continue; + } + else if (strchr(" -+#\'", *format)) + { + *tptr++ = *format; + sign = *format++; + } + else + sign = 0; + + if (*format == '*') + { + /* + * Get width from argument... + */ + + format ++; + width = va_arg(ap, int); + + snprintf(tptr, sizeof(tformat) - (tptr - tformat), "%d", width); + tptr += strlen(tptr); + } + else + { + width = 0; + + while (isdigit(*format & 255)) + { + if (tptr < (tformat + sizeof(tformat) - 1)) + *tptr++ = *format; + + width = width * 10 + *format++ - '0'; + } + } + + if (*format == '.') + { + if (tptr < (tformat + sizeof(tformat) - 1)) + *tptr++ = *format; + + format ++; + + if (*format == '*') + { + /* + * Get precision from argument... + */ + + format ++; + prec = va_arg(ap, int); + + snprintf(tptr, sizeof(tformat) - (tptr - tformat), "%d", prec); + tptr += strlen(tptr); + } + else + { + prec = 0; + + while (isdigit(*format & 255)) + { + if (tptr < (tformat + sizeof(tformat) - 1)) + *tptr++ = *format; + + prec = prec * 10 + *format++ - '0'; + } + } + } + else + prec = -1; + + if (*format == 'l' && format[1] == 'l') + { + size = 'L'; + + if (tptr < (tformat + sizeof(tformat) - 2)) + { + *tptr++ = 'l'; + *tptr++ = 'l'; + } + + format += 2; + } + else if (*format == 'h' || *format == 'l' || *format == 'L') + { + if (tptr < (tformat + sizeof(tformat) - 1)) + *tptr++ = *format; + + size = *format++; + } + + if (!*format) + break; + + if (tptr < (tformat + sizeof(tformat) - 1)) + *tptr++ = *format; + + type = *format++; + *tptr = '\0'; + + switch (type) + { + case 'E' : /* Floating point formats */ + case 'G' : + case 'e' : + case 'f' : + case 'g' : + if ((width + 2) > sizeof(temp)) + break; + + sprintf(temp, tformat, va_arg(ap, double)); + + bytes += strlen(temp); + + if (bufptr) + { + if ((bufptr + strlen(temp)) > bufend) + { + strncpy(bufptr, temp, (size_t)(bufend - bufptr)); + bufptr = bufend; + } + else + { + strcpy(bufptr, temp); + bufptr += strlen(temp); + } + } + break; + + case 'B' : /* Integer formats */ + case 'X' : + case 'b' : + case 'd' : + case 'i' : + case 'o' : + case 'u' : + case 'x' : + if ((width + 2) > sizeof(temp)) + break; + + sprintf(temp, tformat, va_arg(ap, int)); + + bytes += strlen(temp); + + if (bufptr) + { + if ((bufptr + strlen(temp)) > bufend) + { + strncpy(bufptr, temp, (size_t)(bufend - bufptr)); + bufptr = bufend; + } + else + { + strcpy(bufptr, temp); + bufptr += strlen(temp); + } + } + break; + + case 'p' : /* Pointer value */ + if ((width + 2) > sizeof(temp)) + break; + + sprintf(temp, tformat, va_arg(ap, void *)); + + bytes += strlen(temp); + + if (bufptr) + { + if ((bufptr + strlen(temp)) > bufend) + { + strncpy(bufptr, temp, (size_t)(bufend - bufptr)); + bufptr = bufend; + } + else + { + strcpy(bufptr, temp); + bufptr += strlen(temp); + } + } + break; + + case 'c' : /* Character or character array */ + bytes += width; + + if (bufptr) + { + if (width <= 1) + *bufptr++ = va_arg(ap, int); + else + { + if ((bufptr + width) > bufend) + width = bufend - bufptr; + + memcpy(bufptr, va_arg(ap, char *), (size_t)width); + bufptr += width; + } + } + break; + + case 's' : /* String */ + if ((s = va_arg(ap, char *)) == NULL) + s = "(null)"; + + slen = strlen(s); + if (slen > width && prec != width) + width = slen; + + bytes += width; + + if (bufptr) + { + if ((bufptr + width) > bufend) + width = bufend - bufptr; + + if (slen > width) + slen = width; + + if (sign == '-') + { + strncpy(bufptr, s, (size_t)slen); + memset(bufptr + slen, ' ', (size_t)(width - slen)); + } + else + { + memset(bufptr, ' ', (size_t)(width - slen)); + strncpy(bufptr + width - slen, s, (size_t)slen); + } + + bufptr += width; + } + break; + + case 'n' : /* Output number of chars so far */ + *(va_arg(ap, int *)) = bytes; + break; + } + } + else + { + bytes ++; + + if (bufptr && bufptr < bufend) + *bufptr++ = *format; + + format ++; + } + } + + /* + * Nul-terminate the string and return the number of characters needed. + */ + + *bufptr = '\0'; + + return (bytes); +} +#endif /* !HAVE_VSNPRINTF */ + + +/* + * '_mxml_vstrdupf()' - Format and duplicate a string. + */ + +char * /* O - New string pointer */ +_mxml_vstrdupf(const char *format, /* I - Printf-style format string */ + va_list ap) /* I - Pointer to additional arguments */ +{ + int bytes; /* Number of bytes required */ + char *buffer, /* String buffer */ + temp[256]; /* Small buffer for first vsnprintf */ + + + /* + * First format with a tiny buffer; this will tell us how many bytes are + * needed... + */ + + bytes = vsnprintf(temp, sizeof(temp), format, ap); + + if (bytes < sizeof(temp)) + { + /* + * Hey, the formatted string fits in the tiny buffer, so just dup that... + */ + + return (strdup(temp)); + } + + /* + * Allocate memory for the whole thing and reformat to the new, larger + * buffer... + */ + + if ((buffer = calloc(1, bytes + 1)) != NULL) + vsnprintf(buffer, bytes + 1, format, ap); + + /* + * Return the new string... + */ + + return (buffer); +} + + +/* + * End of "$Id: mxml-string.c 312 2007-10-03 06:25:07Z mike $". + */ diff --git a/plugins/zynaddsubfx/mxml/mxml.h b/plugins/zynaddsubfx/mxml/mxml.h new file mode 100644 index 000000000..0b7d7d245 --- /dev/null +++ b/plugins/zynaddsubfx/mxml/mxml.h @@ -0,0 +1,305 @@ +/* + * "$Id: mxml.h 307 2007-09-15 20:03:15Z mike $" + * + * Header file for Mini-XML, a small XML-like file parsing library. + * + * Copyright 2003-2007 by Michael Sweet. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2, 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. + */ + +/* + * Prevent multiple inclusion... + */ + +#ifndef _mxml_h_ +# define _mxml_h_ + +/* + * Include necessary headers... + */ + +# include +# include +# include +# include +# include + + +/* + * Constants... + */ + +# define MXML_TAB 8 /* Tabs every N columns */ + +# define MXML_NO_CALLBACK 0 /* Don't use a type callback */ +# define MXML_INTEGER_CALLBACK mxml_integer_cb + /* Treat all data as integers */ +# define MXML_OPAQUE_CALLBACK mxml_opaque_cb + /* Treat all data as opaque */ +# define MXML_REAL_CALLBACK mxml_real_cb + /* Treat all data as real numbers */ +# define MXML_TEXT_CALLBACK 0 /* Treat all data as text */ +# define MXML_IGNORE_CALLBACK mxml_ignore_cb + /* Ignore all non-element content */ + +# define MXML_NO_PARENT 0 /* No parent for the node */ + +# define MXML_DESCEND 1 /* Descend when finding/walking */ +# define MXML_NO_DESCEND 0 /* Don't descend when finding/walking */ +# define MXML_DESCEND_FIRST -1 /* Descend for first find */ + +# define MXML_WS_BEFORE_OPEN 0 /* Callback for before open tag */ +# define MXML_WS_AFTER_OPEN 1 /* Callback for after open tag */ +# define MXML_WS_BEFORE_CLOSE 2 /* Callback for before close tag */ +# define MXML_WS_AFTER_CLOSE 3 /* Callback for after close tag */ + +# define MXML_ADD_BEFORE 0 /* Add node before specified node */ +# define MXML_ADD_AFTER 1 /* Add node after specified node */ +# define MXML_ADD_TO_PARENT NULL /* Add node relative to parent */ + + +/* + * Data types... + */ + +typedef enum mxml_sax_event_e /**** SAX event type. ****/ +{ + MXML_SAX_CDATA, /* CDATA node */ + MXML_SAX_COMMENT, /* Comment node */ + MXML_SAX_DATA, /* Data node */ + MXML_SAX_DIRECTIVE, /* Processing directive node */ + MXML_SAX_ELEMENT_CLOSE, /* Element closed */ + MXML_SAX_ELEMENT_OPEN /* Element opened */ +} mxml_sax_event_t; + +typedef enum mxml_type_e /**** The XML node type. ****/ +{ + MXML_IGNORE = -1, /* Ignore/throw away node @since Mini-XML 2.3@ */ + MXML_ELEMENT, /* XML element with attributes */ + MXML_INTEGER, /* Integer value */ + MXML_OPAQUE, /* Opaque string */ + MXML_REAL, /* Real value */ + MXML_TEXT, /* Text fragment */ + MXML_CUSTOM /* Custom data @since Mini-XML 2.1@ */ +} mxml_type_t; + +typedef void (*mxml_custom_destroy_cb_t)(void *); + /**** Custom data destructor ****/ + +typedef void (*mxml_error_cb_t)(const char *); + /**** Error callback function ****/ + +typedef struct mxml_attr_s /**** An XML element attribute value. ****/ +{ + char *name; /* Attribute name */ + char *value; /* Attribute value */ +} mxml_attr_t; + +typedef struct mxml_element_s /**** An XML element value. ****/ +{ + char *name; /* Name of element */ + int num_attrs; /* Number of attributes */ + mxml_attr_t *attrs; /* Attributes */ +} mxml_element_t; + +typedef struct mxml_text_s /**** An XML text value. ****/ +{ + int whitespace; /* Leading whitespace? */ + char *string; /* Fragment string */ +} mxml_text_t; + +typedef struct mxml_custom_s /**** An XML custom value. @since Mini-XML 2.1@ ****/ +{ + void *data; /* Pointer to (allocated) custom data */ + mxml_custom_destroy_cb_t destroy; /* Pointer to destructor function */ +} mxml_custom_t; + +typedef union mxml_value_u /**** An XML node value. ****/ +{ + mxml_element_t element; /* Element */ + int integer; /* Integer number */ + char *opaque; /* Opaque string */ + double real; /* Real number */ + mxml_text_t text; /* Text fragment */ + mxml_custom_t custom; /* Custom data @since Mini-XML 2.1@ */ +} mxml_value_t; + +typedef struct mxml_node_s /**** An XML node. ****/ +{ + mxml_type_t type; /* Node type */ + struct mxml_node_s *next; /* Next node under same parent */ + struct mxml_node_s *prev; /* Previous node under same parent */ + struct mxml_node_s *parent; /* Parent node */ + struct mxml_node_s *child; /* First child node */ + struct mxml_node_s *last_child; /* Last child node */ + mxml_value_t value; /* Node value */ + int ref_count; /* Use count */ + void *user_data; /* User data */ +} mxml_node_t; + +typedef struct mxml_index_s /**** An XML node index. ****/ +{ + char *attr; /* Attribute used for indexing or NULL */ + int num_nodes; /* Number of nodes in index */ + int alloc_nodes; /* Allocated nodes in index */ + int cur_node; /* Current node */ + mxml_node_t **nodes; /* Node array */ +} mxml_index_t; + +typedef int (*mxml_custom_load_cb_t)(mxml_node_t *, const char *); + /**** Custom data load callback function ****/ + +typedef char *(*mxml_custom_save_cb_t)(mxml_node_t *); + /**** Custom data save callback function ****/ + +typedef mxml_type_t (*mxml_load_cb_t)(mxml_node_t *); + /**** Load callback function ****/ + +typedef const char *(*mxml_save_cb_t)(mxml_node_t *, int); + /**** Save callback function ****/ + +typedef void (*mxml_sax_cb_t)(mxml_node_t *, mxml_sax_event_t, void *); + /**** SAX callback function ****/ + + +/* + * C++ support... + */ + +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ + +/* + * Prototypes... + */ + +extern void mxmlAdd(mxml_node_t *parent, int where, + mxml_node_t *child, mxml_node_t *node); +extern void mxmlDelete(mxml_node_t *node); +extern void mxmlElementDeleteAttr(mxml_node_t *node, + const char *name); +extern const char *mxmlElementGetAttr(mxml_node_t *node, const char *name); +extern void mxmlElementSetAttr(mxml_node_t *node, const char *name, + const char *value); +extern void mxmlElementSetAttrf(mxml_node_t *node, const char *name, + const char *format, ...) +# ifdef __GNUC__ +__attribute__ ((__format__ (__printf__, 3, 4))) +# endif /* __GNUC__ */ +; +extern int mxmlEntityAddCallback(int (*cb)(const char *name)); +extern const char *mxmlEntityGetName(int val); +extern int mxmlEntityGetValue(const char *name); +extern void mxmlEntityRemoveCallback(int (*cb)(const char *name)); +extern mxml_node_t *mxmlFindElement(mxml_node_t *node, mxml_node_t *top, + const char *name, const char *attr, + const char *value, int descend); +extern void mxmlIndexDelete(mxml_index_t *ind); +extern mxml_node_t *mxmlIndexEnum(mxml_index_t *ind); +extern mxml_node_t *mxmlIndexFind(mxml_index_t *ind, + const char *element, + const char *value); +extern mxml_index_t *mxmlIndexNew(mxml_node_t *node, const char *element, + const char *attr); +extern mxml_node_t *mxmlIndexReset(mxml_index_t *ind); +extern mxml_node_t *mxmlLoadFd(mxml_node_t *top, int fd, + mxml_type_t (*cb)(mxml_node_t *)); +extern mxml_node_t *mxmlLoadFile(mxml_node_t *top, FILE *fp, + mxml_type_t (*cb)(mxml_node_t *)); +extern mxml_node_t *mxmlLoadString(mxml_node_t *top, const char *s, + mxml_type_t (*cb)(mxml_node_t *)); +extern mxml_node_t *mxmlNewCDATA(mxml_node_t *parent, const char *string); +extern mxml_node_t *mxmlNewCustom(mxml_node_t *parent, void *data, + mxml_custom_destroy_cb_t destroy); +extern mxml_node_t *mxmlNewElement(mxml_node_t *parent, const char *name); +extern mxml_node_t *mxmlNewInteger(mxml_node_t *parent, int integer); +extern mxml_node_t *mxmlNewOpaque(mxml_node_t *parent, const char *opaque); +extern mxml_node_t *mxmlNewReal(mxml_node_t *parent, double real); +extern mxml_node_t *mxmlNewText(mxml_node_t *parent, int whitespace, + const char *string); +extern mxml_node_t *mxmlNewTextf(mxml_node_t *parent, int whitespace, + const char *format, ...) +# ifdef __GNUC__ +__attribute__ ((__format__ (__printf__, 3, 4))) +# endif /* __GNUC__ */ +; +extern mxml_node_t *mxmlNewXML(const char *version); +extern int mxmlRelease(mxml_node_t *node); +extern void mxmlRemove(mxml_node_t *node); +extern int mxmlRetain(mxml_node_t *node); +extern char *mxmlSaveAllocString(mxml_node_t *node, + mxml_save_cb_t cb); +extern int mxmlSaveFd(mxml_node_t *node, int fd, + mxml_save_cb_t cb); +extern int mxmlSaveFile(mxml_node_t *node, FILE *fp, + mxml_save_cb_t cb); +extern int mxmlSaveString(mxml_node_t *node, char *buffer, + int bufsize, mxml_save_cb_t cb); +extern mxml_node_t *mxmlSAXLoadFd(mxml_node_t *top, int fd, + mxml_type_t (*cb)(mxml_node_t *), + mxml_sax_cb_t sax, void *sax_data); +extern mxml_node_t *mxmlSAXLoadFile(mxml_node_t *top, FILE *fp, + mxml_type_t (*cb)(mxml_node_t *), + mxml_sax_cb_t sax, void *sax_data); +extern mxml_node_t *mxmlSAXLoadString(mxml_node_t *top, const char *s, + mxml_type_t (*cb)(mxml_node_t *), + mxml_sax_cb_t sax, void *sax_data); +extern int mxmlSetCDATA(mxml_node_t *node, const char *data); +extern int mxmlSetCustom(mxml_node_t *node, void *data, + mxml_custom_destroy_cb_t destroy); +extern void mxmlSetCustomHandlers(mxml_custom_load_cb_t load, + mxml_custom_save_cb_t save); +extern int mxmlSetElement(mxml_node_t *node, const char *name); +extern void mxmlSetErrorCallback(mxml_error_cb_t cb); +extern int mxmlSetInteger(mxml_node_t *node, int integer); +extern int mxmlSetOpaque(mxml_node_t *node, const char *opaque); +extern int mxmlSetReal(mxml_node_t *node, double real); +extern int mxmlSetText(mxml_node_t *node, int whitespace, + const char *string); +extern int mxmlSetTextf(mxml_node_t *node, int whitespace, + const char *format, ...) +# ifdef __GNUC__ +__attribute__ ((__format__ (__printf__, 3, 4))) +# endif /* __GNUC__ */ +; +extern void mxmlSetWrapMargin(int column); +extern mxml_node_t *mxmlWalkNext(mxml_node_t *node, mxml_node_t *top, + int descend); +extern mxml_node_t *mxmlWalkPrev(mxml_node_t *node, mxml_node_t *top, + int descend); + + +/* + * Semi-private functions... + */ + +extern void mxml_error(const char *format, ...); +extern mxml_type_t mxml_ignore_cb(mxml_node_t *node); +extern mxml_type_t mxml_integer_cb(mxml_node_t *node); +extern mxml_type_t mxml_opaque_cb(mxml_node_t *node); +extern mxml_type_t mxml_real_cb(mxml_node_t *node); + + +/* + * C++ support... + */ + +# ifdef __cplusplus +} +# endif /* __cplusplus */ +#endif /* !_mxml_h_ */ + + +/* + * End of "$Id: mxml.h 307 2007-09-15 20:03:15Z mike $". + */ diff --git a/plugins/zynaddsubfx/remote_zynaddsubfx.cpp b/plugins/zynaddsubfx/remote_zynaddsubfx.cpp new file mode 100644 index 000000000..9d8973be3 --- /dev/null +++ b/plugins/zynaddsubfx/remote_zynaddsubfx.cpp @@ -0,0 +1,376 @@ +/* + * remote_zynaddsubfx.cpp - ZynAddSubFX-embedding plugin + * + * Copyright (c) 2008 Tobias Doerffel + * + * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net + * + * 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 (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + + +#include +#include + +#define BUILD_REMOTE_PLUGIN_CLIENT +#include "engine.h" +#include "instrument_play_handle.h" +#include "note_play_handle.h" +#include "remote_plugin.h" +#include "remote_zynaddsubfx.h" + + +std::string __presets_dir; + +#define main unused_main +#ifdef LMMS_BUILD_LINUX +#define ATOM(x) (x) +#endif +#include "src/main.C" + +#undef main + +#include + +static pthread_t __gui_thread_handle; +static pthread_mutex_t __gui_mutex; +static std::queue __gui_messages; + + +class remoteZynAddSubFX : public remotePluginClient +{ +public: + remoteZynAddSubFX( int _shm_in, int _shm_out ) : + remotePluginClient( _shm_in, _shm_out ) + { + for( int i = 0; i < NumKeys; ++i ) + { + m_runningNotes[i] = 0; + } + setInputCount( 0 ); + sendMessage( IdInitDone ); + waitForMessage( IdInitDone ); + } + + virtual void updateSampleRate( void ) + { + SAMPLE_RATE = sampleRate(); + } + + virtual void updateBufferSize( void ) + { + SOUND_BUFFER_SIZE = bufferSize(); + } + + virtual bool processMessage( const message & _m ) + { + bool gui_message = false; + switch( _m.id ) + { + case IdQuit: + delete master; + break; + + case IdShowUI: + case IdHideUI: + case IdLoadSettingsFromFile: + case IdLoadPresetFromFile: + gui_message = true; + break; + + case IdSaveSettingsToFile: + { + char * name = strdup( _m.getString().c_str() ); + master->saveXML( name ); + free( name ); + sendMessage( IdSaveSettingsToFile ); + return true; + break; + } + + case IdZasfPresetDirectory: + __presets_dir = _m.getString(); + for( int i = 0; i < MAX_BANK_ROOT_DIRS; ++i ) + { + if( config.cfg.bankRootDirList[i] == NULL ) + { + config.cfg.bankRootDirList[i] = new char[MAX_STRING_SIZE]; + strcpy(config.cfg.bankRootDirList[i], __presets_dir.c_str() ); + break; + } + else if( strcmp( config.cfg.bankRootDirList[i], + __presets_dir.c_str() ) == 0 ) + { + break; + } + } + break; + + default: + return remotePluginClient::processMessage( _m ); + } + if( gui_message ) + { + pthread_mutex_lock( &__gui_mutex ); + __gui_messages.push( _m ); + pthread_mutex_unlock( &__gui_mutex ); + } + return true; + } + + virtual ~remoteZynAddSubFX() + { + } + + // all functions are called while master->mutex is held + virtual void processMidiEvent( const midiEvent & _e, + const f_cnt_t /* _offset */ ) + { + switch( _e.m_type ) + { + case MidiNoteOn: + if( _e.velocity() > 0 ) + { + if( _e.key() <= 0 || _e.key() >= 128 ) + { + break; + } + if( m_runningNotes[_e.key()] > 0 ) + { + master->NoteOff( 0, _e.key() ); + } + ++m_runningNotes[_e.key()]; + master->NoteOn( 0, _e.key(), + _e.velocity() ); + break; + } + case MidiNoteOff: + if( _e.key() <= 0 || _e.key() >= 128 ) + { + break; + } + if( --m_runningNotes[_e.key()] <= 0 ) + { + master->NoteOff( 0, _e.key() ); + } + break; + case MidiPitchBend: + master->SetController( _e.m_channel, + C_pitchwheel, + _e.m_data.m_param[0] + + _e.m_data.m_param[1]*128-8192 ); + break; + default: + break; + } + } + + + virtual void process( const sampleFrame * _in, sampleFrame * _out ) + { + REALTYPE outputl[SOUND_BUFFER_SIZE]; + REALTYPE outputr[SOUND_BUFFER_SIZE]; + + master->AudioOut( outputl, outputr ); + + for( fpp_t f = 0; f < SOUND_BUFFER_SIZE; ++f ) + { + _out[f][0] = outputl[f]; + _out[f][1] = outputr[f]; + } + } + + +private: + int m_runningNotes[NumKeys]; + +} ; + +static remoteZynAddSubFX * __remote_zasf = NULL; +static int __exit = 0; + + +void * guiThread( void * ) +{ + int e; + ui = NULL; + + while( !__exit ) + { + if( ui ) + { + Fl::wait( 0.1 ); + } + else + { +#ifdef LMMS_BUILD_WIN32 + Sleep( 100 ); +#else + usleep( 100*1000 ); +#endif + } + pthread_mutex_lock( &__gui_mutex ); + while( __gui_messages.size() ) + { + remotePluginClient::message m = __gui_messages.front(); + __gui_messages.pop(); + switch( m.id ) + { + case IdShowUI: + // we only create GUI + if( !ui ) + { + Fl::scheme( "plastic" ); + ui = new MasterUI( master, &e ); + } + ui->showUI(); + ui->refresh_master_ui(); + break; + + case IdHideUI: + if( !ui ) break; + switch( config.cfg.UserInterfaceMode ) + { + case 0: + ui->selectuiwindow->hide(); + break; + case 1: + ui->masterwindow->hide(); + break; + case 2: + ui->simplemasterwindow->hide(); + break; + } + break; + + case IdLoadSettingsFromFile: + { + char * f = strdup( m.getString(). + c_str() ); + pthread_mutex_lock( &master->mutex ); + master->defaults(); + master->loadXML( f ); + pthread_mutex_unlock( &master->mutex ); + master->applyparameters(); + if( ui ) ui->refresh_master_ui(); + unlink( f ); + free( f ); + pthread_mutex_lock( &master->mutex ); + __remote_zasf->sendMessage( + IdLoadSettingsFromFile ); + pthread_mutex_unlock( &master->mutex ); + break; + } + + case IdLoadPresetFromFile: + { + char * f = strdup( m.getString(). + c_str() ); + pthread_mutex_lock( &master->mutex ); + master->part[0]->defaultsinstrument(); + master->part[0]->loadXMLinstrument( f ); + pthread_mutex_unlock( &master->mutex ); + master->applyparameters(); + if( ui ) ui->refresh_master_ui(); + free( f ); + pthread_mutex_lock( &master->mutex ); + __remote_zasf->sendMessage( + IdLoadPresetFromFile ); + pthread_mutex_unlock( &master->mutex ); + break; + } + + default: + break; + } + } + pthread_mutex_unlock( &__gui_mutex ); + } + Fl::flush(); + + return NULL; +} + + + + +int main( int _argc, char * * _argv ) +{ + if( _argc < 3 ) + { + fprintf( stderr, "not enough arguments\n" ); + return( -1 ); + } + +#ifdef LMMS_BUILD_WIN32 + // (non-portable) initialization of statically linked pthread library + pthread_win32_process_attach_np(); + pthread_win32_thread_attach_np(); +#endif + + __remote_zasf = new remoteZynAddSubFX( atoi( _argv[1] ), + atoi( _argv[2] ) ); + + config.init(); + OSCIL_SIZE = config.cfg.OscilSize; + + config.cfg.GzipCompression = 0; + + srand( time( NULL ) ); + denormalkillbuf = new REALTYPE[SOUND_BUFFER_SIZE]; + for( int i = 0; i < SOUND_BUFFER_SIZE; ++i ) + { + denormalkillbuf[i] = (RND-0.5)*1e-16; + } + + OscilGen::tmpsmps = new REALTYPE[OSCIL_SIZE]; + newFFTFREQS( &OscilGen::outoscilFFTfreqs, OSCIL_SIZE/2 ); + + pthread_mutex_init( &__gui_mutex, NULL ); + + master = new Master(); + master->swaplr = 0; + + pthread_create( &__gui_thread_handle, NULL, guiThread, NULL ); + + remotePluginClient::message m; + while( ( m = __remote_zasf->receiveMessage() ).id != IdQuit ) + { + pthread_mutex_lock( &master->mutex ); + __remote_zasf->processMessage( m ); + pthread_mutex_unlock( &master->mutex ); + } + + __exit = 1; + + delete denormalkillbuf; + delete OscilGen::tmpsmps; + deleteFFTFREQS( &OscilGen::outoscilFFTfreqs ); + + pthread_mutex_destroy( &__gui_mutex ); + +#ifdef LMMS_BUILD_WIN32 + pthread_win32_thread_detach_np(); + pthread_win32_process_detach_np(); +#endif + + return 0; +} + + + + diff --git a/plugins/zynaddsubfx/remote_zynaddsubfx.h b/plugins/zynaddsubfx/remote_zynaddsubfx.h new file mode 100644 index 000000000..630f9e712 --- /dev/null +++ b/plugins/zynaddsubfx/remote_zynaddsubfx.h @@ -0,0 +1,36 @@ +/* + * remote_zynaddsubfx.h - ZynAddSubFX-embedding plugin + * + * Copyright (c) 2008 Tobias Doerffel + * + * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net + * + * 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 (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + + +#ifndef _REMOTE_ZYNADDSUBFX_H +#define _REMOTE_ZYNADDSUBFX_H + +#include "remote_plugin.h" + +enum ZasfRemoteMessageIDs +{ + IdZasfPresetDirectory = IdUserBase +} ; + +#endif diff --git a/plugins/zynaddsubfx/src/AUTHORS.txt b/plugins/zynaddsubfx/src/AUTHORS.txt new file mode 100644 index 000000000..a1ffa13d1 --- /dev/null +++ b/plugins/zynaddsubfx/src/AUTHORS.txt @@ -0,0 +1,13 @@ +Main author: + Nasca Octavian Paul + +Developers: + Mark McCurry + +Contributors: + Gerald Folcher (legato, mono notes memory) + Lars Luthman (zombie fix,jack midi, LASH support) + Daniel Clemente (with a workaround of X11 repeated key bug) + Emmanuel Saracco (fix for JACK output) + Achim Settelmeier (QUERTZ keyboard layout for virtual keyboard) + diff --git a/plugins/zynaddsubfx/src/COPYING b/plugins/zynaddsubfx/src/COPYING new file mode 100644 index 000000000..e47a022c6 --- /dev/null +++ b/plugins/zynaddsubfx/src/COPYING @@ -0,0 +1,347 @@ + +NOTE! The GPL below is copyrighted by the Free Software Foundation, but +the instance of code that it refers to (the ZynAddSubFX application) +is copyrighted by the authors (Nasca Octavian Paul and others) who actually wrote it. +--------------------------------------------------------------------------- + + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/plugins/zynaddsubfx/src/ChangeLog b/plugins/zynaddsubfx/src/ChangeLog new file mode 100644 index 000000000..3416596ab --- /dev/null +++ b/plugins/zynaddsubfx/src/ChangeLog @@ -0,0 +1,863 @@ +6 Mar 2002 -(dupamasa - in jur de ora 4) Mi-a venit ideea exact cum sa fac cand ma plimbam pe strada Rolirudnap +7/8 Mar 2002 - Started to do diagrams +10 Mar 2002 - Started to write "voice" +11 Mar 2002 - Heard first sound +12 Mar 2002 - tested with 200 voices +16 Mar 2002 - made "Note" the main class + - added vibratto + - added glissando +20 Mar 2002 - started to write the Envelope class +21 Mar 2002 - Envelope written (almost) + Volume envelope almost written +23 Mar 2002 - Scris relasenote(putin) + Envelope-ul este si in dB + "glissando" este inlocuit cu "Envelope" de frecventa + started to write the LFO class +24 Mar 2002 - Corrected a bug that could crashed the synth (forgotten to disable the amp/freq envelopeenabled when killed it) +25 Mar 2002 - Started to write the Filter class (wrote only few lines) +27 Mar 2002 - Scris filtrul(putin), si FilterEnvelope +28 Mar 2002 - Adaugat la LFO si tipul "rampup" si "rampdown" + Scris filterLFO si amplitudeLFO(termollo) + redenumiti si aranjati parametrii + Adaugat LFO delay + Scris FilterEnvelope(corect) si FilterLFO(corect) +29 Mar 2002 - Adaugat RingModulation + Adaugat FM/RM Amplitude si Frequency Envelope + Corectat un bug minor la Envelope-ASRinit(); + Adaugat FM +01 Apr 2002 - Corectat un bug care facea sa se auda paraituri la sunetele care incepeau co o faza!=0 + Scris cativa dintre parametrii globali Envelop-ulire,LFO,Filter,.. +02 Apr 2002 - Curatat putin ADnote + Adaugat VelocityScale la amplitudine, la FM si la Filtru Global +03 Apr 2002 - Aranjati toti parametrii ADnote in structuri +04 Apr 2002 - Mutati multi parametrii in ADnoteParameters + Inceput sa scriu ADnoteParameters +05 Apr 2002 - Inceput sa scriu clase speciale pentru parametrii(midi) (LFO..) +06 Apr 2002 - Continuat sa scriu clasele speciale pentru parametrii + Teoretic merge sinteza multitimbrala(Adica se poate aplea ADnote(canal,note,vel)) +07 Apr 2002 - Completat(aproape) transferul de parametri midi la cei reali +08 Apr 2002 - Added FM oscil at parameters and corrected a small FM bug +09 Apr 2002 - Inceput sa-l fac real-time +10 Apr 2002 - Merge la keyboard-ul MIDI, polifonic +27 Apr 2002 - Scris interfata la OSS, la latenta scazuta + Corectat un bug care facea ca sa se execute calcule inutile, ceea ce facea ca polifonia maxima sa scada de 10 ori +29 Apr 2002 - Inceput sa scriu interfata midi(obiect) +30 Apr 2002 - Continuat putin interfata midi (dar nu am terminat) +02 Mai 2002 - Merge in timp real cu latenta scazuta, dar se mai auda niste "pacanaituri" +03 Mai 2002 - Inceput sa scriu Reverb (acum este doar ecou) + "Pacanaiturile" au fost eliminate. +09 Mai 2002 - Reverb-ul suna a reverberatie +11 Mai 2002 - Adaugat cativa parametrii midi la Reverb +18 Mai 2002 - Adaugat filtrul AllPass la Reverb si adaugat parametrul Plohidamp +19 Mai 2002 - Adaugat InitialDelay (idelay) la Reverb +24 Iun 2002 - Clasa Filtru nu mai este dependenta de FilterParams(pot sa-l folosesc in alte scopuri) + Corectat un bug la filtru care facea ca la rezomante scazute sa amplifice f. mult basii + Adaugat High Pass Filter + Rezonanta filtrului este exponentiala + Adauga LPF+HPF la Reverb + Inceput sa scriu Generatorul de Functii (OscilGen) +25 Iun 2002 - Scris cateva forme de unda (functii) + Reverb-ul are volumul in dB si daca este zero(ca parametru) atunci se dezactiveaza +02 Iul 2002 - Adaugat inca o functie la generatorul de functii +03 Iul 2002 - Inceput sa scriu generarea de functii la OscilGen pe baza de FFT + Inlaturat DC-ul de la OscilGen +04 Iul 2002 - Adaugat ANTI-ALIASING la ADnote si insumarea armonicelor se face in domeniul frecventa + Corectat un bug care facea sa sune rau dac OSCIL_SIZE!=512 (era declarat de 2 ori) +12 Iul 2002 - Adaugat posibilitatea de a folosi ca modulator alta voce + Adaugat parametrii MIDI la OscilGen +13 Iul 2002 - Adaugat Randomness la clasa OscilGen +15 Iul 2002 - Adaugat si Panning(incl. Randomness) => instrumentul este acum stereo +16 Iul 2002 - Adaugat Randomness la LFO (faza 0 => random) + Inlaturat o eroare care facea ca amplitudinea sa nu fie interpolata +17 Iul 2002 - Volumul FM-ului este exponential + Adaugat atenuare la volumul FM-ului la note inalte +23 Iul 2002 - Adaugat EnvelopeStretch + Corectata o eroare care facea ca uneori sunetul sa se auda foarte tare la inceput + Adaugat fade-in (f. scurt) si fade out in caz ca envelop-ul are A=0 sau R=0, a.i. sa nu se auda pacanaituri +24 Iul 2002 - Corectat Relase-ul la Envelope si adaugat ForcedRelase +25 Iul 2002 - Adaugat posibilitatea de a nu folosi AntiAliasing-ul + Adaugat Frequency Modulation (nu phase modulation) + Adaugat Delay la fiecare voce + Adaugat Morphing la modulatie +26 Iul 2002 - Inceput sa scriu clasa Part +27 Iul 2002 - Se face controlul Midi folosind clasa Part si nu ADnote +28 Iul 2002 - Corectata o eroare care facea sa se instantieze clasa ADnoteParameters pt. fiecare nota => memoria era ocupata excesiv si "manca" din procesor. Cauza erorii este ca trimiteam obiectul ADnoteParameters ca parametru si nu referinta lui. Asta era cauza pacanaiturilor ce se auzeau daca apasam multe clape simultan. +29 Iul 2002 - Adaugat clasa Master (Permite acum mai multe instr. simultan => multitimbral) + Observat o eroare la Envelope +30 Iul 2002 - Adaugat EnvelopeStretch si Forcedrelase la instantierea unui obiect EnvelopeParams + Durata Sustainul-ui fortat este acceeasi indiferent de paramentrul EnvelopeStretch + Adaugat Ecou +31 Iul 2002 - Daca VelocityScaleFunction=127 atunci orice vel. va face amplitudinea maxima (ca si cand vel.=127) + Inceput sa scriu Interfata Utilizator +01 Aug 2002 - Toti parametrii sunt convertiti in REALTYPE direct de ADnote,de LFO + Inlataurate mici probleme de AntiAliasing daca detune-ul era prea sus si la unele moduri FM + Programul incepe sa fie controlabil de Interfata +02 Aug 2002 - Inlaturat o eroare stupida care facea ca sa se seteze valorile EnvelopeParams la -1 (scria din Master:: prea mult) +03 Aug 2002 - Terminata interfata pentru ADnoteParameters.GlobalPars + Adaugat inca un parametru la lfo (continous LFO) care faca ca LFO-ul sa nu inceapa la fiecare NoteOn + Corectat doua erori la ...[nvoice].AmpEnvelope si ...[nvoice].FreqEnvelope + Scrisa interfata pentru ADnoteParameters.VoicePars (fara FM+OSCIL...) +04 Aug 2002 - Scrisa interfata cu FM (fara Oscil) + Corectate doua erori cu provire la FMampenv si FMfreqenv + Inlaturat aliasing-ul la vocea FM + Modificata interfata (Voice si FM-ul sunt intr-o singura fereastra) + Inceput sa scriu schimbare voce curenta. +05 Aug 2002 - Adaugat interfata pentru cei mai importanti parametrii ai ADnote_VoicePar[nvoice] + Inceput sa scriu interfata pentru OscilGen +06 Aug 2002 - Este mult mai usoara schimbarea vocii curente. + Inceput sa scriu OscilEditor + Nu mai este necesara changebasefunc() la oscil pentru a schimba basefunction, se apeleaza automat. + OscilEditor este (aproape) complet + Toti parametrii ADnoteParameters au UI + Corectate cateva erori (cauzate de faptul ca nu am verificat daca ADnote::...Enabled!=0) +07 Aug 2002 - Corectata o eroare la envelope + Adaugat afisaj spectrum la OscilEdit + Adaugat parametrii noi: extenal oscillator (voice si FM) si oscilphase(si FM) si interfata pentru ei + Gasite mai multe erori care apar daca misc widget-urile in timp ce cant la clape (probabil este vorba de thread-uri care trebuie sa fie sincronizate sau ceva cam asa sau memory leaks) + Inceput sa scriu interfata pentru Part + Adaugat bypass la filtrul global + Adaugat conversia oscil-ului in basefunction + Corectata o mica eroare la calcularea oscil-ului referitor la faze +08 Aug 2002 - In VoiceList valorile sunt actualizate la fiecare apasare a butonului "ShowVoiceList" si formele de unda sunt afisate corect. + Corectate niste mici erori la FM + Daca se foloseste ca modulator o alta voce, interfata dezativeaza unii parametrii FM daca sunt inutili + Inceput sa scriu interfata si parametrii Master/Part + Schimbat putin Master si Part (atentie sa nu se instantieza ADnoteParameters la fiecare apasare de tasta) + Inceput sa scriu control-ul pentru Master/Parts +09 Aug 2002 - Scris parametrii Part si Master + Inceput sa scriu sincronizarea intre thread-uri +10 Aug 2002 - Adaugat o noua forma de unda la OscilGen + Adaugat sincronizarea intre thread-uri=>programul nu mai crapa daca in timp ce apas clapele, modific forma de unda + Adaugat enable/disable ADnote + Inceput sa scriu SUBnote/SUBnoteParameters + Se poate canta si la SUBnote(inceput sa scriu UI pt. el) +11 Aug 2002 - Scris controlul armonicelor + Adugati cativa parametrii la SUBnote + Adaugat AmpEnvelope la SUBnote(si UI) +12 Aug 2002 - Adaugat Detune la SUBnote si schimbat Detune-ul la ADnote + Adaugat FreqEnvelope la SUBnote +16 Aug 2002 - Corectata o eroare care facea ca VoiceOut sa fie inlaturat chiar daca era inca folosit(de alte voci) + Daca "Forced Relase" este off atunci se face relase-ul liniar + Adaugat BandWidth Envelope +17 Aug 2002 - Inceput sa pregatesc pentru EffectManager +18 Aug 2002 - Adaugat inca un parametru la Reverb: initial delay fb + Scris efectele de insertie + Inceput sa scriu efectele de sistem +19 Aug 2002 - Continuat sa scriu efectele de sistem + Inceput sa scriu interfata la Efecte (Reverb - terminat, aproape) +22 Aug 2002 - Corectata o eroare la Echo + Se poate schimba efectul de insertie + Gasita o eroare care "crapa" programul daca schimb efectul de le Reverb (rezolvata temporar, dar cu "memory leak") +23 Aug 2002 - Corectata eroarea la Reverb (a fost din cauza ca am pus ">" in loc de ">=" :-p ) + Terminat efectele de insertie(si interfata) + Adaugat Effect cleanup + Scrisa interfata pentru efectele sistem (cu exceptia sendto another sys eff) +24 Aug 2002 - Adaugate doua noi efecte: Chorus si Phaser +25 Aug 2002 - Nu se mai aude tacanit la Chorus daca schimb Delay/Depth + Corectat o mica eroare care facea ca sa nu se afiseze Pinsparts corect + Adaugat un nou efect: AlienWah + Nu se mai aude tacanit la Phaser si la AlienWah la frecvente LFO f. mari +27 Aug 2002 - Adaugata o noua forma de unda: Chirp + Adaugat Waveshaping la OscilGen + Se poate compila si fara UI + Inceput sa scriu Salvarea/Incarcarea Parametrilor +28 Aug 2002 - In ADnoteVoiceListUI se afisaza corect daca vocea este activata/dezactivata + Scrisa Salvarea/Incarcarea parametrilor (cu exceptia la OSCIL::UseAsBaseFunction) + Adaugat File Save/Open +29 Aug 2002 - Se poate salva si oscil::useasbase + Se afiseaza corect valorile dupa incarcare +01 Sep 2002 - Adaugat "codul de intrare" sa saveload 0xfe pt. a sti de unde incepe o noua "ramura" + "Codul de intrare" este folosit pentru a nu incarca "ramurile" care nu se potrivesc cu specificatiile (ex. nr. de voce sau nr. part prea mare) + Adaugat header la fisier + Imbunatatit OscilUI::useasbase +03 Sep 2002 - Modificat codurile de parmetrii: indicele par. sunt >= 0x80, parametrii <0x80 , controlerii speciali(urcare/coborare creanga) >=0xf0; Este util la versiunile viitoare, la forward/reverse compatibility. + Inceput sa scriu clasa Microtonal si interfata pt. Microtonal +04 Sep 2002 - Adaugat Pfilterbypass la salvare (am uitat sa o pun pana acum) + Aproape terminat Microtonal-ul (cu exceptia importului din fisiere .scl) +05 Sep 2002 - Facut cateva mici modificari la Microtonal si Echo + Adaugat un nou parametru la ADnote: PVolumeminus + Adaudat parametrii noi de Detune: Pcoarsedetune(coarse+octave) si Pdetunetype + Adaugat cateva tipuri de detune +06 Sep 2002 - Adaugat posibilitatea de a folosi ADnotepars:Globalpars.Pdetudetype in loc de Pdetunetype (0 = default detunetype), asa ca nu mai trebuie sa mai modific la fiecare voce detunetype: setez la 0 si modific global-ul + Facut mici modificari la MidiInput(OSS) +07 Sep 2002 - Corectata o eroare cu privire la detune si daca freq. > Nyquist + Modificat driver-ul OSSmidiin + Adaugat driver Alsa cu port virtual + Se poate salva doar instrumentele/microtonal. + Adaugata un nou fel de waveshaping(Zigzag) +08 Sep 2002 - Psysefxvol[][] sunt scalate in dB + Nu mai este periculos sa inchid fereastra principala +09 Sep 2002 - Se actualizeaza corect la incarcare la Master:Psysefxvol[][],Pvolume,Pkeyshift; si alti parametrii la Part + Adaugat nume la Part + Panic-ul (Shut-up-ul) se aplica si la efecte + Part->Penable controleaza de fapt daca Part-ul este activat/complet dezactivat. Daca se dezactiveaza un part toate notele+ efectele insertion sunt oprite. Nu mai consuma CPU daca folosesc multe part-uri. + Adaugat un nou parametru la part: Pnoteon care controleaza daca part-ul primeste mesaje NoteOn + Adaugarea extensiei se face automat. + Adaugat LFO exp_up 1 si 2 + Curatat putin de memory leaks (mai am de curatat si interfata) +10 Sep 2002 - Adaugat filtrul HPF cu un pol + Interfata se inchide corect. + Adaugat textul cu Copyright in interfata + Traduse toate comentariile in limba engleza + Adaugat licenta in fiecare fisier +11 Sep 2002 - Adaugat descriere la fiecare fisier + Corectata o eroare care facea ca SUBnote sa aiba amplitudini f. mari la freq. f. inalte + Adaugat cateva macro-uri la interpolarea amplitudinii +12 Sep 2002 - Modificat extensiile (*.mas.zyn ---> *.mas_zyn, la fel si celelalte) pentru a nu aparea fisiere *.mas.mas.zyn +13 Sep 2002 - Am decis numele programului: "ZynAddSubFX" (Zyn de la synthetizer (inlocuit S cu Z), Add de la additive, Sub de la substractive, FX de la effects) +14 Sep 2002 - Volumul din ADvoicelist se afiseaza corect +15 Sep 2002 - Adaugat inca 3 moduri de waveshaping Limiter, UpperLimiter, LowerLimiter +16 Sep 2002 - Adaugat Makefile +17 Sep 2002 - Corectata o mica eroare care facea ca sa nu se incarce fisierele cu data intotdeauna + Nu se amplifica freq. f. inalte daca freq. filtrului este mare. + Inceput sa scriu documentatia. +18 Sep 2002 - Adaugat functia de resetare a tuturor parametrilor(master si instrument) +23 Sep 2002 - Adaugat posibilitatea de a conecta efectele de insertie la iesire Master + Lfo-ul la frecventa incepe de la 0 pt. startphase=0 +24 Sep 2002 - Corectate niste mici erori la Chorus/Phaser + Adaugat si "substract" la Chorus si Phaser + Limitat tipul detune-ului la valoarea maxima +25 Sep 2002 - LANSAT PE INTERNET - PRIMA VERSIUNE (1.0.0) +-------------------------------------------------------------------------------------------------- +01 Dec 2002 - Corectat niste comentarii + - Inlaturat o eroare care facea ca ZynAddSubFX sa crape daca dezactivez un part utilizat + - Inceput sa scriu Rezonanta +02 Dec 2002 - Terminat de scris Rezonante + - Adaugat filtru trecer-banda (BPF) + - Scris Recording +03 Dec 2002 - Adaugat Gain la Resonance + - Adaugat "New Instrument" la meniu +06 Dec 2002 - LANSAT PE INTERNET - VERSIUNEA (1.0.1) +-------------------------------------------------------------------------------------------------- +08 Dec 2002 - Inceput sa scriu Bank si interfata pentru Bank +09 Dec 2002 - adaugat si "make debug" + - Continuat sa scriu Bank/UI; acum se poate folosi (dar nu salva pe HDD) +10 Dec 2002 - Terminat Bank (mai trebuie scris un "config" file pentru a alege automat ultima banka folosita) +11 Dec 2002 - Am mai lucrat ceva la Bank si am adaugat "config file" +12 Dec 2002 - Filtrul BPF suna mai tare + - Nu mai ar trebui sa fie probleme la compilarea FFTwrapper.h (fftw.h) +13 Dec 2002 - LANSAT PE INTERNET - VERSIUNEA (1.0.2) +-------------------------------------------------------------------------------------------------- + - Corectat o eroare care facea ca programul sa crape daca salvam parametrii in timp ce cantam + - LANSAT PE INTERNET - VERSIUNEA (1.0.2-1) - de acasa +-------------------------------------------------------------------------------------------------- +21 Dec 2002 - Corectate mici erori (nu mai dispare "Bypass Global Filter", inlaturat zgomotul de mica amplitudine - cauzat de reverb,nu mai apare intarzierea foarte lunga de la inceput a notelor muzicale daca conectam la aseqview) + - Adaugat filtru de rejectie banda (Notch) + - adugat randomize la Resonance + - Inceput sa scriu VU-meter-ul +22 Dec 2002 - Terminat VU-meter-ul + - Schimbat modul in care efectele de insertie se calculeaza (suna mai tare un pic) + - Adaugata o noua functie la OscilGen +23 Dec 2002 - LANSAT PE INTERNET - VERSIUNEA (1.0.3) +-------------------------------------------------------------------------------------------------- +24 Dec 2002 - Adaugata posibilitatea de a incarca fisiere ".scl" (la Microtonal) +26 Dec 2002 - Adaugata optiunea de a folosi numai OSS-ul (fara ALSA) +27 Dec 2002 - Corectate cateva erori si modificate cateva lucruri marunte la Microtonal +28 Dec 2002 - Mici modificari la Microtonal + - Panic-ul la Reverb functioneaza OK + - Inceput sa scriu Scale Degree Mapping la Microtonal +29 Dec 2002 - Continuat Scale Degree Mapping la Microtonal (dar nu am terminat) +30 Dec 2002 - Corectat lucrul cu ScaleShift-ul + - schimbat modul in care se face keyshift-ul (nu se mai schimba armonia, indiferent de sistem) +31 Dec 2002 - Terminat Mapping-ul la Microtonal(incl. incarcarea/salvarea) + Corectat eroarea care facea ca la Microtonal sa nu se incarce de fiecare data din scl_zyn unele date + +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +01 Ian 2003 - Corectata o eroare la Microtonal (erau probleme la InvertKeys daca era folosit key mapping) + - Adaugata un nou tip de waveshaping (Inverse Limiter) +02 Ian 2003 - Adaugat afisaj al acordului fin (cents) + - Butoanele arata f. frumos (am adaugat un nou widget in loc de Fl_Dial) +03 Ian 2003 - Schimbate butoanele (putin) + - Nu se mai aude un tacanit la ShutUp sau AllNotesOff + - Corectat putin waveshaper-quantisize si butoanele + - Inlaturata o eroare care facea ca programul sa crape daca schimbam unii parametri ale efectelor +07 Ian 2003 - LANSAT PE INTERNET - VERSIUNEA (1.0.4) +-------------------------------------------------------------------------------------------------- +08 Ian 2003 - Am inlaturat de-a binelea eroarea (cu efectele - 3 Ian) +11 Ian 2003 - Corectate o mica eroare care facea ca volumul sa fie negativ la ADnote::voice[].PVolume <64 +13 Ian 2003 - Corectata o mica eroare la VU-Meter + - Corectata o mica eroare cu privire la panning la Reverb +15 Ian 2003 - Adaugat min/max keyresponse limits la Part + - Adaugat Filtru si FiltreEnvelope la SubNote +16 Ian 2003 - Curatat codul sursa (ADnote) prin inlaturarea unor variabile + - Durata fadein-ul este aleasa automat (a.i. sa nu rezulte click-uri la notele joase si nici fadein-ul audibil la notele inalte sau cu freqcvente inalte) + - Corectata o mica eroare care faca ca uneori instrumentul sa nu fie salvat/sters la Bank slot-ul cerut + - Imbunatatita putin interfata: La ADnote si SUBnote, butoanele care controleaza amplitudinea armonicelor sunt colorate diferit daca au amplitudinea 0 +17 Ian 2003 - Corectate erori la Chorus si la Phaser care faceau ca sa sune prea 'sec' (din cauza ca wet-ul era la 50% din volum) +18 Ian 2003 - Inceput sa scriu Preset-uri la efecte +19 Ian 2003 - Adaugat Preset-urile la efecte +20 Ian 2003 - Schimbat putin HPF-ul la Reverb +21 Ian 2003 - Adaugat tuning-ul la Reverb (si Freeverb) si Roomsize + - Schimata putin interfata si modificat putin widgetul Pdial +22 Ian 2003 - Amplificat volumul Reverb-ului cu 6 dB + - Buffer-ul foloseste liste simplu-inlantuite, asa ca nu-i mai problema la "configuratii mari" (multe part-uri) +24 Ian 2003 - LANSAT PE INTERNET - VERSIUNEA (1.0.5) +-------------------------------------------------------------------------------------------------- +26 Ian 2003 - Inceput sa scriu GetAudioOutSamples, care ar putea fi apelat in modul callback +27 Ian 2003 - Adaugat o noua fuctie la waveshaping (clip) + - Adaugat suportul pentru Jack (adica programul poate rula in modul call-back ;-) ) + - Inlaturata o eroare care facea ca npart sa fie foarte mare si ca programul sa crape +29 Ian 2003 - Schimbari foarte minore la OscilGen::waveshape (la clip) + - Daca dau "clear" la OscilEdit, butoanele care au amplitudinea zero, sunt colorate corect +30 Ian 2003 - LANSAT PE INTERNET - VERSIUNEA (1.0.6) +-------------------------------------------------------------------------------------------------- +31 Ian 2003 - Inceput sa adaug optiuni la linia de comanda + - Rata de esantionare (SAMPLE_RATE) este setata la rulare si nu la compilare +01 Feb 2003 - Inca 2 variabile sunt setate la rulare (SOUND_BUFFER_SIZE si OSCIL_SIZE) + - Volumul la Part se aplica doar dupa efecte de insertie + - Inceput sa scriu Distorsionarea (fara filtre) +02 Feb 2003 - Schimbate modurile de distorsionare (exp -> asym1 si pow -> pow ( altul ) ) + - Terminat Distorsionarea +03 Feb 2003 - Adaugata inca o functie la waveshape (asym2) + - Inceput sa scriu Controller-ii + - Adaugat controller-i PitchWheel,Expression,Panning,Filter Cutoff, Filter Q, BandWidth, Modulation Wheel + - Panning-ul si volumul sunt interpolate + - Inceput sa scriu un nou program (Controller) care timite mesaje midi (controller) catre un port ALSA + - Panning-ul la Part se aplica doar dupa efecte de insertie + - Panning-ul la efecte se aplica inainte de procesare +04 Feb 2003 - Adaugat posibilitatea de a seta intensitatea/dezactiva la controlleri(incl. UI) + - Adaugat controler-ul FMmodulationAmplitude + - Corectat o eroare la Buffer (care facea ca Buffer-ul sa nu se reseteze :-P ) +05 Feb 2003 - Corectata o eroare care facea ca programul sa consume mult din procesor (denormalisation) + - Nu mai este permisa o valoare a lui OSCIL_SIZE care sa nu fie putere a lui 2 (este ajustata automat) + - Adaugat controller-i Volume si Sustain Pedal, AllNotesOff, AllSoundOff, ResetAllControllers + - Adaugat NRPN, adica toti parametrii efectelor pot fi controlati prin controlleri +06 Feb 2003 - Pus limite la parametrii efectelor a.i. sa nu se seteze (datorita controllerilor) la valori nevalide + - Inlaturata o mica eroare la controller-ul BandWidth + - Schimbat putin EffectLFO::updateparams + - Controler-ul BandWidth afecteaza doar FineDetune-ul + - Schimbat putin identificare controlerilor si adaugat controlleri la OSS + - Schimbat putin interfata utilizator la controlleri +07 Feb 2003 - LANSAT PE INTERNET - VERSIUNEA (1.0.7) +-------------------------------------------------------------------------------------------------- +08 Feb 2003 - Adaugat modul "mono"(monofonic) la part + - Inceput sa scriu portamento-ul +09 Feb 2003 - Terminat portamento-ul +10 Feb 2003 - Inceput sa scriu Equaliser-ul + - Inlaturata o eroare care facea ca la parametrii efectelor care sunt 0 sa nu fie incarcati +11 Feb 2003 - Terminat Equaliser-ul (adica adaugat vizualizator freq response) + - Corectata o mica eroare care facea ca part-ul 0 sa fie activ chiar daca cel salvat era inactiv +12 Feb 2003 - Mici modificari la EQ (UI) + - Adaugata posibilitatea de swap (stanga <--> dreapta) + - Adaugat Q la filtrele shelf +13 Feb 2003 - Adaugat inca un parametru la Phaser (phase) + - Curatit putin codul sursa la efecte + - Adaugat system effect send to next systems effects +14 Feb 2003 - LANSAT PE INTERNET - VERSIUNEA (1.0.8) +-------------------------------------------------------------------------------------------------- + - cateva mici modificari (de la un patch primit de pe Internet) + - adaugat keylimit la Part (si first note priority) +15 Feb 2003 - Corectata o foarte mica eroare la Part +16 Feb 2003 - Se poate aplica filtrul inainte de distorsion + - Adaugat filter stages (adica filtrul se poate aplica de mai multe ori) +17 Feb 2003 - Corectata o mica eroare la Reverb si modificat putin filter-ul si UI +18 Feb 2003 - Corectata o eroare care facea ca semnalul la voice sa fie intre [-4.0..4.0] si sa faca probleme la RingModulation + - Adaugat modul Noise la ADsynth(voice) pentru a putea produce si tobe + - Adaugat parametrul fixed frequency la 440Hz +19 Feb 2003 - Corectata o mica eroare la ADnote (aparea un fadein nedorit) + - Facute inca cateva mici modificari la ADnoteUI +20 Feb 2003 - Imbunatatit foarte mult Controller-ul si adaugat la ZynAddSubFX ca program extern + - Modificat putin Waveshaper-ul (fct. L/U limit) + - Corectata o eroare la SUBnote (care facea probleme la glissando) + - Adaugat un nou parametru Punch la ADnote care face ca sa sune ca si cum ar fi o lovitura (f. util la Rhodes) +21 Feb 2003 - Adaugata inca o functie de distorsionare x(1-x) +23 Feb 2003 - Corectata o eroare (cu mutex) care facea ca sunetul sa fie extrem de tare, daca in timp ce cantam, modificam unii parametrii de sunet la ADnote +24 Feb 2003 - LANSAT PE INTERNET - VERSIUNEA (1.0.9) +-------------------------------------------------------------------------------------------------- + - Adaugata posibilitatea de a tipari notele si timpul in care au fost produse (optiunea -D) +26 Feb 2003 - Adaugat inca 2 controlleri (Resonance Center Freq. (relative) si Resonace Bandwidth(relative)) +27 Feb 2003 - Adaugata posibilitatea de a modifica parametrii (in mod direct) al oscilatorului extern +07 Mar 2003 - Portat partial(doar interfata) programul sub Windows +08 Mar 2003 - Adaugat Virtual Keyboard + - Cateva mici modificari in vederea portarii pt. windows + - Adaugat si controller la Virtual Keyboard +09 Mar 2003 - Adaugat pitch wheel la Virtual Keyboard si modificat putin controller-ul la VK +10 Mar 2003 - Adaugat Filter Frequency Tracking (adica modificarea frecventei filtrului in functie de frecventa notei) + - Marite eficienta la LFOparams - update lfotime + - Adaugat mod de normalize prin RMS + - Corectate doua erori la Distorsion (negate si mono+prefiltering) +11 Mar 2003 - In Windows, nu mai este necesar functiile getopt (scrisa o functie proprie) +12 Mar 2003 - Adaugat filtru la OscilGen +13 Mar 2003 - Adaugat mai multe filtre la OscilGen + - Facute optimzari la ADnote (adaugarea unui element la oscilsmp si fmsmp,etc.) si curatat putin codul sursa + - Corectata o eroare care amplifica fm-ul la rate de esantionare inalte + - Optimizat si curatat reverb-ul +16 Mar 2003 - Modificate optiunile de compilare in Makefile.inc si coduri sursa a.i. sa se realizeze portarea pe windows mai usor +17 Mar 2003 - Inregistrarea se face in formatul WAV si nu RAW + - Adaugat trigger la recorder (se incepe inregistrarea doar cand este apasata o nota) + - Adaugat interfata PortAudio + - Corectata eroarea care facea ca UI sa nu ruleze pt. Windows (trebuia dat show() la UI in thread-ul 3) si corectate alte erori din windows + - Si audio-ul functioneaza sub Windows + - Corectata o eroare care se manifesta foarte rar(Resonance, i era de la 0 si nu de la 1) +18 Mar 2003 - Adaugat interpolare la filtru (nu se mai aud tacanaituri, daca frecventa filtrului se schimba foarte rapid si semnalul contine putine armonice) + - Adaugat interfata Midi in Windows => consider ca programul este portat in Windows +19 Mar 2003 - Adaugat interfata de configurare + - Corectata o eroare la OscilGen care facea ca in loc ca amplitudinile sa fie reduse la -40,..,-100dB, sa fie setate la 1 si unde era intensitate mare sa file amplificate +20 Mar 2003 - Corectata o mica eroare la interfata (uneori disparea butonul ON de la ADvoice) +21 Mar 2003 - LANSAT PE INTERNET - VERSIUNEA (1.2.0) +-------------------------------------------------------------------------------------------------- + - Se interpoleaza filtrul si cand se trece peste pragul Nyquist (in sus sau in jos) +22 Mar 2003 - Corectata o eroare care facea ca nr. de esantioane scrise in headerul fisierului WAV sa nu fie initializat +26 Mar 2003 - Nu mai este permisa alegerea unui fisier wav in timpul pauzei de la record + - Gasita si corectata o eroare stupida (am pus la NRPN 0x98 in loc de 98 zecimal) +28 Mar 2003 - Inceput sa portez programul sub VST +29 Mar 2003 - Adaugat Master fine detune (-64.0 .. 63.0 cents) +01 Apr 2003 - Functioneaza portarea sub VST, dar mai este de lucru... +02 Apr 2003 - Modificat synth-ul a.i. sa se poate apela in mai multe instante in VST + - Continuata portarea in VST +03 Apr 2003 - Continuata portarea in VST (este limitat la o singura instanta) +05 Apr 2003 - Adaugata posibilitatea de a interschimba/copia parametrii efectelor + - Mici modificari la Makefile (ignora headerele inexistente la deps) +06 Apr 2003 - Adaugat posibilitatea de protectie impotriva atenuarii a notei fundamentale la rezonanta + - Pitch bend-ul merge bine in Windows +07 Apr 2003 - LANSAT PE INTERNET - VERSIUNEA (1.2.1) +-------------------------------------------------------------------------------------------------- + - Adaugat efect la part (adica efect care face parte din instrument ;-) ) +08 Apr 2003 - Adaugata interpolare la Resonance (peak-urile le interpoleaza) +09 Apr 2003 - Interfata la Envelope este o singura clasa + - Adaugat Envelope free mode (adica de orice forma) + - Adaugata posibilitatea de a copia de la o voce la alta la ADnote + - Release-ul este liniar (in loc de dB) +10 Apr 2003 - Adaugata afisarea ultimului fisier master salvat/incarcat + - Adaugata setarea notei minime/maxime la ultima nota + - Pot alege daca release-ul sa fie liniar + - Facute cateva corecturi la envelope +11 Apr 2003 - Curatat codul sursa la UI si impartit in mai multe fisiere .fl + - Corectate niste erori la Envelope si adaugat modul liniar/logaritmic la amplitudine +12 Apr 2003 - Inceput sa scriu kit-ul la part +13 Apr 2003 - Terminat de scris kit-ul la part+UI +14 Apr 2003 - Copierea vocilor este sub forma de clipboard + - ADsyn su SUBsyn check-urile de la PartUI sunt actualizate +15 Apr 2003 - LANSAT PE INTERNET - VERSIUNEA (1.4.0) +-------------------------------------------------------------------------------------------------- +16 Apr 2003 - Adaugat modul "Single" la instrument kit, care face ca sa sune doar primul instrument din kit disponibil +21 Apr 2003 - Adaugat realtime priority, care seteaza prioritatea mare la sintetizator, daca are posibilitate; merge numai pe Linux + - Gasite multe erori mici(dar potential periculoase) cu ajutorul programului Valgrind +30 Apr 2003 - Adaugat "Spectrum adjust" la OscilGen, care ajusteaza intensitatile armonicelor +03 Mai 2003 - Normalizat spectrul inaintea adjust-ului la OscilGen +04 Mai 2003 - Adaugat mod "egal temperat" la fixed frequency (440Hz), util la tobe +05 Mai 2003 - Adaugat modul "Drum mode", unde sistemul este intotdeauna temperat (12tET), toate notele sunt mapate si transpose-ul este ignorat +08 Mai 2003 - LANSAT PE INTERNET - VERSIUNEA (1.4.1) +-------------------------------------------------------------------------------------------------- +09 Iun 2003 - Am schimbat in .H in fisierele .fl (ca sa se poate compila si pe Debian) +10 Iun 2003 - Inceput sa modific interfata la filtru a.i. sa pot adauga filtrul formantic usor + - Interfata pentru filtru este o singura clasa +12 Iun 2003 - Inceput sa scriu panoul de part-uri (care afiseaza parametrii importanti ale part-urilor) + - VU-meter-ul poate afisa si intensitatea part-ului dorit (folosit la panou de part-uri) +13 Iun 2003 - Terminat panoul de part-uri + - Adaugat posibilitatea de a inchide automat fereastra bancii de instrumente, cand se incarca un instrument +19 Iun 2003 - Modificat modul cum se calculeaza frecventa filtrului (se fac doar adunari si doar la urma se ridica la putere) +22 Iun 2003 - Aproape terminat filtrul formantic (fara UI) +24 Iun 2003 - Merge mai multe instante in jack (alege porturi diferite) +26 Iun 2003 - Continuat de scris filtrul formantic +29 Iun 2003 - Adaugat vu-meter fals la Panel (in caz ca partul este dezactivat si primeste note on). De asemenea se arata daca in partul dezactivat s-a cantat ceva (apare o liniuta). +09 Iul 2003 - Inceput sa scriu interfata pentru filtrul formantic +10 Iul 2003 - Continuat filtrul formantic (interfata) +11 Iul 2003 - Eroarea vine de la Makefile pt. ca nu recompileaza si clasele care folosesc o anumita clasa, daca aceasta din urma se schimba + - Continuat filtrul formantic (interfata+adaugarea interpolarii la Q) +12 Iul 2003 - Adaugat la filtrul formantic setarile de amplitudine formanti si interpolarea acestora + - Adaugat grafic la UI-ul filtrului formantic si alti paramatrii la filtrul formantic +13 Iul 2003 - Corectata eroarea la FormantFilter care facea ca sa nu se interpoleze intre vocale + - Adaugat parametrul VowelClearness la FormantFilter care face ca sa se evite vocalele mixte +14 Iul 2003 - Inlaturat parametrul Psequence[].pos, pt. ca era confuz => fiecare vocala are zona egala + - Adaugat parametrii Psequencestretch si Psequencereversed la FormantFilter + - Adaugat parametrul Pgain la filtru (-30...30 dB) + - Terminat de scris Filtrul Formantic + - Corectata o eroare care facea ca sa nu se salveze oscilatorul la o ADnote_voce, daca vocea este dezactivata, chiar daca era folosita de o alta voce + - Prima data se cauta fisierul "default.bnk_zyn" si in dir "/usr/share/zynaddsubfx" sau "/usr/local/share/zynaddsubfx" +15 Iul 2003 - Setat Pkeylimit prestabilit la 15 la Part + - Activarea unui Part din interfata Panel schimba automat part-ul curent la acela + - Se poate alege ca un instrument din Kit sa fie procesat incepand cu un anumit efect; si se mai poate alege ca un efect din Part sa fie trimis in afara +17 Iul 2003 - LANSAT PE INTERNET - VERSIUNEA (1.4.2) +-------------------------------------------------------------------------------------------------- +21 Iul 2003 - Corectata o eroare la FilterUI care facea ca la fiecare afisare sa se initializeze FilterParames::Pgain la 64 +25 Iul 2003 - Corectata o eroare care facea ca modulatia in faza/frecventa sa sune diferit la diferite rate de esantionare/oscilsize +26 Iul 2003 - Afisat corect - valoarea OSCIL_SIZE ajustata (in caz ca a fost data optiunea "-o" incorect) + - In windows arata si numele la midi_in_device +04 Aug 2003 - Adaugat filtrele Peak,LowShelf,HighSelf la filtru si foloseste parametrul Gain de la interfata filtrelor +30 Aug 2003 - Adaugat un nou tip de filtru: State Variable Filter +31 Aug 2003 - LANSAT PE INTERNET - VERSIUNEA (1.4.3) +-------------------------------------------------------------------------------------------------- +02 Sep 2003 - Adaugata posibilitatea de a incarca de la inceput un fisier .mas_zyn "-l" + - Se poate lansa programul fara interfata utilizator ("-U") +17 Sep 2003 - Adaugat niste simple patch-uri de Frank Neumann +02 Oct 2003 - Corectata o eroare la SUBsynth care facea ca la freq inalte si Q foarte mici sa se produca filtre instabile +30 Oct 2003 - Adaugate posibilitatea (+interfata in config) de Dump (avansat) + - Adaugat ModWheel liniar si facut prestabilit (si posibilitatea de a alege in interfata modul de modwheel) +04 Nov 2003 - Modificat putin interfata la ResonanceUI +05 Nov 2003 - Marita viteza prin inlocuirea de (int) cu cod de asamblare (cu.10-50% la FM,chorus,etc.) +10 Nov 2003 - Inceput sa adaug posibilitatea de a adauga comentarii la instrumente +11 Nov 2003 - Terminat de adaugat comentariile/autor/tipuri la instrumente +12 Nov 2003 - Adaugat intefata pentru FFTW3 la fftwrapper +18 Nov 2003 - Inceput sa scriu Sequencer-ul +19 Nov 2003 - Adaugat un buton "i" pt. instrument info si facut ca instrument info sa se afiseze automat daca se schimba partul (sau se incarca instrumente,etc) +20 Nov 2003 - Continuat de scris Sequencer-ul si inceput sa ii scriu interfata + - Mici modificari la preset-urile de la Echo +26 Nov 2003 - Continuat de scris sequencerul - inceput sa scriu inregistrarea (fara timer) +27 Nov 2003 - Se poate inregistra (dar nu rula) - adaugat timerul de inregistrat + - Frecventa maxima al filtrelor este de Nyquist-500.0 pentru a evita instabilitatea filtrelor +28 Nov 2003 - Adaugata favorizarea portamento-ului in sus sau un jos; ex. se poate face ca portamento-ul sa fie doar in sus, sau portamento-ul in jos sa fie mai scurt decat cel in jos + - Inceput sa pun pe cvs la cvs.sourceforge.net +01 Dec 2003 - Am facut niste mici modificari ca urmare a unui bug-report +05 Dec 2003 - Facute cateva modificari la jack +08 Dec 2003 - Inceput sa incerc sa fac rt-safe sub jack, dar in stadiul actual suportul jack este nefunctional +11 Dec 2003 - Adaugat aleatorism la amplitudinile armonicelor +13 Dec 2003 - Adaugat LFO frequency randomness +14 Dec 2003 - Imbunatatit LFO frequency randomness +15 Dec 2003 - Corectata o mica eroare la ADnoteParameters (lipseau niste break-uri la salvarea/incarcarea parametrilor) +16 Dec 2003 - Eroarea cu break-urile se dovedeste a fi o eroare majora :( ; adica corectarea ei, necesita resalvarea tuturor instrumentelor + - Am revenit la suportul vechi de JACK, dar cel nou este disponiblil ca JACK_RT (nefunctional inca) +17 Dec 2003 - Inceput sa restucturez Part-ul (am adaugat clasele Instrument,InstrumentParams) - programul nu mai este compatibil cu versiunile anterioare + - RMS normalize este prestabilit la OscilGen +18 Dec 2003 - Continuat de restructurat Part-ul + +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +01 Feb 2004 - Revenit la versiunea din 16 Dec. 2003 + - Pus iarasi RMS normalize prestabilit la OscilGen + - M-am razgandit ;) nu mai restructurez part-ul; mai bine pun acolo o functie separata pentru salvari/incarcari par instrumente + - Inceput sa adaug suportul XML +02 Feb 2004 - Corectata o eroare care facea ca numele la instrumentele din bank sa fie aratate gresit (nu era pus un \0 ) + - Continuat suportul de XML +03 Feb 2004 - Continuat de scris suportul XML - inceput sa salvezi cativa parametrii +04 Feb 2004 - Se salveaza parametrii XML la master, part, filter, lfo, envelope, resonance si adnote (partial) +05 Feb 2004 - Se salveaza toti parametrii in XML +06 Feb 2004 - Adaugat salvarea de instrument in XML + - Adaugat export la bank intr-un director XML si decis ca bank-ul sa fie un director cu mai multe fisiere xml de forma XXXX-nume.xml sau XXXX-nume.xml.gz +07 Feb 2004 - Adaugat functii de initializare si renuntat la masterdefaultbuf si instrumentdefaultbuf (adica salvarea la inceput si incarcarea bufferelor cu instrumentele prestabilite) + - Corectata o mica eroare care facea ca sa se incarce subnotepars la adnotepars (eroarea a aparut azi) +08 Feb 2004 - Modificat putin formatul XML +10 Feb 2004 - Adaugata salvarea parametrilor pt. basefunction la OscilGen + - Inceput sa scriu incarcarea parametrilor +11 Feb 2004 - Se pot incarca cativa parametrii de la master +12 Feb 2004 - Continuat incarcarea parametrilor XML si la part (neterminat) +13 Feb 2004 - Terminat de adaugat parametrii la incarcarea XML +14 Feb 2004 - Se poate incarca si instrumente + - Rezolvata o problema la coarse detune + - Corectate cateva erori la incarcarea XML-ului + - Frecventa LFO-ul de la instrumente are valoare reala intre 0..1 + - Corectata eroarea care facea ca functia de rezonanta sa fie trasata incorect + - Adaugata compresie gzip la fisiere si decompresie automata la incarcare (folosesc biblioteca zlib) +15 Feb 2004 - O mica modificare la envelope parameters in sensul ca envelope-ul prestabilit la FM nu mai este liniar +22 Feb 2004 - Adaugat normalize Full RMS la Oscil +23 Feb 2004 - Inceput sa fac ca sa pot adauga Bank bazat pe XML (adaugat temporar clasa OldBank) +24 Feb 2004 - Continuat la Bank +25 Feb 2004 - La Bank - inceput sa scriu partea ca sa arate instrumentele din banca +26 Feb 2004 - Continuat la Bank +27 Feb 2004 - Corectate erori la snprintf (nu dadeam parametru "%s" inainte de string si daca acel string continea ceva %, era periculos) si alte erori + - Micsorat timpul de marire amplitudine la ADnote (doar in cazul cand amplitudinea creste brusc ca la un LFO expdown) + - Corectata o eroare foarte veche la LFO amplitudine (amplitudinea nu scadea corespunzator) +28 Feb 2004 - Se poate incarca si salva instrumente in Bank +01 Mar 2004 - Se pot schimba bancile de instrumente + - Introduse si celelalte functii la Bank (cu exceptia salvarii/incarcarii locului bancii folosite) + - Se poate importa banci din bnk_zyn +03 Mar 2004 - Terminat (teoretic) partea de XML +05 Mar 2004 - Actualizat Copyright-ul la 2004 in fisiere +08 Mar 2004 - Corectat o mica eroare la OscilGen (se aplica gain-ul rezonantei incorect) +09 Mar 2004 - Adaugata posibilitatea de stretch la LFO in functie de frecventa notei +12 Mar 2004 - Adaugata modulatie la OscilGen (functia de baza) +13 Mar 2004 - Adaugat HarmonicShift la oscilgen +15 Mar 2004 - Inceput sa scriu partea de incarcare MIDI + - Inlaturata partea de recording din Sequencer +16 Mar 2004 - Inceput sa scriu partea de analiza midi +25 Mar 2004 - Continuat partea de analiza midi +28 Mar 2004 - Scris partea de incarcat fisier midi + - Merge partial playerul +26 Mai 2004 - Playerul merge bine cu un canal midi (rezolvata problema cu timing-ul) +03 Iun 2004 - Adaugata partea de play speed la interfata +06 Iun 2004 - Adaugata functia sigmoid la distorsionare +12 Iun 2004 - Modificat modul cum este realizat bank-urile, adica directoarele de bank-uri exista in anumite directoare si aceste directoare sunt cautate automat de bankuri; adaugat optiunea de a se folosi mai multe bank-uri +13 Iun 2004 - Adaugat filtrul "sinus" la OscilGen + - Managementul bancilor de instrumente este complet + - Se cauta bancile si in '/usr/share/zynaddsubfx/banks' si '/usr/local/share/zynaddsubfx/banks' + - Corectata o eroare la filter la OscilGen care filtra diferit componentele sin si cos + - Adaugat posibilitatea de swap la instrumentele din bank +14 Iun 2004 - Adaugat __DATE__ si __TIME__ sa stiu cand s-a compilat + - Modificat interfata la PartUI + - Imbunatatit modulatia basefunc la OscilGen (adaugat inca un parametru si inca un tip de modulatie ("power")) + - Adaugat inca o noua functie basefunc la OscilGen (sqr=atan(sin(x)*a)) +15 Iun 2004 - Adaugat posibilitatea de a face armonicele ca sa depinda de frecventa ("adaptive") si rezultatul suna foarte frumos pentru ca tendinta este de pastrare a frecventelor armonicelor si nu a numarului de ordine al lor +16 Iun 2004 - Inceput sa trec configul pe XML +17 Iun 2004 - Adaugat tipul threshUp la spectrum adjust + - Terminat de trecut config-ul pe XML (inclusiv setarile bancilor de instrumente) +18 Iun 2004 - Incercata interpolarea cubica dar am vazut ca nu merita pentru ca OSCIL_SIZE e suficient de mare si pentru o interpolare liniara + - Separat OscilGenUI din ADnoteUI + - Inceput sa scriu modulul de sinteza PADnote +19 Iun 2004 - Adaugat modul liniar de controller bandwidth si modificat modul liniar la controllerul modulation wheel + - Adaugata modulatia in frecventa la OsciGen +20 Iun 2004 - Nu se mai deschide automat fereastra de instrumente daca a fost deschisa si s-a descarcat un instrument + - Facute mici modificari la FM-ul de la Oscil +21 Iun 2004 - Inceput sa scriu conversia in sinus +22 Iun 2004 - Continuat conversia in sinus si facut teste pentru posibilitatea de "draw" cu sliderele +23 Iun 2004 - Modificat modul in care parametrii se afiseaza la OscilGen (este o functie "refresh" care face asta) + - Adaugata posibilitatea de draw la armonicele OscilGen daca se apasa tasta Shift + - Corectata o mica eroare care facea imposibila modificarea amplitudinii armonicelor cu tastatura + - Adaugat randomness de grup (adica se aplica acelasi randomness la toate vocile care folosesc acelasi oscilator) +24 Iun 2004 - Inlaturata setara de normalize la OscilGen. Intotdeauna normalize este Full RMS + - Facute cateva imbunatatiri la interfata unde sunt inlocuite comuter-urile cu setari mai usor de inteles de catre utilizator (ex. la efectele de insertie se arata "insert to Master Out" in loc de "-2") +29 Iun 2004 - Inlaturata setarea cu gain la Resonance pentru ca este inutil (datorita faptului ca normalize este Full RMS intotdeauna) +30 Iun 2004 - Inlaturata o eroare recenta la EffectUI si modificat EffectUI in sensul ca nu trebuie sters si reinstantiat pentru a se reincarca valorile curente de efecte + - Inceput sa scriu un nou efect (DynamicFilter) +01 Iul 2004 - Corectata o mica eroare la EffectUI care facea ca efectele sa nu apara activate + - Continuat de scris la DynamicFiter (mai este doar de salvat parametrii si de auto-update la filtru) +02 Iul 2004 - Continuat la DynamicFilter (adaugata auto-update, adaugat preset-uri) + - Terminat DynamicFilter + - Corectata o eroare la EQui care facea ca sa nu se actualizeze efectul curent si sa nu se obtina graficul egalizatorului +03 Iul 2004 - Corectata o mica eroare care nu activa la EffectUI daca efectul anterior era dezactivat + - Actualizat Swap/Copy la efecte ca sa proceseze si parametrii la filtre + - Adaugat Bypass la efectele de instrument + - Imbunatatit interfata utilizator (eliminate setarile "-1",etc.) + - Scris calcularea profilului la PADsynth + - Adaugat OscilGen si Resonance la PADsynth si inceput sa scriu interfata utilizator la PADsynth +04 Iul 2004 - Adaugata calcularea automata a largimii de banda echivalente si afisarea ei + - Inceput sa scriu partea de sinteza la PADsynth + - Auzit primul sunet la PADsynth +05 Iul 2004 - Nu mai face urat daca schimb parametrii in timp ce cant si apas apply + - Adaugat harmonic scale si position la PADsynth + - Se calculeaza corect si armonicele cu largime de banda mare +06 Iul 2004 - Inceput sa adaug filtre,lfo,envelopes,etc. la PADsynth +07 Iul 2004 - Corectate cateva mici erori si adaugat autoscale + - Modificata putin interfata de la filtru + - Adaugata interfata si parametrii la LFOs,Envelopes,Filter la PADsynth + - Adaugata fereastra care arata pozitiile armonicelor si continuat de lucru la acestea +08 Iul 2004 - La pozitiile armonicelor sunt aratate si valorile lor reale in dB + - Alte adaugiri minore la PADsynth + - Adaugat interpolare cubica la PADsynth +09 Iul 2004 - Modificat modul cum se calculeaza profilul armonicelor la PADsynth (nu se mai ridica la patrat) + - Corectate cateva erori la PADsynth + - Modific amplitudinea in functie de sqrt(largime de banda) => amplitudinile armonicelor sunt echivalente cu oscil +11 Iul 2004 - Acum nu se mai intrerupe sunetul la notele care canta in timp ce sunt aplicate modificarile la parametrii + - Se poate alege marimea sample-lui + - Adaugat multisampling la PADsynth + - Cand se incarca parametrii ADsynth se da volumul ceva mai incet ca sa corecteze faptul ca normalize-ul este doar RMS +12 Iul 2004 - Inlocuit codul de D/W sau Volume de la efecte cu un cod unic in EffectMgr + - Se poate face efecte la instrumente la care doar semnalul Wet e procesat de efectele urmatoare + - Modificat modul cum se calculeaza intensitatea Wet la Reverb si Echo + - Corectata eroarea la FM care facea ca daca Adaptive Harmonics!=0 sa se calculeze FM-ul gresit +13 Iul 2004 - Rezonanta la PADsynth se face in functie de armonica reala si nu de numarul de ordine al armonicei + - LFO,Envelope, Filters, etc. merg la PADnote + - Inceput sa fac partea de aratare ca parametrii au fost schimbati (butonul "Apply" se coloreaza in rosu) +14 Iul 2004 - Butonul Apply la PADsynth se coloreaza in rosu cand se modifica ceva + - Adaugat fixed freq. la PADsynth + - Sunt salvati si parametrii PADsynth => consider in mod oficial ca PADsynth este complet +15 Iul 2004 - Facuta o modificare la PADnoteUI care arata foarte frumos + - Completata partea de save/load si stabilite noile extensii ale fisierelor: master - .XMZ, instrument - .XIZ, microtonal - .XSZ + - Inlocuit memset cu un macro (ZERO) pentru ca memset nu seteaza toate valorile ci uneori doar prima valoare cu 0 (e o optimizare la gcc care face asta) + - Corectate niste erori la makefile care aveau legatura cu compilarea in windows + - Corectate 2 erori referitor la Banci de instrumente +16 Iul 2004 - Adaugat inca noi tipuri de harmonic bandwidth scale + - Adaugat inca un parametru la filter la OscilGen si inca un nou tip de filtru +17 Iul 2004 - Corectata o eroare care facea sa crape programul uneori dupa ce scria instrumentul in banca + - Modificata optiunea -l ca sa incarce un .xmz + - LANSAT PE INTERNET - VERSIUNEA (2.0.0pre1) +-------------------------------------------------------------------------------------------------- +18 Iul 2004 - Corectata o mica eroare la afisare care facea ca la PADnoteUI sa fie trasate liniile in mod gresit +19 Iul 2004 - Corectata doua mici erori (se incarca gresit parametrii filtrului de la OscilGen) + - Corectata inca o mica eroare care facea ca sa nu se coloreze butonul PAD_Synth Apply in rosu la anumiti parametrii de la oscilgen + - Se dezactiveaza butoanele Edit de la PartUI ca sa nu se poata edita module de sinteza inactive +20 Iul 2004 - Corectate cateva erori cu compilare pe windows +21 Iul 2004 - Corectata o mica eroare la Bank si alte erori +26 Iul 2004 - Acum este folosita biblioteca mxml-2 + - Corectata o eroare care facea ca sample-ul la PADnote sa nu fie ales in functie de frecventa reala de baza (cu detune) + - Mutat functiile de waveshaping in Distorsion.C/.h +27 Iul 2004 - Corectata o eroare foarte suparatoare care bloca uneori calculatorul + - Adaugat inca un nou parametru la PADsynth la base function + - Nu se mai arata butonul de apply parameters la PADsynth cand nu este necesar + - Eliminate blocarile de cateva secunde din threadul de sunet in momentul cand se incarca un nou instrument care contine parametrii PADsynth + - Adaugata schimbarea titlului ferestrei principale la load XML +29 Iul 2004 - Modificat modul cum este stocat lista de banci root dir + - Gasita o eroare care facea ca sa se stearga denormalkillbuffer inaintea lui master +30 Iul 2004 - Gasite si corectate o gramada de erori (eu stergeam elemente din ferestre si fltk le stergea din nou) + - Eliminate warning-urile pentru -Wall +31 Iul 2004 - Eliminate complet stergerile in plus de la UI din destructorele obiecte + - LANSAT PE INTERNET - VERSIUNEA (2.0.0pre2) +-------------------------------------------------------------------------------------------------- +01 Aug 2004 - Adaugat un nou tip de OvertonesPosition la PADsynth +02 Aug 2004 - Am pus din nou schimbarea schedule-ului la valoare corecta (l-am scos dintr-o greseala) +04 Aug 2004 - Am corectat niste erori la VST + - Merge VST, dar nu intotdeauna stabil (merge stabil pe vsthost.exe) + - Corectata eroare care facea ca sa nu mearga MIDI + - LANSAT PE INTERNET - VERSIUNEA (2.0.0pre2 VST) +-------------------------------------------------------------------------------------------------- +13 Aug 2004 - Inceput sa scriu modurile continous si discrete la PADnote +14 Aug 2004 - Terminat modul continous la PADnote + - Corectata o mica eroare la OscilGen care facea daca adaptive harmonics e activ si phase randomness>0 sa rezulte si aleatorism in amplitudinile armonicelor + - Inceput sa scriu Presets/Clipboard (Clipboardul, in stadiu actual va putea copia doar parametrii folositi si nu cei dezactivati) + - Merge partial partea de Copy in clipboard +15 Aug 2004 - Corectata o eroare in main.c la pitch bend + - Scos Swap/Copy la efecte si la PartUI si vechiul Copy/Paste de la ADnote voice + - Merge clipboardul la Oscil, Resonance, Filter si partial la ADsynth,SUBSynth si PADsynth +16 Aug 2004 - Corectata inca o eroare la pitch bend (aratata de Krzysztof Korpiela) + - Adaugat refresh si la Filtru si paste la ADnote, SUBnote si PADsynth sunt complete +17 Aug 2004 - Adaugat clipboard la LFO, Envelope, ADnoteVoice si Filter Vowel +18 Aug 2004 - In clipboard se salveaza toti parametrii (chiar si cei dezactivati) + - Corectata o eroare care facea ca instrumentul sa fie incarcat la fiecare salvare in banca + - Tipurile de lfo sunt compatibile intre ele la clipboard +19 Aug 2004 - Corectata o mica eroare la XMLwrapper care facea ca sa se salveze fortat toti parametrii (chiar si cei nefolositi) + - Adaugata partea de salvare/incarcare a listei directoarelor unde se afla presetarile +21 Aug 2004 - Am lucrat putin la salvare/incarcare a listei dir. cu presetari +22 Aug 2004 - Corectata o eroare de compilare + - Makefile-ul modificat, a.i. make-ul sa se opreasca in caz de eroare + - Terminat managerul de preset-uri +23 Aug 2004 - Adaugata posibilitatea de a se vedea direct din lista cu bancile de instrumente +24 Aug 2004 - Inlaturat complet suportul pentru formatele *.mas_zyn, *.ins_zyn, *.bnk_zyn si *.scl_zyn + - Ascuns Sequencer-ul de utilizator (o sa il continui mai incolo) +25 Aug 2004 - Listele de banci si de preset-uri sunt sortate + - Corectate niste erori la Oscilgen care faceau ca sa se calculeze randomness chiar daca este folosit de PADsynth si pus automat parametrul randomness daca PADsynth este folosit (in caz ca se va importa la un ADsynth) + - Gasita o eroare care face sa crape daca lucrez mult cu bancile de instrumente +27 Aug 2004 - Adaugata posibilitatea de a dezactiva aratarea starii PADsynth din instrumente + - LANSAT PE INTERNET - VERSIUNEA (2.0.0) +-------------------------------------------------------------------------------------------------- +05 Sep 2004 - Corectata o mica eroare de la SUBnote (legat de pitch wheel) +06 Sep 2004 - Eliminata variabila "disablekitloading" din Part si din UI +07 Sep 2004 - Modificat id-ul vst in 'zasf' (inainte era de 5 litere si poate cauza un crash la host) +27 Sep 2004 - Corectat un mic bug la salvare in xml la parametrul FMcoarseDetune din adnote + - La VST, daca incerc sa inchid fereastra principala, se minimizeaza + - Eliminate setarile cu indice '0' (zero) +28 Sep 2004 - Adaugata salvarea tuturor parametrilor in hostul VST (trebuie testat) + - Adaugat installer pt. windows (cu NSIS) +29 Sep 2004 - Inceput sa scriu interfata utilizator pt. incepatori +30 Sep 2004 - Terminat de scris interfata utilizator pt. incepatori si se selecteaza la pornire modul dorit + - Adaugata posibilitatea de a compila cu suport jack si oss simultan si sa se aleaga runtime ce doresc (jack/oss) +01 Oct 2004 - Corectata o mica eroare care facea ca sa nu se inchida ferestrele cu instrumente cand incarc din banca + - LANSAT PE INTERNET - VERSIUNEA (2.1.0) +-------------------------------------------------------------------------------------------------- +02 Oct 2004 - Corectata o eroare grava care facea ca sa nu pot schimba partul curent in interfata utilizator obisnuita +03 Oct 2004 - LANSAT PE INTERNET - VERSIUNEA (2.1.1) +-------------------------------------------------------------------------------------------------- +04 Oct 2004 - Corectata o eroare care face ca in modul simple UI, sa se inverseze panning-ul + - Adaugat un icon la ZynAddSubFX +10 Oct 2004 - Si controllerul de Resonance se aplica la toate item-urile din kit +12 Oct 2004 - Corectata o eroare care facea ca butoanele Addpoint si Delpoint de la Envelope sa nu fie afisate +16 Oct 2004 - Corectata o eroare care facea ca partUI-ul sa nu se actualizeze intotdeauna cand incarcam un instrument +20 Oct 2004 - Corectata o mica eroare asemanetoare cu cea din 16 Oct, dar care afecta meniul new +07 Nov 2004 - Corectata o mica eroare care facea ca sa nu se incarce corect instrumentele in linia de comanda (-l) +14 Nov 2004 - Nu mai verific in bank daca este un director sau fisier simplu, pt. ca poate sa aiba probleme +28 Nov 2004 - Curatat codul la OscilGen (acum datele sunt stocate mai bine si nu in functie de biblioteca FFTW) + - Corectata o mica eroare la OscilGen cu adaptive harmonics care facea ca energia vechilor armonice sa nu se adauge in mod corect la noile armonice (la note inalte) + - Sortarea nu mai este quicksort la bank si la presets pt. ca am vazut ca nu merge in windows intotdeauna + - Corectata o eroare la egalizator care facea ca sa se aplice si la el par. D/W +29 Nov 2004 - Marita zona de valori la adaptive harmonics power din OscilGen + - Adaugata posibilitate de a post-procesa la adaptive harmonics(adica a adauga sau a amplifica anumite armonice) +05 Dec 2004 - Corectata o eroare care facea ca functiile getChunk si setChunk sa fie supraincarcate in loc de suprascrise (dar nu am testat) + - Corectata o eroare care returna gresit la canDo in vst (netestat) +17 Dec 2004 - Inceput sa folosesc Dvorak pt. VK +18 Dec 2004 - Continuat putin la VK +20 Dec 2004 - Se poate selecta la VK dintre "qwerty" si "Dvorak" + - Corectata o mica erare care facea sa nu arate BWprofile dezactivat la PADnote + +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + +04 Ian 2005 - Corectata o mica eroare care facea ca sa nu arate Force Release la Freemode Envelope +15 Ian 2005 - Corectata o eroare la controllerul bandwidth care facea ca sa ajunga la valoarea 0 si sa dea peste cap SUBsynth +22 Ian 2005 - Inceput sa scriu suportul pt. DSSI +27 Ian 2005 - Corectata eroare care facea ca in cazul in care sunt 2 banci cu acelasi nume (sau aceeasi bank root dir sa fie selectat de 2 ori) sa produca confuzie +03 Feb 2005 - Inceput sa scriu la Microtonal ca sa se faca butonul apply de culoare rosie cand se schimba ceva +06 Feb 2005 - Facuta o mica modificare care interzice punera notelor "0" in dump si alta modificare care mareste nr. de octave calculate la PADsynth + - Renuntat sa fac modificarea la Microtonal inceputa din 03 Feb, pentru ca nu am gasit cum pot schimba culoarea butonului automat cand modific un text +07 Feb 2005 - Corectata o eroare care facea ca la microtonal mapping sa nu se calculeze corect (adica sa se stocheze valoarea corecta) +12 Feb 2005 - Controllerul prestabilit la Virtual Keyboard este Filter Cutoff in loc de BandWidth + - Modificate cateva preseturi la DynamicFilter + - Adaugata posibilitatea de a mari sau micsora cu un parametru detune-ul vocilor de la ADnote +17 Feb 2005 - Corectate cateva erori la PADsynth care faceau ca sa se citeasca date din zone de memorie nealocata + - Corectata o eroare la Bank care facea ca uneori sa crape programul cand umblam mult cu bankuri +19 Feb 2005 - Corectata o eroare care facea ca uneori sa fie calculata frecventa la ADnote=nan si programul sa crape pentru ca era folosit parametrul bandwidthDetuneMultiplier inainte de a fi calculat +21 Feb 2005 - Se afiseaza corect numele fisierului proaspat salvat in fereastra principala +26 Feb 2005 - Corectata eroarea la windows si la OSS care facea ca pitch bend sa nu fie mapat corect (trebuie verificat) +27 Feb 2005 - Se afiseaza corect valoarea lui detune in centi +28 Feb 2005 - Corectata o mica eroare care facea ca sa nu se afiseze intotdeauna corect detune-ul la ADvoice + - Afisajul VU-meter la Master nu mai prezinta variatii mari in timp scurt + - Adaugata afisajul RMS la VU-meter +06 Mar 2005 - Facute cateva mici modificari referitoare in special la warning-uri + - Corectata o mica eroare care facea ca la un Paste sa nu se actulizeze unii parametrii ai filtrului in interfata +12 Mar 2005 - Imbunatatiri la interfata PADsynth, adica se poate da "apply" direct din OscilGenUI sau ResonanceUI +13 Mar 2005 - Facute cateva compilari in Makefile pt. compilare pt. Windows (standalone exe si vst) + - Se compileaza in mod cross-compile pt. windows din linux +14 Mar 2005 - Mici modificari la afisarea RMS-ului + - Actualizat textul copyright-ului la anul 2005 +22 Mar 2005 - Corectata o mica eroare care facea ca la schimbari foarte lente al parametrilor sa nu se actualizeze Format Filter +25 Mar 2005 - Corectata o eroare care facea ca uneori, la anumite setari ale lui SepctrumAdjust din OscilGen sa rezulte semnal zero + Corectata o mica eroare care facea ca daca se foloseste setarea 440Hz la Padsynth sa se aleaga sample-ul incorect +06 Apr 2005 - Modificat installerul pt. windows si pregatit pt. installer (folosit cross-compiling si nsis&wine) + - Adaugat icon in format windows (si la installer) + - Adaugat parametrul '-Y' la linia de comanda, care este folosit doar pentru installerul NSIS (parametrul este necesar pentru ca NSIS ma forteaza sa dau un parametru la program pentru ca sa adauge un icon la shortcut; zynaddsubfx ignora acest parametru) +07 Apr 2005 - Pregatit pentru release +08 Apr 2005 - Corectata o mica eroare care facea ca sa nu se incarce configul la inceput + - LANSAT PE INTERNET - VERSIUNEA (2.2.0) +-------------------------------------------------------------------------------------------------- +12 Apr 2005 - Actualizat pentru MXML 2.2 (nu o sa mearga pe vers. mai vechi de mxml) +27 Apr 2005 - Adaugata posibilitatea de a inlatura complet interfata grafica in Makefile.inc (in acest caz nu mai sunt necesare bibliotecile grafice ca fltk) + - Adaugata posibilitatea de a incarca direct un instrument cu -L (deocamdata se poate incarca doar in part-ul 0) + - LANSAT PE INTERNET - VERSIUNEA (2.2.1) +-------------------------------------------------------------------------------------------------- +28 Apr 2005 - Corectata o eroare care facea ca uneori sa fie frecventa prea mare la LFO daca era folosit random + - Nu mai afiseaza optionea -A in help daca nu este compilat si OSS si JACK +29 Mai 2005 - Corectata o eroare care facea ca sa nu se tina minte ultimul bank +27 Aug 2005 - Corectata o eroare care facea ca sa nu mearga functia Dump (se initializa inainte de citirea configurarilor) +21 Sep 2005 - Imbunatatit modul de scalare al profilei unei armonice la PADsynth +27 Sep 2005 - Gasita si rezolvata o posibila problema la PADsynth care facea ca sa nu se foloseasca mutex la stergerea de sample-uri (daca se aleg mai putine sample-uri decat initial) +09 Oct 2005 - Rezolvat un memory-leak la FFTwrapper + +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +16 Apr 2006 - Corectata o eroare care facea ca sa nu se foloseasca insertion effect la master +20 Aug 2006 - Adaugat 88200 ca rata de esantionare +14 Sep 2006 - Se afiseaza spectrul la nota cu frecventa de 440 Hz la Oscil si pentru parametru Adaptive Harmonics +30 Oct 2006 - Adaugat un patch "standalone zombie fix stripped from Lars" + - Adaugat un patch "Extended mono" si "font resizing stuff" de Gerald Folcher +31 Oct 2006 - Adaugat un patch "Extended mono v.3" de Gerald Folcher + - Inlocuit fl_ask cu fl_choice in fisierele .fl + - In mod prestabilit nu se mai seteaza volumul la efectul 0 + - Efectele sunt numerotare de la 1 si in la "send to" din partui +01 Nov 2006 - Adaugat patch-urile de Jack Midi si LASH de Lars Luthman +06 Nov 2006 - Aplicat un patch "Fix for ALSA system lockup" de Lars Luthman +10 Nov 2006 - Aplicat un patch "zyn-extendedmono_v4_update-061110.diff.gz" de Gerald Folcher +14 Nov 2006 - Aplicat un patch "zyn-CVS-extendedmono_v5_update-061113.diff.gz" de Gerald Folcher + +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +19 Mar 2007 - Aplicat un patch mic de la Daniel Clemente care este un workaround la bug-ul X11 cand tin tastele apasate mai mult timp +01 Apr 2007 - O mica modificare cu xclass zynaddsubfx in MasterUI.fl +09 Sep 2007 - Schimbata licenta la GPL 2 or other later + +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +02 Ian 2008 - Corectate cateva mici erori la dezalocarea memoriei + - Codul de recorder wav a fost rescris + - Adaugata functia de export la sample-urile din PADsynth + +20 Feb 2009 (Mark McCurry) + - Made several functions accept 'constant char' over 'char' to + prevent warnings + - Changed several 'delete' operations to 'delete []' based upon + the usage of 'new []' + - Gave external programs Makefiles + - Gave dials tooltips showing their value when they are being + moved + - Gave dials the ability to have normal tooltips when the mouse + hovers over them + - Created tooltips for the effects knobs + - Standardized the code, so it could compile with pedantic without + errors [it looks like some errors may have ben missed] + +22 Feb 2009 (Mark McCurry) + - Fix improper deallocation in PresetsStore + - Fixed errors with drawing of the Oscillator as reported with + valgrind + +07 Mar 2009 (Mark McCurry) + - Added start of DocBook documentation + - Incorperated JACK output patch by Emmanuel Saracco + - Incorperated QUERTZ layout by Achim Settelmeier + +29 Mar 2009 (Mark McCurry) + - Started to use Doxygen within the Effects + - Started to use const within Effects + - Changing tabs->four spaces in hopes of generating a bit more + consitancy + - Began to use Initialization Lists + - Almost all changes contained in Effects until further + discussion on the style, so consistancy can be reached + diff --git a/plugins/zynaddsubfx/src/DSP/AnalogFilter.C b/plugins/zynaddsubfx/src/DSP/AnalogFilter.C new file mode 100644 index 000000000..934904263 --- /dev/null +++ b/plugins/zynaddsubfx/src/DSP/AnalogFilter.C @@ -0,0 +1,358 @@ +/* + ZynAddSubFX - a software synthesizer + + AnalogFilter.C - Several analog filters (lowpass, highpass...) + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include +#include +#include "AnalogFilter.h" + +AnalogFilter::AnalogFilter(unsigned char Ftype,REALTYPE Ffreq, REALTYPE Fq,unsigned char Fstages){ + stages=Fstages; + for (int i=0;i<3;i++){ + oldc[i]=0.0;oldd[i]=0.0; + c[i]=0.0;d[i]=0.0; + }; + type=Ftype; + freq=Ffreq; + q=Fq; + gain=1.0; + if (stages>=MAX_FILTER_STAGES) stages=MAX_FILTER_STAGES; + cleanup(); + firsttime=0; + abovenq=0;oldabovenq=0; + setfreq_and_q(Ffreq,Fq); + firsttime=1; + d[0]=0;//this is not used + outgain=1.0; +}; + +AnalogFilter::~AnalogFilter(){ +}; + +void AnalogFilter::cleanup(){ + for (int i=0;ifreq; + if (freq>(SAMPLE_RATE/2-500.0)) { + freq=SAMPLE_RATE/2-500.0; + zerocoefs=1; + }; + if (freq<0.1) freq=0.1; + //do not allow bogus Q + if (q<0.0) q=0.0; + REALTYPE tmpq,tmpgain; + if (stages==0) { + tmpq=q; + tmpgain=gain; + } else { + tmpq=(q>1.0 ? pow(q,1.0/(stages+1)) : q); + tmpgain=pow(gain,1.0/(stages+1)); + }; + + //most of theese are implementations of + //the "Cookbook formulae for audio EQ" by Robert Bristow-Johnson + //The original location of the Cookbook is: + //http://www.harmony-central.com/Computer/Programming/Audio-EQ-Cookbook.txt + switch(type){ + case 0://LPF 1 pole + if (zerocoefs==0) tmp=exp(-2.0*PI*freq/SAMPLE_RATE); + else tmp=0.0; + c[0]=1.0-tmp;c[1]=0.0;c[2]=0.0; + d[1]=tmp;d[2]=0.0; + order=1; + break; + case 1://HPF 1 pole + if (zerocoefs==0) tmp=exp(-2.0*PI*freq/SAMPLE_RATE); + else tmp=0.0; + c[0]=(1.0+tmp)/2.0;c[1]=-(1.0+tmp)/2.0;c[2]=0.0; + d[1]=tmp;d[2]=0.0; + order=1; + break; + case 2://LPF 2 poles + if (zerocoefs==0){ + omega=2*PI*freq/SAMPLE_RATE; + sn=sin(omega); + cs=cos(omega); + alpha=sn/(2*tmpq); + tmp=1+alpha; + c[0]=(1.0-cs)/2.0/tmp; + c[1]=(1.0-cs)/tmp; + c[2]=(1.0-cs)/2.0/tmp; + d[1]=-2*cs/tmp*(-1); + d[2]=(1-alpha)/tmp*(-1); + } else { + c[0]=1.0;c[1]=0.0;c[2]=0.0; + d[1]=0.0;d[2]=0.0; + }; + order=2; + break; + case 3://HPF 2 poles + if (zerocoefs==0){ + omega=2*PI*freq/SAMPLE_RATE; + sn=sin(omega); + cs=cos(omega); + alpha=sn/(2*tmpq); + tmp=1+alpha; + c[0]=(1.0+cs)/2.0/tmp; + c[1]=-(1.0+cs)/tmp; + c[2]=(1.0+cs)/2.0/tmp; + d[1]=-2*cs/tmp*(-1); + d[2]=(1-alpha)/tmp*(-1); + } else { + c[0]=0.0;c[1]=0.0;c[2]=0.0; + d[1]=0.0;d[2]=0.0; + }; + order=2; + break; + case 4://BPF 2 poles + if (zerocoefs==0){ + omega=2*PI*freq/SAMPLE_RATE; + sn=sin(omega); + cs=cos(omega); + alpha=sn/(2*tmpq); + tmp=1+alpha; + c[0]=alpha/tmp*sqrt(tmpq+1); + c[1]=0; + c[2]=-alpha/tmp*sqrt(tmpq+1); + d[1]=-2*cs/tmp*(-1); + d[2]=(1-alpha)/tmp*(-1); + } else { + c[0]=0.0;c[1]=0.0;c[2]=0.0; + d[1]=0.0;d[2]=0.0; + }; + order=2; + break; + case 5://NOTCH 2 poles + if (zerocoefs==0){ + omega=2*PI*freq/SAMPLE_RATE; + sn=sin(omega); + cs=cos(omega); + alpha=sn/(2*sqrt(tmpq)); + tmp=1+alpha; + c[0]=1/tmp; + c[1]=-2*cs/tmp; + c[2]=1/tmp; + d[1]=-2*cs/tmp*(-1); + d[2]=(1-alpha)/tmp*(-1); + } else { + c[0]=1.0;c[1]=0.0;c[2]=0.0; + d[1]=0.0;d[2]=0.0; + }; + order=2; + break; + case 6://PEAK (2 poles) + if (zerocoefs==0){ + omega=2*PI*freq/SAMPLE_RATE; + sn=sin(omega); + cs=cos(omega); + tmpq*=3.0; + alpha=sn/(2*tmpq); + tmp=1+alpha/tmpgain; + c[0]=(1.0+alpha*tmpgain)/tmp; + c[1]=(-2.0*cs)/tmp; + c[2]=(1.0-alpha*tmpgain)/tmp; + d[1]=-2*cs/tmp*(-1); + d[2]=(1-alpha/tmpgain)/tmp*(-1); + } else { + c[0]=1.0;c[1]=0.0;c[2]=0.0; + d[1]=0.0;d[2]=0.0; + }; + order=2; + break; + case 7://Low Shelf - 2 poles + if (zerocoefs==0){ + omega=2*PI*freq/SAMPLE_RATE; + sn=sin(omega); + cs=cos(omega); + tmpq=sqrt(tmpq); + alpha=sn/(2*tmpq); + beta=sqrt(tmpgain)/tmpq; + tmp=(tmpgain+1.0)+(tmpgain-1.0)*cs+beta*sn; + + c[0]=tmpgain*((tmpgain+1.0)-(tmpgain-1.0)*cs+beta*sn)/tmp; + c[1]=2.0*tmpgain*((tmpgain-1.0)-(tmpgain+1.0)*cs)/tmp; + c[2]=tmpgain*((tmpgain+1.0)-(tmpgain-1.0)*cs-beta*sn)/tmp; + d[1]=-2.0*((tmpgain-1.0)+(tmpgain+1.0)*cs)/tmp*(-1); + d[2]=((tmpgain+1.0)+(tmpgain-1.0)*cs-beta*sn)/tmp*(-1); + } else { + c[0]=tmpgain;c[1]=0.0;c[2]=0.0; + d[1]=0.0;d[2]=0.0; + }; + order=2; + break; + case 8://High Shelf - 2 poles + if (zerocoefs==0){ + omega=2*PI*freq/SAMPLE_RATE; + sn=sin(omega); + cs=cos(omega); + tmpq=sqrt(tmpq); + alpha=sn/(2*tmpq); + beta=sqrt(tmpgain)/tmpq; + tmp=(tmpgain+1.0)-(tmpgain-1.0)*cs+beta*sn; + + c[0]=tmpgain*((tmpgain+1.0)+(tmpgain-1.0)*cs+beta*sn)/tmp; + c[1]=-2.0*tmpgain*((tmpgain-1.0)+(tmpgain+1.0)*cs)/tmp; + c[2]=tmpgain*((tmpgain+1.0)+(tmpgain-1.0)*cs-beta*sn)/tmp; + d[1]=2.0*((tmpgain-1.0)-(tmpgain+1.0)*cs)/tmp*(-1); + d[2]=((tmpgain+1.0)-(tmpgain-1.0)*cs-beta*sn)/tmp*(-1); + } else { + c[0]=1.0;c[1]=0.0;c[2]=0.0; + d[1]=0.0;d[2]=0.0; + }; + order=2; + break; + default://wrong type + type=0; + computefiltercoefs(); + break; + }; +}; + + +void AnalogFilter::setfreq(REALTYPE frequency){ + if (frequency<0.1) frequency=0.1; + REALTYPE rap=freq/frequency;if (rap<1.0) rap=1.0/rap; + + oldabovenq=abovenq;abovenq=frequency>(SAMPLE_RATE/2-500.0); + + int nyquistthresh=(abovenq^oldabovenq); + + + if ((rap>3.0)||(nyquistthresh!=0)){//if the frequency is changed fast, it needs interpolation (now, filter and coeficients backup) + for (int i=0;i<3;i++){ + oldc[i]=c[i];oldd[i]=d[i]; + }; + for (int i=0;i=MAX_FILTER_STAGES) stages_=MAX_FILTER_STAGES-1; + stages=stages_; + cleanup(); + computefiltercoefs(); +}; + +void AnalogFilter::singlefilterout(REALTYPE *smp,fstage &x,fstage &y,REALTYPE *c,REALTYPE *d){ + int i; + REALTYPE y0; + if (order==1) {//First order filter + for (i=0;i1,1->2,etc.) + REALTYPE freq;//Frequency given in Hz + REALTYPE q; //Q factor (resonance or Q factor) + REALTYPE gain;//the gain of the filter (if are shelf/peak) filters + + int order;//the order of the filter (number of poles) + + REALTYPE c[3],d[3];//coefficients + + REALTYPE oldc[3],oldd[3];//old coefficients(used only if some filter paremeters changes very fast, and it needs interpolation) + + REALTYPE xd[3],yd[3];//used if the filter is applied more times + int needsinterpolation,firsttime; + int abovenq;//this is 1 if the frequency is above the nyquist + int oldabovenq;//if the last time was above nyquist (used to see if it needs interpolation) +}; + + +#endif + diff --git a/plugins/zynaddsubfx/src/DSP/FFTwrapper.C b/plugins/zynaddsubfx/src/DSP/FFTwrapper.C new file mode 100644 index 000000000..fadf45c71 --- /dev/null +++ b/plugins/zynaddsubfx/src/DSP/FFTwrapper.C @@ -0,0 +1,99 @@ +/* + ZynAddSubFX - a software synthesizer + + FFTwrapper.c - A wrapper for Fast Fourier Transforms + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include +#include "FFTwrapper.h" + +FFTwrapper::FFTwrapper(int fftsize_){ + fftsize=fftsize_; + tmpfftdata1=new fftw_real[fftsize]; + tmpfftdata2=new fftw_real[fftsize]; +#ifdef FFTW_VERSION_2 + planfftw=rfftwf_create_plan(fftsize,FFTW_REAL_TO_COMPLEX,FFTW_ESTIMATE|FFTW_IN_PLACE); + planfftwf_inv=rfftwf_create_plan(fftsize,FFTW_COMPLEX_TO_REAL,FFTW_ESTIMATE|FFTW_IN_PLACE); +#else + planfftw=fftwf_plan_r2r_1d(fftsize,tmpfftdata1,tmpfftdata1,FFTW_R2HC,FFTW_ESTIMATE); + planfftw_inv=fftwf_plan_r2r_1d(fftsize,tmpfftdata2,tmpfftdata2,FFTW_HC2R,FFTW_ESTIMATE); +#endif +}; + +FFTwrapper::~FFTwrapper(){ +#ifdef FFTW_VERSION_2 + rfftwf_destroy_plan(planfftw); + rfftwf_destroy_plan(planfftwf_inv); +#else + fftwf_destroy_plan(planfftw); + fftwf_destroy_plan(planfftw_inv); +#endif + + delete [] tmpfftdata1; + delete [] tmpfftdata2; +}; + +/* + * do the Fast Fourier Transform + */ +void FFTwrapper::smps2freqs(REALTYPE *smps,FFTFREQS freqs){ +#ifdef FFTW_VERSION_2 + for (int i=0;i +#define fftw_real float +#define rfftw_plan fftwf_plan + +class FFTwrapper{ + public: + FFTwrapper(int fftsize_); + ~FFTwrapper(); + void smps2freqs(REALTYPE *smps,FFTFREQS freqs); + void freqs2smps(FFTFREQS freqs,REALTYPE *smps); + private: + int fftsize; + fftw_real *tmpfftdata1,*tmpfftdata2; + rfftw_plan planfftw,planfftw_inv; +}; +#endif + diff --git a/plugins/zynaddsubfx/src/DSP/Filter.C b/plugins/zynaddsubfx/src/DSP/Filter.C new file mode 100644 index 000000000..75fc00336 --- /dev/null +++ b/plugins/zynaddsubfx/src/DSP/Filter.C @@ -0,0 +1,72 @@ +/* + ZynAddSubFX - a software synthesizer + + Filter.C - Filters, uses analog,formant,etc. filters + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include +#include + +#include "Filter.h" + +Filter::Filter(FilterParams *pars){ + unsigned char Ftype=pars->Ptype; + unsigned char Fstages=pars->Pstages; + + category=pars->Pcategory; + + switch (category) { + case 1:filter=new FormantFilter(pars); + break; + case 2:filter=new SVFilter(Ftype,1000.0,pars->getq(),Fstages); + filter->outgain=dB2rap(pars->getgain()); + if (filter->outgain>1.0) filter->outgain=sqrt(filter->outgain); + break; + default:filter=new AnalogFilter(Ftype,1000.0,pars->getq(),Fstages); + if ((Ftype>=6)&&(Ftype<=8)) filter->setgain(pars->getgain()); + else filter->outgain=dB2rap(pars->getgain()); + break; + }; +}; + +Filter::~Filter(){ + delete (filter); +}; + +void Filter::filterout(REALTYPE *smp){ + filter->filterout(smp); +}; + +void Filter::setfreq(REALTYPE frequency){ + filter->setfreq(frequency); +}; + +void Filter::setfreq_and_q(REALTYPE frequency,REALTYPE q_){ + filter->setfreq_and_q(frequency,q_); +}; + +void Filter::setq(REALTYPE q_){ + filter->setq(q_); +}; + +REALTYPE Filter::getrealfreq(REALTYPE freqpitch){ + if ((category==0)||(category==2)) return(pow(2.0,freqpitch+9.96578428));//log2(1000)=9.95748 + else return(freqpitch); +}; + diff --git a/plugins/zynaddsubfx/src/DSP/Filter.h b/plugins/zynaddsubfx/src/DSP/Filter.h new file mode 100644 index 000000000..4ca5f3ff0 --- /dev/null +++ b/plugins/zynaddsubfx/src/DSP/Filter.h @@ -0,0 +1,51 @@ +/* + ZynAddSubFX - a software synthesizer + + Filter.h - Filters, uses analog,formant,etc. filters + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef FILTER_H +#define FILTER_H + +#include "../globals.h" + +#include "Filter_.h" +#include "AnalogFilter.h" +#include "FormantFilter.h" +#include "SVFilter.h" +#include "../Params/FilterParams.h" + +class Filter{ + public: + Filter(FilterParams *pars); + ~Filter(); + void filterout(REALTYPE *smp); + void setfreq(REALTYPE frequency); + void setfreq_and_q(REALTYPE frequency,REALTYPE q_); + void setq(REALTYPE q_); + + REALTYPE getrealfreq(REALTYPE freqpitch); + private: + Filter_ *filter; + unsigned char category; +}; + + +#endif + diff --git a/plugins/zynaddsubfx/src/DSP/Filter_.h b/plugins/zynaddsubfx/src/DSP/Filter_.h new file mode 100644 index 000000000..116a41bf6 --- /dev/null +++ b/plugins/zynaddsubfx/src/DSP/Filter_.h @@ -0,0 +1,42 @@ +/* + ZynAddSubFX - a software synthesizer + + Filter_.h - This class is inherited by filter classes + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef FILTER__H +#define FILTER__H + +#include "../globals.h" + +class Filter_{ + public: + virtual ~Filter_(){}; + virtual void filterout(REALTYPE *smp){}; + virtual void setfreq(REALTYPE frequency){}; + virtual void setfreq_and_q(REALTYPE frequency,REALTYPE q_){}; + virtual void setq(REALTYPE q_){}; + virtual void setgain(REALTYPE dBgain){}; + REALTYPE outgain; + private: +}; + + +#endif + diff --git a/plugins/zynaddsubfx/src/DSP/FormantFilter.C b/plugins/zynaddsubfx/src/DSP/FormantFilter.C new file mode 100644 index 000000000..f82df1e8d --- /dev/null +++ b/plugins/zynaddsubfx/src/DSP/FormantFilter.C @@ -0,0 +1,163 @@ +/* + ZynAddSubFX - a software synthesizer + + FormantFilter.C - formant filters + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include +#include +#include "FormantFilter.h" + +FormantFilter::FormantFilter(FilterParams *pars){ + numformants=pars->Pnumformants; + for (int i=0;iPstages); + cleanup(); + inbuffer=new REALTYPE [SOUND_BUFFER_SIZE]; + tmpbuf=new REALTYPE [SOUND_BUFFER_SIZE]; + + for (int j=0;jgetformantfreq(pars->Pvowels[j].formants[i].freq); + formantpar[j][i].amp=pars->getformantamp(pars->Pvowels[j].formants[i].amp); + formantpar[j][i].q=pars->getformantq(pars->Pvowels[j].formants[i].q); + }; + for (int i=0;iPformantslowness/128.0),3.0); + + sequencesize=pars->Psequencesize;if (sequencesize==0) sequencesize=1; + for (int k=0;kPsequence[k].nvowel; + + vowelclearness=pow(10.0,(pars->Pvowelclearness-32.0)/48.0); + + sequencestretch=pow(0.1,(pars->Psequencestretch-32.0)/48.0); + if (pars->Psequencereversed) sequencestretch*= -1.0; + + outgain=dB2rap(pars->getgain()); + + oldinput=-1.0; + Qfactor=1.0;oldQfactor=Qfactor; + firsttime=1; +}; + +FormantFilter::~FormantFilter(){ + for (int i=0;icleanup(); +}; + +void FormantFilter::setpos(REALTYPE input){ + int p1,p2; + + if (firsttime!=0) slowinput=input; + else slowinput=slowinput*(1.0-formantslowness)+input*formantslowness; + + if ((fabs(oldinput-input)<0.001)&&(fabs(slowinput-input)<0.001)&& + (fabs(Qfactor-oldQfactor)<0.001)) { +// oldinput=input; daca setez asta, o sa faca probleme la schimbari foarte lente + firsttime=0; + return; + } else oldinput=input; + + + REALTYPE pos=fmod(input*sequencestretch,1.0);if (pos<0.0) pos+=1.0; + + F2I(pos*sequencesize,p2); + p1=p2-1;if (p1<0) p1+=sequencesize; + + pos=fmod(pos*sequencesize,1.0); + if (pos<0.0) pos=0.0; else if (pos>1.0) pos=1.0; + pos=(atan((pos*2.0-1.0)*vowelclearness)/atan(vowelclearness)+1.0)*0.5; + + p1=sequence[p1].nvowel; + p2=sequence[p2].nvowel; + + if (firsttime!=0) { + for (int i=0;isetfreq_and_q(currentformants[i].freq,currentformants[i].q*Qfactor); + oldformantamp[i]=currentformants[i].amp; + }; + firsttime=0; + } else { + for (int i=0;isetfreq_and_q(currentformants[i].freq,currentformants[i].q*Qfactor); + }; + }; + + oldQfactor=Qfactor; +}; + +void FormantFilter::setfreq(REALTYPE frequency){ + setpos(frequency); +}; + +void FormantFilter::setq(REALTYPE q_){ + Qfactor=q_; + for (int i=0;isetq(Qfactor*currentformants[i].q); +}; + +void FormantFilter::setfreq_and_q(REALTYPE frequency,REALTYPE q_){ + Qfactor=q_; + setpos(frequency); +}; + + +void FormantFilter::filterout(REALTYPE *smp){ + int i,j; + for (i=0;ifilterout(tmpbuf); + + if (ABOVE_AMPLITUDE_THRESHOLD(oldformantamp[j],currentformants[j].amp)) + for (i=0;i +#include +#include "SVFilter.h" + +SVFilter::SVFilter(unsigned char Ftype,REALTYPE Ffreq, REALTYPE Fq,unsigned char Fstages){ + stages=Fstages; + type=Ftype; + freq=Ffreq; + q=Fq; + gain=1.0; + outgain=1.0; + needsinterpolation=0; + firsttime=1; + if (stages>=MAX_FILTER_STAGES) stages=MAX_FILTER_STAGES; + cleanup(); + setfreq_and_q(Ffreq,Fq); +}; + +SVFilter::~SVFilter(){ +}; + +void SVFilter::cleanup(){ + for (int i=0;i0.99999) par.f=0.99999; + par.q=1.0-atan(sqrt(q))*2.0/PI; + par.q=pow(par.q,1.0/(stages+1)); + par.q_sqrt=sqrt(par.q); +}; + + +void SVFilter::setfreq(REALTYPE frequency){ + if (frequency<0.1) frequency=0.1; + REALTYPE rap=freq/frequency;if (rap<1.0) rap=1.0/rap; + + oldabovenq=abovenq;abovenq=frequency>(SAMPLE_RATE/2-500.0); + + int nyquistthresh=(abovenq^oldabovenq); + + + if ((rap>3.0)||(nyquistthresh!=0)){//if the frequency is changed fast, it needs interpolation (now, filter and coeficients backup) + if (firsttime==0) needsinterpolation=1; + ipar=par; + }; + freq=frequency; + computefiltercoefs(); + firsttime=0; + +}; + +void SVFilter::setfreq_and_q(REALTYPE frequency,REALTYPE q_){ + q=q_; + setfreq(frequency); +}; + +void SVFilter::setq(REALTYPE q_){ + q=q_; + computefiltercoefs(); +}; + +void SVFilter::settype(int type_){ + type=type_; + computefiltercoefs(); +}; + +void SVFilter::setgain(REALTYPE dBgain){ + gain=dB2rap(dBgain); + computefiltercoefs(); +}; + +void SVFilter::setstages(int stages_){ + if (stages_>=MAX_FILTER_STAGES) stages_=MAX_FILTER_STAGES-1; + stages=stages_; + cleanup(); + computefiltercoefs(); +}; + +void SVFilter::singlefilterout(REALTYPE *smp,fstage &x,parameters &par){ + int i; + REALTYPE *out=NULL; + switch(type){ + case 0: out=&x.low;break; + case 1: out=&x.high;break; + case 2: out=&x.band;break; + case 3: out=&x.notch;break; + }; + + for (i=0;i1,1->2,etc.) + REALTYPE freq;//Frequency given in Hz + REALTYPE q; //Q factor (resonance or Q factor) + REALTYPE gain;//the gain of the filter (if are shelf/peak) filters + + int abovenq;//this is 1 if the frequency is above the nyquist + int oldabovenq; + int needsinterpolation,firsttime; +}; + + +#endif + diff --git a/plugins/zynaddsubfx/src/Effects/Alienwah.C b/plugins/zynaddsubfx/src/Effects/Alienwah.C new file mode 100644 index 000000000..0f5e40b4c --- /dev/null +++ b/plugins/zynaddsubfx/src/Effects/Alienwah.C @@ -0,0 +1,230 @@ +/* + ZynAddSubFX - a software synthesizer + + Alienwah.C - "AlienWah" effect + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include +#include "Alienwah.h" + +Alienwah::Alienwah(const int &insertion_,REALTYPE *const efxoutl_,REALTYPE *const efxoutr_) + :Effect(insertion_,efxoutl_,efxoutr_,NULL,0),oldl(NULL),oldr(NULL) +{ + setpreset(Ppreset); + cleanup(); + oldclfol=complex(fb,0.0); + oldclfor=complex(fb,0.0); +}; + +Alienwah::~Alienwah(){ + if (oldl!=NULL) delete [] oldl; + if (oldr!=NULL) delete [] oldr ; +}; + + +/* + * Apply the effect + */ +void Alienwah::out(REALTYPE *smpsl,REALTYPE *smpsr){ + REALTYPE lfol,lfor; //Left/Right LFOs + complex clfol,clfor,out,tmp; + /**\todo Rework, as optimization can be used when the new complex type is + * utilized. + * Before all calculations needed to be done with individual REALTYPE, + * but now they can be done together*/ + lfo.effectlfoout(&lfol,&lfor); + lfol*=depth*PI*2.0;lfor*=depth*PI*2.0; + clfol=complex(cos(lfol+phase)*fb,sin(lfol+phase)*fb); //rework + clfor=complex(cos(lfor+phase)*fb,sin(lfor+phase)*fb); //rework + + for (int i=0;i=Pdelay) oldk=0; + //LRcross + efxoutl[i]=l*(1.0-lrcross)+r*lrcross; + efxoutr[i]=r*(1.0-lrcross)+l*lrcross; + }; + + oldclfol=clfol; + oldclfor=clfor; + +}; + +/* + * Cleanup the effect + */ +void Alienwah::cleanup(){ + for (int i=0;i(0.0,0.0); + oldr[i]=complex(0.0,0.0); + }; + oldk=0; +}; + + +/* + * Parameter control + */ + +void Alienwah::setdepth(const unsigned char &Pdepth){ + this->Pdepth=Pdepth; + depth=(Pdepth/127.0); +}; + +void Alienwah::setfb(const unsigned char &Pfb){ + this->Pfb=Pfb; + fb=fabs((Pfb-64.0)/64.1); + fb=sqrt(fb); + if (fb<0.4) fb=0.4; + if (Pfb<64) fb=-fb; +}; + +void Alienwah::setvolume(const unsigned char &Pvolume){ + this->Pvolume=Pvolume; + outvolume=Pvolume/127.0; + if (insertion==0) volume=1.0; + else volume=outvolume; +}; + +void Alienwah::setpanning(const unsigned char &Ppanning){ + this->Ppanning=Ppanning; + panning=Ppanning/127.0; +}; + +void Alienwah::setlrcross(const unsigned char &Plrcross){ + this->Plrcross=Plrcross; + lrcross=Plrcross/127.0; +}; + +void Alienwah::setphase(const unsigned char &Pphase){ + this->Pphase=Pphase; + phase=(Pphase-64.0)/64.0*PI; +}; + +void Alienwah::setdelay(const unsigned char &Pdelay){ + if (oldl!=NULL) delete [] oldl; + if (oldr!=NULL) delete [] oldr; + if (Pdelay>=MAX_ALIENWAH_DELAY) this->Pdelay=MAX_ALIENWAH_DELAY; + else this->Pdelay=Pdelay; + oldl=new complex[Pdelay]; + oldr=new complex[Pdelay]; + cleanup(); +}; + +void Alienwah::setpreset(unsigned char npreset){ + const int PRESET_SIZE=11; + const int NUM_PRESETS=4; + unsigned char presets[NUM_PRESETS][PRESET_SIZE]={ + //AlienWah1 + {127,64,70,0,0,62,60,105,25,0,64}, + //AlienWah2 + {127,64,73,106,0,101,60,105,17,0,64}, + //AlienWah3 + {127,64,63,0,1,100,112,105,31,0,42}, + //AlienWah4 + {93,64,25,0,1,66,101,11,47,0,86}}; + + if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1; + for (int n=0;n +#include "../globals.h" +#include "Effect.h" +#include "EffectLFO.h" + +using namespace std; + +#define MAX_ALIENWAH_DELAY 100 + +/**"AlienWah" Effect*/ +class Alienwah:public Effect { + public: + /** + * Constructor + * @param insetion_ 1 for insertion Effect, 0 for others + * @param efxoutl_ Pointer to Alienwah's left channel output buffer + * @param efxoutr_ Pointer to Alienwah's left channel output buffer + * @return Initialized Alienwah + */ + Alienwah(const int &insetion_,REALTYPE *const efxoutl_,REALTYPE *const efxoutr_); + ~Alienwah(); + void out(REALTYPE *const smpsl,REALTYPE *const smpsr); + + void setpreset(unsigned char npreset); + void changepar(const int &npar,const unsigned char &value); + unsigned char getpar(const int &npar)const; + void cleanup(); + + private: + //Alienwah Parameters + EffectLFO lfo;//lfo-ul Alienwah + unsigned char Pvolume; + unsigned char Ppanning; + unsigned char Pdepth;//the depth of the Alienwah + unsigned char Pfb;//feedback + unsigned char Plrcross;//feedback + unsigned char Pdelay; + unsigned char Pphase; + + + //Control Parameters + void setvolume(const unsigned char &Pvolume); + void setpanning(const unsigned char &Ppanning); + void setdepth(const unsigned char &Pdepth); + void setfb(const unsigned char &Pfb); + void setlrcross(const unsigned char &Plrcross); + void setdelay(const unsigned char &Pdelay); + void setphase(const unsigned char &Pphase); + + //Internal Values + REALTYPE panning,fb,depth,lrcross,phase; + complex *oldl,*oldr; + complex oldclfol,oldclfor; + int oldk; +}; + +#endif + diff --git a/plugins/zynaddsubfx/src/Effects/Chorus.C b/plugins/zynaddsubfx/src/Effects/Chorus.C new file mode 100644 index 000000000..d7462cc03 --- /dev/null +++ b/plugins/zynaddsubfx/src/Effects/Chorus.C @@ -0,0 +1,275 @@ +/* + ZynAddSubFX - a software synthesizer + + Chorus.C - Chorus and Flange effects + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include +#include "Chorus.h" +#include + +using namespace std; + +Chorus::Chorus(const int &insertion_,REALTYPE *const efxoutl_,REALTYPE *const efxoutr_) + :Effect(insertion_,efxoutl_,efxoutr_,NULL,0) +{ + dlk=0;drk=0; + maxdelay=(int)(MAX_CHORUS_DELAY/1000.0*SAMPLE_RATE); + delayl=new REALTYPE[maxdelay]; + delayr=new REALTYPE[maxdelay]; + + setpreset(Ppreset); + + lfo.effectlfoout(&lfol,&lfor); + dl2=getdelay(lfol); + dr2=getdelay(lfor); + cleanup(); +}; + +Chorus::~Chorus(){ + delete [] delayl; + delete [] delayr; +}; + +/* + * get the delay value in samples; xlfo is the current lfo value + */ +REALTYPE Chorus::getdelay(REALTYPE xlfo){ + REALTYPE result; + if (Pflangemode==0){ + result=(delay+xlfo*depth)*SAMPLE_RATE; + } else result=0; + + //check if it is too big delay(caused bu errornous setdelay() and setdepth() + /**\todo fix setdelay() and setdepth(), so this error cannot occur*/ + if ((result+0.5)>=maxdelay) { + cerr << "WARNING: Chorus.C::getdelay(..) too big delay (see setdelay and setdepth funcs.)\n"; + result=maxdelay-1.0; + }; + return(result); +}; + +/* + * Apply the effect + */ +void Chorus::out(REALTYPE *smpsl,REALTYPE *smpsr){ + int i; + const REALTYPE one=1.0; + dl1=dl2;dr1=dr2; + lfo.effectlfoout(&lfol,&lfor); + + dl2=getdelay(lfol); + dr2=getdelay(lfor); + + for (i=0;i=maxdelay) dlk=0; + REALTYPE tmp=dlk-mdel+maxdelay*2.0;//where should I get the sample from + + F2I(tmp,dlhi); + dlhi%=maxdelay; + + dlhi2=(dlhi-1+maxdelay)%maxdelay; + dllo=1.0-fmod(tmp,one); + efxoutl[i]=delayl[dlhi2]*dllo+delayl[dlhi]*(1.0-dllo); + delayl[dlk]=inl+efxoutl[i]*fb; + + //Right channel + + //compute the delay in samples using linear interpolation between the lfo delays + mdel=(dr1*(SOUND_BUFFER_SIZE-i)+dr2*i)/SOUND_BUFFER_SIZE; + if (++drk>=maxdelay) drk=0; + tmp=drk*1.0-mdel+maxdelay*2.0;//where should I get the sample from + + F2I(tmp,dlhi); + dlhi%=maxdelay; + + dlhi2=(dlhi-1+maxdelay)%maxdelay; + dllo=1.0-fmod(tmp,one); + efxoutr[i]=delayr[dlhi2]*dllo+delayr[dlhi]*(1.0-dllo); + delayr[dlk]=inr+efxoutr[i]*fb; + + }; + + if (Poutsub!=0) + for (i=0;iPdepth=Pdepth; + depth=(pow(8.0,(Pdepth/127.0)*2.0)-1.0)/1000.0;//seconds +}; + +void Chorus::setdelay(const unsigned char &Pdelay){ + this->Pdelay=Pdelay; + delay=(pow(10.0,(Pdelay/127.0)*2.0)-1.0)/1000.0;//seconds +}; + +void Chorus::setfb(const unsigned char &Pfb){ + this->Pfb=Pfb; + fb=(Pfb-64.0)/64.1; +}; +void Chorus::setvolume(const unsigned char &Pvolume){ + this->Pvolume=Pvolume; + outvolume=Pvolume/127.0; + if (insertion==0) volume=1.0; + else volume=outvolume; +}; + +void Chorus::setpanning(const unsigned char &Ppanning){ + this->Ppanning=Ppanning; + panning=Ppanning/127.0; +}; + +void Chorus::setlrcross(const unsigned char &Plrcross){ + this->Plrcross=Plrcross; + lrcross=Plrcross/127.0; +}; + +void Chorus::setpreset(unsigned char npreset){ + const int PRESET_SIZE=12; + const int NUM_PRESETS=10; + unsigned char presets[NUM_PRESETS][PRESET_SIZE]={ + //Chorus1 + {64,64,50,0,0,90,40,85,64,119,0,0}, + //Chorus2 + {64,64,45,0,0,98,56,90,64,19,0,0}, + //Chorus3 + {64,64,29,0,1,42,97,95,90,127,0,0}, + //Celeste1 + {64,64,26,0,0,42,115,18,90,127,0,0}, + //Celeste2 + {64,64,29,117,0,50,115,9,31,127,0,1}, + //Flange1 + {64,64,57,0,0,60,23,3,62,0,0,0}, + //Flange2 + {64,64,33,34,1,40,35,3,109,0,0,0}, + //Flange3 + {64,64,53,34,1,94,35,3,54,0,0,1}, + //Flange4 + {64,64,40,0,1,62,12,19,97,0,0,0}, + //Flange5 + {64,64,55,105,0,24,39,19,17,0,0,1}}; + + if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1; + for (int n=0;n1) Pflangemode=1; + else Pflangemode=value; + break; + case 11:if (value>1) Poutsub=1; + else Poutsub=value; + break; + }; +}; + +unsigned char Chorus::getpar(const int &npar)const{ + switch (npar){ + case 0: return(Pvolume); + break; + case 1: return(Ppanning); + break; + case 2: return(lfo.Pfreq); + break; + case 3: return(lfo.Prandomness); + break; + case 4: return(lfo.PLFOtype); + break; + case 5: return(lfo.Pstereo); + break; + case 6: return(Pdepth); + break; + case 7: return(Pdelay); + break; + case 8: return(Pfb); + break; + case 9: return(Plrcross); + break; + case 10:return(Pflangemode); + break; + case 11:return(Poutsub); + break; + default:return (0); + }; + +}; + diff --git a/plugins/zynaddsubfx/src/Effects/Chorus.h b/plugins/zynaddsubfx/src/Effects/Chorus.h new file mode 100644 index 000000000..b53db141e --- /dev/null +++ b/plugins/zynaddsubfx/src/Effects/Chorus.h @@ -0,0 +1,111 @@ +/* + ZynAddSubFX - a software synthesizer + + Chorus.h - Chorus and Flange effects + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef CHORUS_H +#define CHORUS_H +#include "../globals.h" +#include "Effect.h" +#include "EffectLFO.h" + +#define MAX_CHORUS_DELAY 250.0 //ms + +/**Chorus and Flange effects*/ +class Chorus:public Effect { + public: + Chorus(const int &insetion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_); + /**Destructor*/ + ~Chorus(); + void out(REALTYPE *smpsl,REALTYPE *smpsr); + void setpreset(unsigned char npreset); + /** + * Sets the value of the chosen variable + * + * The possible parameters are: + * -# Volume + * -# Panning + * -# LFO Frequency + * -# LFO Randomness + * -# LFO Type + * -# LFO stereo + * -# Depth + * -# Delay + * -# Feedback + * -# Flange Mode + * -# Subtractive + * @param npar number of chosen parameter + * @param value the new value + */ + void changepar(const int &npar,const unsigned char &value); + /** + * Gets the value of the chosen variable + * + * The possible parameters are: + * -# Volume + * -# Panning + * -# LFO Frequency + * -# LFO Randomness + * -# LFO Type + * -# LFO stereo + * -# Depth + * -# Delay + * -# Feedback + * -# Flange Mode + * -# Subtractive + * @param npar number of chosen parameter + * @return the value of the parameter + */ + unsigned char getpar(const int &npar)const; + void cleanup(); + + private: + //Chorus Parameters + EffectLFO lfo;//lfo-ul chorus + unsigned char Pvolume; + unsigned char Ppanning; + unsigned char Pdepth;//the depth of the Chorus(ms) + unsigned char Pdelay;//the delay (ms) + unsigned char Pfb;//feedback + unsigned char Plrcross;//feedback + unsigned char Pflangemode;//how the LFO is scaled, to result chorus or flange + unsigned char Poutsub;//if I wish to substract the output instead of the adding it + + + //Parameter Controls + void setvolume(const unsigned char &Pvolume); + void setpanning(const unsigned char &Ppanning); + void setdepth(const unsigned char &Pdepth); + void setdelay(const unsigned char &Pdelay); + void setfb(const unsigned char &Pfb); + void setlrcross(const unsigned char &Plrcross); + + //Internal Values + REALTYPE depth,delay,fb,lrcross,panning; + REALTYPE dl1,dl2,dr1,dr2,lfol,lfor; + int maxdelay; + REALTYPE *delayl,*delayr; + int dlk,drk,dlhi,dlhi2; + REALTYPE getdelay(REALTYPE xlfo); + REALTYPE dllo,mdel; +}; + +#endif + diff --git a/plugins/zynaddsubfx/src/Effects/Distorsion.C b/plugins/zynaddsubfx/src/Effects/Distorsion.C new file mode 100644 index 000000000..33dabe2a7 --- /dev/null +++ b/plugins/zynaddsubfx/src/Effects/Distorsion.C @@ -0,0 +1,376 @@ +/* + ZynAddSubFX - a software synthesizer + + Distorsion.C - Distorsion effect + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include +#include "Distorsion.h" + + +/* + * Waveshape (this is called by OscilGen::waveshape and Distorsion::process) + */ + +void waveshapesmps(int n,REALTYPE *smps,unsigned char type,unsigned char drive){ + int i; + REALTYPE ws=drive/127.0; + REALTYPE tmpv; + + switch(type){ + case 1: ws=pow(10,ws*ws*3.0)-1.0+0.001;//Arctangent + for (i=0;iws) { + if (tmp>=0.0) smps[i]=1.0; + else smps[i]=-1.0; + } else smps[i]/=ws; + }; + break; + case 8: ws=pow(2.0,-ws*ws*8.0); //Upper Limiter + for (i=0;iws) smps[i]=ws; + smps[i]*=2.0; + }; + break; + case 9: ws=pow(2.0,-ws*ws*8.0); //Lower Limiter + for (i=0;iws) { + if (tmp>=0.0) smps[i]=tmp-ws; + else smps[i]=tmp+ws; + } else smps[i]=0; + }; + break; + case 11:ws=pow(5,ws*ws*1.0)-1.0;//Clip + for (i=0;i-2.0) && (tmp<1.0)) smps[i]=tmp*(1.0-tmp)*(tmp+2.0)/tmpv; + else smps[i]=0.0; + }; + break; + case 13:ws=ws*ws*ws*32.0+0.0001;//Pow2 + if (ws<1.0) tmpv=ws*(1+ws)/2.0; + else tmpv=1.0; + for (i=0;i-1.0)&&(tmp<1.618034)) smps[i]=tmp*(1.0-tmp)/tmpv; + else if (tmp>0.0) smps[i]=-1.0; + else smps[i]=-2.0; + }; + break; + case 14:ws=pow(ws,5.0)*80.0+0.0001;//sigmoid + if (ws>10.0) tmpv=0.5; + else tmpv=0.5-1.0/(exp(ws)+1.0); + for (i=0;i10.0) tmp=10.0; + tmp=0.5-1.0/(exp(tmp)+1.0); + smps[i]=tmp/tmpv; + }; + break; + /**\todo update to Distorsion::changepar (Ptype max) if there is added more waveshapings functions*/ + }; + +}; + + +Distorsion::Distorsion(const int &insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_) + :Effect(insertion_,efxoutl_,efxoutr_,NULL,0) +{ + + lpfl=new AnalogFilter(2,22000,1,0); + lpfr=new AnalogFilter(2,22000,1,0); + hpfl=new AnalogFilter(3,20,1,0); + hpfr=new AnalogFilter(3,20,1,0); + + + //default values + Pvolume=50; + Plrcross=40; + Pdrive=90; + Plevel=64; + Ptype=0; + Pnegate=0; + Plpf=127; + Phpf=0; + Pstereo=0; + Pprefiltering=0; + + setpreset(Ppreset); + cleanup(); +}; + +Distorsion::~Distorsion(){ + delete lpfl; + delete lpfr; + delete hpfl; + delete hpfr; + +}; + +/* + * Cleanup the effect + */ +void Distorsion::cleanup(){ + lpfl->cleanup(); + hpfl->cleanup(); + lpfr->cleanup(); + hpfr->cleanup(); +}; + + +/* + * Apply the filters + */ + +void Distorsion::applyfilters(REALTYPE *efxoutl,REALTYPE *efxoutr){ + lpfl->filterout(efxoutl); + hpfl->filterout(efxoutl); + if (Pstereo!=0){//stereo + lpfr->filterout(efxoutr); + hpfr->filterout(efxoutr); + }; + +}; + + +/* + * Effect output + */ +void Distorsion::out(REALTYPE *smpsl,REALTYPE *smpsr){ + int i; + REALTYPE l,r,lout,rout; + + REALTYPE inputvol=pow(5.0,(Pdrive-32.0)/127.0); + if (Pnegate!=0) inputvol*=-1.0; + + if (Pstereo!=0){//Stereo + for (i=0;iPvolume=Pvolume; + + if (insertion==0) { + outvolume=pow(0.01,(1.0-Pvolume/127.0))*4.0; + volume=1.0; + } else { + volume=outvolume=Pvolume/127.0; + }; + if (Pvolume==0) cleanup(); + +}; + +void Distorsion::setpanning(const unsigned char &Ppanning){ + this->Ppanning=Ppanning; + panning=(Ppanning+0.5)/127.0; +}; + + +void Distorsion::setlrcross(const unsigned char &Plrcross){ + this->Plrcross=Plrcross; + lrcross=Plrcross/127.0*1.0; +}; + +void Distorsion::setlpf(const unsigned char &Plpf){ + this->Plpf=Plpf; + REALTYPE fr=exp(pow(Plpf/127.0,0.5)*log(25000.0))+40; + lpfl->setfreq(fr); + lpfr->setfreq(fr); +}; + +void Distorsion::sethpf(const unsigned char &Phpf){ + this->Phpf=Phpf; + REALTYPE fr=exp(pow(Phpf/127.0,0.5)*log(25000.0))+20.0; + hpfl->setfreq(fr); + hpfr->setfreq(fr); +}; + + +void Distorsion::setpreset(unsigned char npreset){ + const int PRESET_SIZE=11; + const int NUM_PRESETS=6; + unsigned char presets[NUM_PRESETS][PRESET_SIZE]={ + //Overdrive 1 + {127,64,35,56,70,0,0,96,0,0,0}, + //Overdrive 2 + {127,64,35,29,75,1,0,127,0,0,0}, + //A. Exciter 1 + {64,64,35,75,80,5,0,127,105,1,0}, + //A. Exciter 2 + {64,64,35,85,62,1,0,127,118,1,0}, + //Guitar Amp + {127,64,35,63,75,2,0,55,0,0,0}, + //Quantisize + {127,64,35,88,75,4,0,127,0,1,0}}; + + + if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1; + for (int n=0;n13) Ptype=13;//this must be increased if more distorsion types are added + else Ptype=value; + break; + case 6: if (value>1) Pnegate=1; + else Pnegate=value; + break; + case 7: setlpf(value); + break; + case 8: sethpf(value); + break; + case 9: if (value>1) Pstereo=1; + else Pstereo=value; + break; + case 10:Pprefiltering=value; + break; + }; +}; + +unsigned char Distorsion::getpar(const int &npar)const{ + switch (npar){ + case 0: return(Pvolume); + break; + case 1: return(Ppanning); + break; + case 2: return(Plrcross); + break; + case 3: return(Pdrive); + break; + case 4: return(Plevel); + break; + case 5: return(Ptype); + break; + case 6: return(Pnegate); + break; + case 7: return(Plpf); + break; + case 8: return(Phpf); + break; + case 9: return(Pstereo); + break; + case 10:return(Pprefiltering); + break; + }; + return(0);//in case of bogus parameter number +}; + diff --git a/plugins/zynaddsubfx/src/Effects/Distorsion.h b/plugins/zynaddsubfx/src/Effects/Distorsion.h new file mode 100644 index 000000000..c211168e0 --- /dev/null +++ b/plugins/zynaddsubfx/src/Effects/Distorsion.h @@ -0,0 +1,72 @@ +/* + ZynAddSubFX - a software synthesizer + + Distorsion.h - Distorsion Effect + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef DISTORSION_H +#define DISTORSION_H + +#include "../globals.h" +#include "../DSP/AnalogFilter.h" +#include "Effect.h" + +//Waveshaping(called by Distorsion effect and waveshape from OscilGen) +void waveshapesmps(int n,REALTYPE *smps,unsigned char type,unsigned char drive); +/**Distortion Effect*/ +class Distorsion:public Effect{ + public: + Distorsion(const int &insertion,REALTYPE *efxoutl_,REALTYPE *efxoutr_); + ~Distorsion(); + void out(REALTYPE *smpsl,REALTYPE *smpr); + void setpreset(unsigned char npreset); + void changepar(const int &npar,const unsigned char &value); + unsigned char getpar(const int &npar)const; + void cleanup(); + void applyfilters(REALTYPE *efxoutl,REALTYPE *efxoutr); + + private: + //Parametrii + unsigned char Pvolume; //Volumul or E/R + unsigned char Ppanning;//Panning + unsigned char Plrcross;// L/R Mixing + unsigned char Pdrive; //the input amplification + unsigned char Plevel; //the output amplification + unsigned char Ptype; //Distorsion type + unsigned char Pnegate; //if the input is negated + unsigned char Plpf; //lowpass filter + unsigned char Phpf; //highpass filter + unsigned char Pstereo; //0=mono,1=stereo + unsigned char Pprefiltering;//if you want to do the filtering before the distorsion + + void setvolume(const unsigned char &Pvolume); + void setpanning(const unsigned char &Ppanning); + void setlrcross(const unsigned char &Plrcross); + void setlpf(const unsigned char &Plpf); + void sethpf(const unsigned char &Phpf); + + //Real Parameters + REALTYPE panning,lrcross; + AnalogFilter *lpfl,*lpfr,*hpfl,*hpfr; + +}; + + +#endif + diff --git a/plugins/zynaddsubfx/src/Effects/DynamicFilter.C b/plugins/zynaddsubfx/src/Effects/DynamicFilter.C new file mode 100644 index 000000000..150c4c590 --- /dev/null +++ b/plugins/zynaddsubfx/src/Effects/DynamicFilter.C @@ -0,0 +1,312 @@ +/* + ZynAddSubFX - a software synthesizer + + DynamicFilter.C - "WahWah" effect and others + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include +#include "DynamicFilter.h" + +DynamicFilter::DynamicFilter(int insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_) + :Effect(insertion_,efxoutl_,efxoutr_,new FilterParams(0,64,64),0), + filterl(NULL),filterr(NULL) +{ + setpreset(Ppreset); + cleanup(); + /**\todo fix intialization issues here*/ +}; + +DynamicFilter::~DynamicFilter(){ + delete filterpars; + delete filterl; + delete filterr; +}; + + +/* + * Apply the effect + */ +void DynamicFilter::out(REALTYPE *smpsl,REALTYPE *smpsr){ + int i; + if (filterpars->changed){ + filterpars->changed=false; + cleanup(); + }; + + REALTYPE lfol,lfor; + lfo.effectlfoout(&lfol,&lfor); + lfol*=depth*5.0;lfor*=depth*5.0; + REALTYPE freq=filterpars->getfreq(); + REALTYPE q=filterpars->getq(); + + for (i=0;igetrealfreq(freq+lfol+rms); + REALTYPE frr=filterr->getrealfreq(freq+lfor+rms); + + filterl->setfreq_and_q(frl,q); + filterr->setfreq_and_q(frr,q); + + + filterl->filterout(efxoutl); + filterr->filterout(efxoutr); + + //panning + for (i=0;iPdepth=Pdepth; + depth=pow((Pdepth/127.0),2.0); +}; + + +void DynamicFilter::setvolume(const unsigned char &Pvolume){ + this->Pvolume=Pvolume; + outvolume=Pvolume/127.0; + if (insertion==0) volume=1.0; + else volume=outvolume; +}; + +void DynamicFilter::setpanning(const unsigned char &Ppanning){ + this->Ppanning=Ppanning; + panning=Ppanning/127.0; +}; + + +void DynamicFilter::setampsns(const unsigned char &Pampsns){ + ampsns=pow(Pampsns/127.0,2.5)*10.0; + if (Pampsnsinv!=0) ampsns=-ampsns; + ampsmooth=exp(-Pampsmooth/127.0*10.0)*0.99;/**\todo currently Pampsmooth is + * uninitialized when this is + * called. Please fix. + */ + this->Pampsns=Pampsns; +}; + +void DynamicFilter::reinitfilter(){ + if (filterl!=NULL) delete(filterl); + if (filterr!=NULL) delete(filterr); + filterl=new Filter(filterpars); + filterr=new Filter(filterpars); +}; + +void DynamicFilter::setpreset(unsigned char npreset){ + const int PRESET_SIZE=10; + const int NUM_PRESETS=5; + unsigned char presets[NUM_PRESETS][PRESET_SIZE]={ + //WahWah + {110,64,80,0,0,64,0,90,0,60}, + //AutoWah + {110,64,70,0,0,80,70,0,0,60}, + //Sweep + {100,64,30,0,0,50,80,0,0,60}, + //VocalMorph1 + {110,64,80,0,0,64,0,64,0,60}, + //VocalMorph1 + {127,64,50,0,0,96,64,0,0,60}}; + + if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1; + for (int n=0;ndefaults(); + switch(npreset){ + case 0: + filterpars->Pcategory=0; + filterpars->Ptype=2; + filterpars->Pfreq=45; + filterpars->Pq=64; + filterpars->Pstages=1; + filterpars->Pgain=64; + break; + case 1: + filterpars->Pcategory=2; + filterpars->Ptype=0; + filterpars->Pfreq=72; + filterpars->Pq=64; + filterpars->Pstages=0; + filterpars->Pgain=64; + break; + case 2: + filterpars->Pcategory=0; + filterpars->Ptype=4; + filterpars->Pfreq=64; + filterpars->Pq=64; + filterpars->Pstages=2; + filterpars->Pgain=64; + break; + case 3: + filterpars->Pcategory=1; + filterpars->Ptype=0; + filterpars->Pfreq=50; + filterpars->Pq=70; + filterpars->Pstages=1; + filterpars->Pgain=64; + + filterpars->Psequencesize=2; + // "I" + filterpars->Pvowels[0].formants[0].freq=34; + filterpars->Pvowels[0].formants[0].amp=127; + filterpars->Pvowels[0].formants[0].q=64; + filterpars->Pvowels[0].formants[1].freq=99; + filterpars->Pvowels[0].formants[1].amp=122; + filterpars->Pvowels[0].formants[1].q=64; + filterpars->Pvowels[0].formants[2].freq=108; + filterpars->Pvowels[0].formants[2].amp=112; + filterpars->Pvowels[0].formants[2].q=64; + // "A" + filterpars->Pvowels[1].formants[0].freq=61; + filterpars->Pvowels[1].formants[0].amp=127; + filterpars->Pvowels[1].formants[0].q=64; + filterpars->Pvowels[1].formants[1].freq=71; + filterpars->Pvowels[1].formants[1].amp=121; + filterpars->Pvowels[1].formants[1].q=64; + filterpars->Pvowels[1].formants[2].freq=99; + filterpars->Pvowels[1].formants[2].amp=117; + filterpars->Pvowels[1].formants[2].q=64; + break; + case 4: + filterpars->Pcategory=1; + filterpars->Ptype=0; + filterpars->Pfreq=64; + filterpars->Pq=70; + filterpars->Pstages=1; + filterpars->Pgain=64; + + filterpars->Psequencesize=2; + filterpars->Pnumformants=2; + filterpars->Pvowelclearness=0; + + filterpars->Pvowels[0].formants[0].freq=70; + filterpars->Pvowels[0].formants[0].amp=127; + filterpars->Pvowels[0].formants[0].q=64; + filterpars->Pvowels[0].formants[1].freq=80; + filterpars->Pvowels[0].formants[1].amp=122; + filterpars->Pvowels[0].formants[1].q=64; + + filterpars->Pvowels[1].formants[0].freq=20; + filterpars->Pvowels[1].formants[0].amp=127; + filterpars->Pvowels[1].formants[0].q=64; + filterpars->Pvowels[1].formants[1].freq=100; + filterpars->Pvowels[1].formants[1].amp=121; + filterpars->Pvowels[1].formants[1].q=64; + break; + }; + +// for (int i=0;i<5;i++){ +// printf("freq=%d amp=%d q=%d\n",filterpars->Pvowels[0].formants[i].freq,filterpars->Pvowels[0].formants[i].amp,filterpars->Pvowels[0].formants[i].q); +// }; + if (insertion==0) changepar(0,presets[npreset][0]/2);//lower the volume if this is system effect + Ppreset=npreset; + + reinitfilter(); +}; + + +void DynamicFilter::changepar(const int &npar,const unsigned char &value){ + switch(npar){ + case 0: setvolume(value); + break; + case 1: setpanning(value); + break; + case 2: lfo.Pfreq=value; + lfo.updateparams(); + break; + case 3: lfo.Prandomness=value; + lfo.updateparams(); + break; + case 4: lfo.PLFOtype=value; + lfo.updateparams(); + break; + case 5: lfo.Pstereo=value; + lfo.updateparams(); + break; + case 6: setdepth(value); + break; + case 7: setampsns(value); + break; + case 8: Pampsnsinv=value; + setampsns(Pampsns); + break; + case 9: Pampsmooth=value; + setampsns(Pampsns); + break; + }; +}; + +unsigned char DynamicFilter::getpar(const int &npar)const{ + switch (npar){ + case 0: return(Pvolume); + break; + case 1: return(Ppanning); + break; + case 2: return(lfo.Pfreq); + break; + case 3: return(lfo.Prandomness); + break; + case 4: return(lfo.PLFOtype); + break; + case 5: return(lfo.Pstereo); + break; + case 6: return(Pdepth); + break; + case 7: return(Pampsns); + break; + case 8: return(Pampsnsinv); + break; + case 9: return(Pampsmooth); + break; + default:return (0); + }; + +}; + diff --git a/plugins/zynaddsubfx/src/Effects/DynamicFilter.h b/plugins/zynaddsubfx/src/Effects/DynamicFilter.h new file mode 100644 index 000000000..ba8c04407 --- /dev/null +++ b/plugins/zynaddsubfx/src/Effects/DynamicFilter.h @@ -0,0 +1,71 @@ +/* + ZynAddSubFX - a software synthesizer + + DynamicFilter.h - "WahWah" effect and others + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef DYNAMICFILTER_H +#define DYNAMICFILTER_H +#include "../globals.h" +#include "Effect.h" +#include "EffectLFO.h" + +#include "../DSP/Filter.h" +/**DynamicFilter Effect*/ +class DynamicFilter:public Effect { + public: + DynamicFilter(int insetion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_); + ~DynamicFilter(); + void out(REALTYPE *smpsl,REALTYPE *smpsr); + + void setpreset(unsigned char npreset); + void changepar(const int &npar,const unsigned char &value); + unsigned char getpar(const int &npar)const; + void cleanup(); + +// void setdryonly(); + + private: + //Parametrii DynamicFilter + EffectLFO lfo;//lfo-ul DynamicFilter + unsigned char Pvolume; + unsigned char Ppanning; + unsigned char Pdepth;/** +#include "EQ.h" + +EQ::EQ(const int &insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_) + :Effect(insertion_,efxoutl_,efxoutr_,NULL,0) +{ + + for (int i=0;icleanup(); + filter[i].r->cleanup(); + }; +}; + + + +/* + * Effect output + */ +void EQ::out(REALTYPE *smpsl,REALTYPE *smpsr){ + int i; + for (i=0;ifilterout(efxoutl); + filter[i].r->filterout(efxoutr); + }; +}; + + +/* + * Parameter control + */ +void EQ::setvolume(const unsigned char &Pvolume){ + this->Pvolume=Pvolume; + + outvolume=pow(0.005,(1.0-Pvolume/127.0))*10.0; + if (insertion==0) { + volume=1.0; + } else { + volume=outvolume; + }; + +}; + + +void EQ::setpreset(unsigned char npreset){ + const int PRESET_SIZE=1; + const int NUM_PRESETS=2; + unsigned char presets[NUM_PRESETS][PRESET_SIZE]={ + //EQ 1 + {67}, + //EQ 2 + {67}}; + + if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1; + for (int n=0;n=MAX_EQ_BANDS) return; + int bp=npar%5;//band paramenter + + REALTYPE tmp; + switch(bp){ + case 0: filter[nb].Ptype=value; + if (value>9) filter[nb].Ptype=0;//has to be changed if more filters will be added + if (filter[nb].Ptype!=0){ + filter[nb].l->settype(value-1); + filter[nb].r->settype(value-1); + }; + break; + case 1: filter[nb].Pfreq=value; + tmp=600.0*pow(30.0,(value-64.0)/64.0); + filter[nb].l->setfreq(tmp); + filter[nb].r->setfreq(tmp); + break; + case 2: filter[nb].Pgain=value; + tmp=30.0*(value-64.0)/64.0; + filter[nb].l->setgain(tmp); + filter[nb].r->setgain(tmp); + break; + case 3: filter[nb].Pq=value; + tmp=pow(30.0,(value-64.0)/64.0); + filter[nb].l->setq(tmp); + filter[nb].r->setq(tmp); + break; + case 4: filter[nb].Pstages=value; + if (value>=MAX_FILTER_STAGES) filter[nb].Pstages=MAX_FILTER_STAGES-1; + filter[nb].l->setstages(value); + filter[nb].r->setstages(value); + break; + }; +}; + +unsigned char EQ::getpar(const int &npar)const{ + switch (npar){ + case 0: return(Pvolume); + break; + }; + + if (npar<10) return(0); + + int nb=(npar-10)/5;//number of the band (filter) + if (nb>=MAX_EQ_BANDS) return(0); + int bp=npar%5;//band paramenter + switch(bp){ + case 0: return(filter[nb].Ptype); + break; + case 1: return(filter[nb].Pfreq); + break; + case 2: return(filter[nb].Pgain); + break; + case 3: return(filter[nb].Pq); + break; + case 4: return(filter[nb].Pstages); + break; + }; + + return(0);//in case of bogus parameter number +}; + + + + +REALTYPE EQ::getfreqresponse(REALTYPE freq){ + REALTYPE resp=1.0; + + for (int i=0;iH(freq); + }; + return(rap2dB(resp*outvolume)); +}; + + diff --git a/plugins/zynaddsubfx/src/Effects/EQ.h b/plugins/zynaddsubfx/src/Effects/EQ.h new file mode 100644 index 000000000..315d51a34 --- /dev/null +++ b/plugins/zynaddsubfx/src/Effects/EQ.h @@ -0,0 +1,59 @@ +/* + ZynAddSubFX - a software synthesizer + + EQ.h - EQ Effect + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef EQ_H +#define EQ_H + +#include "../globals.h" +#include "../DSP/AnalogFilter.h" +#include "Effect.h" + +/**EQ Effect*/ +class EQ:public Effect{ + public: + EQ(const int &insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_); + ~EQ(); + void out(REALTYPE *smpsl,REALTYPE *smpr); + void setpreset(unsigned char npreset); + void changepar(const int &npar,const unsigned char &value); + unsigned char getpar(const int &npar)const; + void cleanup(); + REALTYPE getfreqresponse(REALTYPE freq); + private: + //Parameters + unsigned char Pvolume;/** +#include "Echo.h" + +Echo::Echo(const int & insertion_,REALTYPE *const efxoutl_,REALTYPE *const efxoutr_) + : Effect(insertion_,efxoutl_,efxoutr_,NULL,0), + Pvolume(50),Ppanning(64),Pdelay(60), + Plrdelay(100),Plrcross(100),Pfb(40),Phidamp(60), + lrdelay(0),ldelay(NULL),rdelay(NULL) +{ + setpreset(Ppreset); + cleanup(); +} + +Echo::~Echo(){ + delete[] ldelay; + delete[] rdelay; +} + +/* + * Cleanup the effect + */ +void Echo::cleanup(){ + int i; + for (i=0;i=dl) kl=0; + if (++kr>=dr) kr=0; + }; + +} + + +/* + * Parameter control + */ +void Echo::setvolume(const unsigned char & Pvolume){ + this->Pvolume=Pvolume; + + if (insertion==0) { + outvolume=pow(0.01,(1.0-Pvolume/127.0))*4.0; + volume=1.0; + } else { + volume=outvolume=Pvolume/127.0; + }; + if (Pvolume==0) cleanup(); + +} + +void Echo::setpanning(const unsigned char & Ppanning){ + this->Ppanning=Ppanning; + panning=(Ppanning+0.5)/127.0; +} + +void Echo::setdelay(const unsigned char & Pdelay){ + this->Pdelay=Pdelay; + delay=1+(int)(Pdelay/127.0*SAMPLE_RATE*1.5);//0 .. 1.5 sec + initdelays(); +} + +void Echo::setlrdelay(const unsigned char & Plrdelay){ + REALTYPE tmp; + this->Plrdelay=Plrdelay; + tmp=(pow(2,fabs(Plrdelay-64.0)/64.0*9)-1.0)/1000.0*SAMPLE_RATE; + if (Plrdelay<64.0) tmp=-tmp; + lrdelay=(int) tmp; + initdelays(); +} + +void Echo::setlrcross(const unsigned char & Plrcross){ + this->Plrcross=Plrcross; + lrcross=Plrcross/127.0*1.0; +} + +void Echo::setfb(const unsigned char & Pfb){ + this->Pfb=Pfb; + fb=Pfb/128.0; +} + +void Echo::sethidamp(const unsigned char & Phidamp){ + this->Phidamp=Phidamp; + hidamp=1.0-Phidamp/127.0; +} + +void Echo::setpreset(unsigned char npreset){ + /**\todo see if the preset array can be replaced with a struct or a class*/ + const int PRESET_SIZE=7; + const int NUM_PRESETS=9; + unsigned char presets[NUM_PRESETS][PRESET_SIZE]={ + //Echo 1 + {67,64,35,64,30,59,0}, + //Echo 2 + {67,64,21,64,30,59,0}, + //Echo 3 + {67,75,60,64,30,59,10}, + //Simple Echo + {67,60,44,64,30,0,0}, + //Canyon + {67,60,102,50,30,82,48}, + //Panning Echo 1 + {67,64,44,17,0,82,24}, + //Panning Echo 2 + {81,60,46,118,100,68,18}, + //Panning Echo 3 + {81,60,26,100,127,67,36}, + //Feedback Echo + {62,64,28,64,100,90,55}}; + + + if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1; + for (int n=0;n +#include "../Misc/Util.h" +#include "../globals.h" +#include "../Params/FilterParams.h" + + +/**this class is inherited by the all effects(Reverb, Echo, ..)*/ +class Effect{ + public: + /** + * Effect Constructor + * @param insertion_ 1 when it is an insertion Effect and 0 when it + * is not an insertion Effect + * @param efxoutl_ Effect output buffer Left channel + * @param efxoutr_ Effect output buffer Right channel + * @param filterpars_ pointer to FilterParams array + * @param Ppreset_ chosen preset + * @return Initialized Effect object*/ + Effect(const int & insertion_,REALTYPE *const efxoutl_, + REALTYPE *const efxoutr_,FilterParams *filterpars_, + const unsigned char & Ppreset_); + /**Deconstructor + * + * Deconstructs the Effect and releases any resouces that it has + * allocated for itself*/ + virtual ~Effect(){}; + /** + * Choose a preset + * @param npreset number of chosen preset*/ + virtual void setpreset(unsigned char npreset)=0; + /**Change parameter npar to value + * @param npar chosen parameter + * @param value chosen new value*/ + virtual void changepar(const int &npar,const unsigned char &value)=0; + /**Get the value of parameter npar + * @param npar chosen parameter + * @return the value of the parameter in an unsigned char or 0 if it + * does not exist*/ + virtual unsigned char getpar(const int &npar)const=0; + /**Output result of effect based on the given buffers + * + * This method should result in the effect generating its results + * and placing them into the efxoutl and efxoutr buffers. + * Every Effect should overide this method. + * + * @param smpsl Input buffer for the Left channel + * @param smpsr Input buffer for the Right channel + */ + virtual void out(REALTYPE *const smpsl,REALTYPE *const smpsr)=0; + /**Reset the state of the effect*/ + virtual void cleanup(){}; + /**This is only used for EQ (for user interface)*/ + virtual REALTYPE getfreqresponse(REALTYPE freq){return (0);}; + + unsigned char Ppreset;/** +#include + +#include "EffectLFO.h" + + +EffectLFO::EffectLFO(){ + xl=0.0;xr=0.0; + Pfreq=40; + Prandomness=0; + PLFOtype=0; + Pstereo=96; + + updateparams(); + + ampl1=(1-lfornd)+lfornd*RND; + ampl2=(1-lfornd)+lfornd*RND; + ampr1=(1-lfornd)+lfornd*RND; + ampr2=(1-lfornd)+lfornd*RND; +}; + +EffectLFO::~EffectLFO(){ +}; + + +/* + * Update the changed parameters + */ +void EffectLFO::updateparams(){ + REALTYPE lfofreq=(pow(2,Pfreq/127.0*10.0)-1.0)*0.03; + incx=fabs(lfofreq)*(REALTYPE)SOUND_BUFFER_SIZE/(REALTYPE)SAMPLE_RATE; + if (incx>0.49999999) incx=0.499999999; //Limit the Frequency + + lfornd=Prandomness/127.0; + if (lfornd<0.0) lfornd=0.0; else if (lfornd>1.0) lfornd=1.0; + + if (PLFOtype>1) PLFOtype=1;//this has to be updated if more lfo's are added + lfotype=PLFOtype; + + xr=fmod(xl+(Pstereo-64.0)/127.0+1.0,1.0); +}; + + +/* + * Compute the shape of the LFO + */ +REALTYPE EffectLFO::getlfoshape(REALTYPE x){ + REALTYPE out; + switch (lfotype){ + case 1: //EffectLFO_TRIANGLE + if ((x>0.0)&&(x<0.25)) out=4.0*x; + else if ((x>0.25)&&(x<0.75)) out=2-4*x; + else out=4.0*x-4.0; + break; + /**\todo more to be added here; also ::updateparams() need to be updated (to allow more lfotypes)*/ + default:out=cos(x*2*PI);//EffectLFO_SINE + }; + return(out); +}; + +/* + * LFO output + */ +void EffectLFO::effectlfoout(REALTYPE *outl,REALTYPE *outr){ + REALTYPE out; + + out=getlfoshape(xl); + if ((lfotype==0)||(lfotype==1)) out*=(ampl1+xl*(ampl2-ampl1)); + xl+=incx; + if (xl>1.0) { + xl-=1.0; + ampl1=ampl2; + ampl2=(1.0-lfornd)+lfornd*RND; + }; + *outl=(out+1.0)*0.5; + + out=getlfoshape(xr); + if ((lfotype==0)||(lfotype==1)) out*=(ampr1+xr*(ampr2-ampr1)); + xr+=incx; + if (xr>1.0) { + xr-=1.0; + ampr1=ampr2; + ampr2=(1.0-lfornd)+lfornd*RND; + }; + *outr=(out+1.0)*0.5; +}; + diff --git a/plugins/zynaddsubfx/src/Effects/EffectLFO.h b/plugins/zynaddsubfx/src/Effects/EffectLFO.h new file mode 100644 index 000000000..ca78b8414 --- /dev/null +++ b/plugins/zynaddsubfx/src/Effects/EffectLFO.h @@ -0,0 +1,51 @@ +/* + ZynAddSubFX - a software synthesizer + + EffectLFO.h - Stereo LFO used by some effects + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef EFFECT_LFO_H +#define EFFECT_LFO_H + +#include "../globals.h" +/**LFO for some of the Effect objects*/ +class EffectLFO{ + public: + EffectLFO(); + ~EffectLFO(); + void effectlfoout(REALTYPE *outl,REALTYPE *outr); + void updateparams(); + unsigned char Pfreq; + unsigned char Prandomness; + unsigned char PLFOtype; + unsigned char Pstereo;//"64"=0 + private: + REALTYPE getlfoshape(REALTYPE x); + + REALTYPE xl,xr; + REALTYPE incx; + REALTYPE ampl1,ampl2,ampr1,ampr2;//necessary for "randomness" + REALTYPE lfointensity; + REALTYPE lfornd; + char lfotype; /**\todo GET RID OF CHAR (use a subclass if types are needed)*/ +}; + + +#endif + diff --git a/plugins/zynaddsubfx/src/Effects/EffectMgr.C b/plugins/zynaddsubfx/src/Effects/EffectMgr.C new file mode 100644 index 000000000..f61896f6c --- /dev/null +++ b/plugins/zynaddsubfx/src/Effects/EffectMgr.C @@ -0,0 +1,295 @@ +/* + ZynAddSubFX - a software synthesizer + + EffectMgr.C - Effect manager, an interface betwen the program and effects + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include "EffectMgr.h" + +EffectMgr::EffectMgr(int insertion_,pthread_mutex_t *mutex_) + :insertion(insertion_), + efxoutl(new REALTYPE[SOUND_BUFFER_SIZE]), + efxoutr(new REALTYPE[SOUND_BUFFER_SIZE]), + filterpars(NULL),nefx(0),efx(NULL),mutex(mutex_),dryonly(false) +{ + setpresettype("Peffect"); /**\todo Figure out what this is doing + * , as it might be another leaky abstraction.*/ +// efx=NULL; +// nefx=0; +// insertion=insertion_; +// mutex=mutex_; +// efxoutl=new REALTYPE[SOUND_BUFFER_SIZE]; +// efxoutr=new REALTYPE[SOUND_BUFFER_SIZE]; + for (int i=0;ifilterpars; +} + +/* + * Obtain the effect number + */ +int EffectMgr::geteffect(){ + return (nefx); +} + +/* + * Cleanup the current effect + */ +void EffectMgr::cleanup(){ + if (efx!=NULL) efx->cleanup(); +} + + +/* + * Get the preset of the current effect + */ + +unsigned char EffectMgr::getpreset(){ + if (efx!=NULL) return(efx->Ppreset); + else return(0); +} + +/* + * Change the preset of the current effect + */ +void EffectMgr::changepreset_nolock(unsigned char npreset){ + if (efx!=NULL) efx->setpreset(npreset); +} + +/* + * Change the preset of the current effect(with thread locking) + */ +void EffectMgr::changepreset(unsigned char npreset){ + pthread_mutex_lock(mutex); + changepreset_nolock(npreset); + pthread_mutex_unlock(mutex); +} + + +/* + * Change a parameter of the current effect + */ +void EffectMgr::seteffectpar_nolock(int npar,unsigned char value){ + if (efx==NULL) return; + efx->changepar(npar,value); +} + +/* + * Change a parameter of the current effect (with thread locking) + */ +void EffectMgr::seteffectpar(int npar,unsigned char value){ + pthread_mutex_lock(mutex); + seteffectpar_nolock(npar,value); + pthread_mutex_unlock(mutex); +} + +/* + * Get a parameter of the current effect + */ +unsigned char EffectMgr::geteffectpar(int npar){ + if (efx==NULL) return(0); + return(efx->getpar(npar)); +} + + +/* + * Apply the effect + */ +void EffectMgr::out(REALTYPE *smpsl,REALTYPE *smpsr){ + int i; + if (efx==NULL){ + if (insertion==0) + for (i=0;iout(smpsl,smpsr); + + REALTYPE volume=efx->volume; + + if (nefx==7){//this is need only for the EQ effect + /**\todo figure out why*/ + for (i=0;ioutvolume); +} + + +/* + * Get the EQ response + */ +REALTYPE EffectMgr::getEQfreqresponse(REALTYPE freq){ + if (nefx==7) return(efx->getfreqresponse(freq)); + else return(0.0); +} + + +void EffectMgr::setdryonly(bool value){ + dryonly=value; +} + +void EffectMgr::add2XML(XMLwrapper *xml){ + xml->addpar("type",geteffect()); + + if ((efx==NULL)||(geteffect()==0)) return; + xml->addpar("preset",efx->Ppreset); + + xml->beginbranch("EFFECT_PARAMETERS"); + for (int n=0;n<128;n++){ /**\todo evaluate who should oversee saving + * and loading of parameters*/ + int par=geteffectpar(n); + if (par==0) continue; + xml->beginbranch("par_no",n); + xml->addpar("par",par); + xml->endbranch(); + }; + if (filterpars!=NULL){ + xml->beginbranch("FILTER"); + filterpars->add2XML(xml); + xml->endbranch(); + }; + xml->endbranch(); +} + +void EffectMgr::getfromXML(XMLwrapper *xml){ + changeeffect(xml->getpar127("type",geteffect())); + + if ((efx==NULL)||(geteffect()==0)) return; + + efx->Ppreset=xml->getpar127("preset",efx->Ppreset); + + if (xml->enterbranch("EFFECT_PARAMETERS")){ + for (int n=0;n<128;n++){ + seteffectpar_nolock(n,0);//erase effect parameter + if (xml->enterbranch("par_no",n)==0) continue; + + int par=geteffectpar(n); + seteffectpar_nolock(n,xml->getpar127("par",par)); + xml->exitbranch(); + }; + if (filterpars!=NULL){ + if (xml->enterbranch("FILTER")){ + filterpars->getfromXML(xml); + xml->exitbranch(); + }; + }; + xml->exitbranch(); + }; + cleanup(); +} + diff --git a/plugins/zynaddsubfx/src/Effects/EffectMgr.h b/plugins/zynaddsubfx/src/Effects/EffectMgr.h new file mode 100644 index 000000000..c680b335f --- /dev/null +++ b/plugins/zynaddsubfx/src/Effects/EffectMgr.h @@ -0,0 +1,106 @@ +/* + ZynAddSubFX - a software synthesizer + + EffectMgr.h - Effect manager, an interface betwen the program and effects + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef EFFECTMGR_H +#define EFFECTMGR_H + +#include + +#include "Effect.h" +#include "Reverb.h" +#include "Echo.h" +#include "Chorus.h" +#include "Phaser.h" +#include "Alienwah.h" +#include "Distorsion.h" +#include "EQ.h" +#include "DynamicFilter.h" +#include "../Misc/XMLwrapper.h" +#include "../Params/FilterParams.h" +#include "../Params/Presets.h" + + +/**Effect manager, an interface betwen the program and effects*/ +class EffectMgr:public Presets{ + public: + EffectMgr(int insertion_,pthread_mutex_t *mutex_); + ~EffectMgr(); + + void add2XML(XMLwrapper *xml); + void defaults(); + void getfromXML(XMLwrapper *xml); + + void out(REALTYPE *smpsl,REALTYPE *smpsr); + + void setdryonly(bool value); + + /**get the output(to speakers) volume of the systemeffect*/ + REALTYPE sysefxgetvolume(); + + void cleanup();/** +#include "Phaser.h" +/**\todo figure out why this define was made*/ +#define PHASER_LFO_SHAPE 2 + +Phaser::Phaser(const int &insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_) + :Effect(insertion_,efxoutl_,efxoutr_,NULL,0),oldl(NULL),oldr(NULL) +{ + setpreset(Ppreset); + cleanup(); +}; + +Phaser::~Phaser(){ + if (oldl!=NULL) delete [] oldl; + if (oldr!=NULL) delete [] oldr; +}; + + +/* + * Effect output + */ +void Phaser::out(REALTYPE *smpsl,REALTYPE *smpsr){ + int i,j; + REALTYPE lfol,lfor,lgain,rgain,tmp; + + lfo.effectlfoout(&lfol,&lfor); + lgain=lfol; + rgain=lfor; + lgain=(exp(lgain*PHASER_LFO_SHAPE)-1)/(exp(PHASER_LFO_SHAPE)-1.0); + rgain=(exp(rgain*PHASER_LFO_SHAPE)-1)/(exp(PHASER_LFO_SHAPE)-1.0); + + + lgain=1.0-phase*(1.0-depth)-(1.0-phase)*lgain*depth; + rgain=1.0-phase*(1.0-depth)-(1.0-phase)*rgain*depth; + + if (lgain>1.0) lgain=1.0;else if (lgain<0.0) lgain=0.0; + if (rgain>1.0) rgain=1.0;else if (rgain<0.0) rgain=0.0; + + for (i=0;iPdepth=Pdepth; + depth=(Pdepth/127.0); +}; + + +void Phaser::setfb(const unsigned char &Pfb){ + this->Pfb=Pfb; + fb=(Pfb-64.0)/64.1; +}; + +void Phaser::setvolume(const unsigned char &Pvolume){ + this->Pvolume=Pvolume; + outvolume=Pvolume/127.0; + if (insertion==0) volume=1.0; + else volume=outvolume; +}; + +void Phaser::setpanning(const unsigned char &Ppanning){ + this->Ppanning=Ppanning; + panning=Ppanning/127.0; +}; + +void Phaser::setlrcross(const unsigned char &Plrcross){ + this->Plrcross=Plrcross; + lrcross=Plrcross/127.0; +}; + +void Phaser::setstages(const unsigned char &Pstages){ + if (oldl!=NULL) delete [] oldl; + if (oldr!=NULL) delete [] oldr; + if (Pstages>=MAX_PHASER_STAGES) this->Pstages=MAX_PHASER_STAGES-1; + else this->Pstages=Pstages; + oldl=new REALTYPE[Pstages*2]; + oldr=new REALTYPE[Pstages*2]; + cleanup(); +}; + +void Phaser::setphase(const unsigned char &Pphase){ + this->Pphase=Pphase; + phase=(Pphase/127.0); +}; + + +void Phaser::setpreset(unsigned char npreset){ + const int PRESET_SIZE=12; + const int NUM_PRESETS=6; + unsigned char presets[NUM_PRESETS][PRESET_SIZE]={ + //Phaser1 + {64,64,36,0,0,64,110,64,1,0,0,20}, + //Phaser2 + {64,64,35,0,0,88,40,64,3,0,0,20}, + //Phaser3 + {64,64,31,0,0,66,68,107,2,0,0,20}, + //Phaser4 + {39,64,22,0,0,66,67,10,5,0,1,20}, + //Phaser5 + {64,64,20,0,1,110,67,78,10,0,0,20}, + //Phaser6 + {64,64,53,100,0,58,37,78,3,0,0,20}}; + if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1; + for (int n=0;n1) Poutsub=1; + else Poutsub=value; + break; + case 11:setphase(value); + break; + }; +}; + +unsigned char Phaser::getpar(const int &npar)const{ + switch (npar){ + case 0: return(Pvolume); + break; + case 1: return(Ppanning); + break; + case 2: return(lfo.Pfreq); + break; + case 3: return(lfo.Prandomness); + break; + case 4: return(lfo.PLFOtype); + break; + case 5: return(lfo.Pstereo); + break; + case 6: return(Pdepth); + break; + case 7: return(Pfb); + break; + case 8: return(Pstages); + break; + case 9: return(Plrcross); + break; + case 10:return(Poutsub); + break; + case 11:return(Pphase); + break; + default:return (0); + }; + +}; + diff --git a/plugins/zynaddsubfx/src/Effects/Phaser.h b/plugins/zynaddsubfx/src/Effects/Phaser.h new file mode 100644 index 000000000..d74390f89 --- /dev/null +++ b/plugins/zynaddsubfx/src/Effects/Phaser.h @@ -0,0 +1,71 @@ +/* + ZynAddSubFX - a software synthesizer + + Phaser.h - Phaser effect + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef PHASER_H +#define PHASER_H +#include "../globals.h" +#include "Effect.h" +#include "EffectLFO.h" + +#define MAX_PHASER_STAGES 12 +/**Phaser Effect*/ +class Phaser:public Effect { + public: + Phaser(const int &insetion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_); + ~Phaser(); + void out(REALTYPE *smpsl,REALTYPE *smpsr); + void setpreset(unsigned char npreset); + void changepar(const int &npar,const unsigned char &value); + unsigned char getpar(const int &npar)const; + void cleanup(); + void setdryonly(); + + private: + //Parametrii Phaser + EffectLFO lfo;/** +#include "Reverb.h" + +/**\todo: EarlyReflections,Prdelay,Perbalance */ + +Reverb::Reverb(const int &insertion_,REALTYPE *efxoutl_,REALTYPE *efxoutr_) + :Effect(insertion_,efxoutl_,efxoutr_,NULL,0) +{ + inputbuf=new REALTYPE[SOUND_BUFFER_SIZE]; + + //defaults + Pvolume=48; + Ppan=64; + Ptime=64; + Pidelay=40; + Pidelayfb=0; + Prdelay=0; + Plpf=127; + Phpf=0; + Perbalance=64; + Plohidamp=80; + Ptype=1; + Proomsize=64;roomsize=1.0;rs=1.0; + + for (int i=0;icleanup(); + if (lpf!=NULL) lpf->cleanup(); + +}; + +/* + * Process one channel; 0=left,1=right + */ +void Reverb::processmono(int ch,REALTYPE *output){ + int i,j; + REALTYPE fbout,tmp; + /**\todo: implement the high part from lohidamp*/ + + for (j=REV_COMBS*ch;j=comblength) ck=0; + }; + + combk[j]=ck; + lpcomb[j]=lpcombj; + }; + + for (j=REV_APS*ch;j=aplength) ak=0; + }; + apk[j]=ak; + }; +}; + +/* + * Effect output + */ +void Reverb::out(REALTYPE *smps_l, REALTYPE *smps_r){ + int i; + if ((Pvolume==0)&&(insertion!=0)) return; + + for (i=0;i=idelaylen) idelayk=0; + }; + }; + + if (lpf!=NULL) lpf->filterout(inputbuf); + if (hpf!=NULL) hpf->filterout(inputbuf); + + processmono(0,efxoutl);//left + processmono(1,efxoutr);//right + + REALTYPE lvol=rs/REV_COMBS*pan; + REALTYPE rvol=rs/REV_COMBS*(1.0-pan); + if (insertion!=0){ + lvol*=2;rvol*=2; + }; + for (int i=0;iPvolume=Pvolume; + if (insertion==0) { + outvolume=pow(0.01,(1.0-Pvolume/127.0))*4.0; + volume=1.0; + } else { + volume=outvolume=Pvolume/127.0; + if (Pvolume==0) cleanup(); + }; +}; + +void Reverb::setpan(const unsigned char &Ppan){ + this->Ppan=Ppan; + pan=(REALTYPE)Ppan/127.0; +}; + +void Reverb::settime(const unsigned char &Ptime){ + int i; + REALTYPE t; + this->Ptime=Ptime; + t=pow(60.0,(REALTYPE)Ptime/127.0)-0.97; + + for (i=0;iPlohidamp=Plohidamp; + if (Plohidamp==64) { + lohidamptype=0; + lohifb=0.0; + } else { + if (Plohidamp<64) lohidamptype=1; + if (Plohidamp>64) lohidamptype=2; + x=fabs((REALTYPE)(Plohidamp-64)/64.1); + lohifb=x*x; + }; +}; + +void Reverb::setidelay(const unsigned char &Pidelay){ + REALTYPE delay; + this->Pidelay=Pidelay; + delay=pow(50*Pidelay/127.0,2)-1.0; + + if (idelay!=NULL) delete []idelay; + idelay=NULL; + + idelaylen=(int) (SAMPLE_RATE*delay/1000); + if (idelaylen>1) { + idelayk=0; + idelay=new REALTYPE[idelaylen]; + for (int i=0;iPidelayfb=Pidelayfb; + idelayfb=Pidelayfb/128.0; +}; + +void Reverb::sethpf(const unsigned char &Phpf){ + this->Phpf=Phpf; + if (Phpf==0) {//No HighPass + if (hpf!=NULL) delete hpf; + hpf=NULL; + } + else{ + REALTYPE fr=exp(pow(Phpf/127.0,0.5)*log(10000.0))+20.0; + if (hpf==NULL) hpf=new AnalogFilter(3,fr,1,0); + else hpf->setfreq(fr); + }; +}; + +void Reverb::setlpf(const unsigned char &Plpf){ + this->Plpf=Plpf; + if (Plpf==127) {//No LowPass + if (lpf!=NULL) delete lpf; + lpf=NULL; + } + else{ + REALTYPE fr=exp(pow(Plpf/127.0,0.5)*log(25000.0))+40; + if (lpf==NULL) lpf=new AnalogFilter(2,fr,1,0); + else lpf->setfreq(fr); + }; +}; + +void Reverb::settype(unsigned char Ptype){ + const int NUM_TYPES=2; + int combtunings[NUM_TYPES][REV_COMBS]={ + //this is unused (for random) + {0,0,0,0,0,0,0,0}, + //Freeverb by Jezar at Dreampoint + {1116,1188,1277,1356,1422,1491,1557,1617} + }; + int aptunings[NUM_TYPES][REV_APS]={ + //this is unused (for random) + {0,0,0,0}, + //Freeverb by Jezar at Dreampoint + {225,341,441,556} + }; + + if (Ptype>=NUM_TYPES) Ptype=NUM_TYPES-1; + this->Ptype=Ptype; + + REALTYPE tmp; + for (int i=0;iREV_COMBS) tmp+=23.0; + tmp*=SAMPLE_RATE/44100.0;//adjust the combs according to the samplerate + if (tmp<10) tmp=10; + + comblen[i]=(int) tmp; + combk[i]=0; + lpcomb[i]=0; + if (comb[i]!=NULL) delete []comb[i]; + comb[i]=new REALTYPE[comblen[i]]; + }; + + for (int i=0;iREV_APS) tmp+=23.0; + tmp*=SAMPLE_RATE/44100.0;//adjust the combs according to the samplerate + if (tmp<10) tmp=10; + aplen[i]=(int) tmp; + apk[i]=0; + if (ap[i]!=NULL) delete []ap[i]; + ap[i]=new REALTYPE[aplen[i]]; + }; + settime(Ptime); + cleanup(); +}; + +void Reverb::setroomsize(const unsigned char &Proomsize){ + this->Proomsize=Proomsize; + if (Proomsize==0) this->Proomsize=64;//this is because the older versions consider roomsize=0 + roomsize=(this->Proomsize-64.0)/64.0; + if (roomsize>0.0) roomsize*=2.0; + roomsize=pow(10.0,roomsize); + rs=sqrt(roomsize); + settype(Ptype); +}; + +void Reverb::setpreset(unsigned char npreset){ + const int PRESET_SIZE=12; + const int NUM_PRESETS=13; + unsigned char presets[NUM_PRESETS][PRESET_SIZE]={ + //Cathedral1 + {80,64,63,24,0,0,0,85,5,83,1,64}, + //Cathedral2 + {80,64,69,35,0,0,0,127,0,71,0,64}, + //Cathedral3 + {80,64,69,24,0,0,0,127,75,78,1,85}, + //Hall1 + {90,64,51,10,0,0,0,127,21,78,1,64}, + //Hall2 + {90,64,53,20,0,0,0,127,75,71,1,64}, + //Room1 + {100,64,33,0,0,0,0,127,0,106,0,30}, + //Room2 + {100,64,21,26,0,0,0,62,0,77,1,45}, + //Basement + {110,64,14,0,0,0,0,127,5,71,0,25}, + //Tunnel + {85,80,84,20,42,0,0,51,0,78,1,105}, + //Echoed1 + {95,64,26,60,71,0,0,114,0,64,1,64}, + //Echoed2 + {90,64,40,88,71,0,0,114,0,88,1,64}, + //VeryLong1 + {90,64,93,15,0,0,0,114,0,77,0,95}, + //VeryLong2 + {90,64,111,30,0,0,0,114,90,74,1,80}}; + + if (npreset>=NUM_PRESETS) npreset=NUM_PRESETS-1; + for (int n=0;n'Z') --> Zyn + ^^^ + 2) Additive Synthesis ------> Add + ^^^ + 3) Subtractive Synthesis ---> Sub + ^^^ + 4) Effects ----------------> FX + + So, ZynAddSubFX is a SYNthesizer with ADDitive, SUBtractive engines and effects. + + +Q2) How can I load files from older versions of ZynAddSubFX (like *.mas_zyn,etc) +A2) You need to convert them into new format. Please use 2.0.0pre1 or (recomanded) 2.0.0pre2 versions of ZynAddSubFX to load old file formants and save them in the new formats + + +Q3) How can I change the number of parts, voices to ADSynth, effects, etc. ? +A3) Look in src/globals.h and change there theese values. You don't have to change anything else, just recompile all. But most settings must be below 128. As the rule of the thumb if a setting is 128 or below 128, please don't make it bigger than 128. Anyway, I don't belive that you'll need more than 128 for theese settings; for example you don't need 128(or more) effects same time? That's why I put the limit of 128 (using 7 bits of char). + + +Q4) How do I enable Jack support on ZynAddSubFX ? +A4) Look in "Makefile.inc" from "src/" directory for more information. It is highly recomanded that the Jack samplerate to be equal to ZynAddSubFX samplerate (SAMPLE_RATE from globals.h), otherwise the resampling will be done and this will decrease the quality a bit. + diff --git a/plugins/zynaddsubfx/src/HISTORY.txt b/plugins/zynaddsubfx/src/HISTORY.txt new file mode 100644 index 000000000..0166b6d43 --- /dev/null +++ b/plugins/zynaddsubfx/src/HISTORY.txt @@ -0,0 +1,183 @@ +2.2.1 (28 Apr 2005) + - made to work with mxml-2.2 (will NOT work on older versions) + - it is possible to remove completely the graphical user interface (e.g. it can run without X). For this you need to modify the DISABLE_GUI option from the Makefile.inc + - added a commandline -L which load a instrument (.xiz) - now it only loads to part 0 (you can use this option with -l to load a master file and after this the option -L to replace the part) + +2.2.0 (8 Apr 2005) + - the VST version of ZynAddSubFX is removed from the instalation until it will be more stable (hope soon :) ) + - now, the instrument banks contains over 300 high quality instruments + - added "Apply" a button from OscilGen window for PADsynth + - added another parameter to ADsynth that controls the amount of all detunes of voices + - adaptive harmonics postprocess + - improved the VU-meter and added a RMS plot + - Dvorak support for Virtual Keyboard + - many bugs fixed and code cleanups + +2.1.1 (2 Oct 2004) + - Removed a big bug that prevented changing the part +2.1.0 (1 Oct 2004) + - Added a installer for windows (thanks to NSIS installer ( http://nsis.sourceforge.net/ ) ). Both VST and standalone vesions are contained in the same installer. + - Added a new user interface for beginners. You can switch the current user interface with that anytime do you want. + - All parts, effects, etc. are counted from '1' and not from '0' + - Added the posibility to compile the OSS and JACK support in the same binary (look in the Makefile.inc) + - VST host should be able to save all zynaddsubfx parameters into their setups (this is untested) + - Bugfixes and other + +2.0.0 (27 Aug 2004) + - VST version works (there are some issues/bugs but it works) + - Added a advanced Clipboard and Preset module - now is possible to add user preset LFOs,Envelopes, Effects, Oscillators, Resonances, Filters, etc. + - Completely removed the *.MAS_ZYN formats (masters, instruments,etc) support; use 2.0.0pre1 and 2.0.0pre2 to convert + - Corrected a error to pitch bend on VST plugin (thanks to Krzysztof Korpiela) + - Impoved the PADsynth module + - Because the PADsynth module takes a time to load, the instrument that contains such modules are shown in different colors + - Bugfixes + - Other + +2.0.0_pre2 (31 Iul 2004) + - Updated the XMLwrapper to mxml-2.0 + - Many bugfixes + - Other + +2.0.0_pre1 (17 Iul 2004) + - Added a new powerful synth engine which is called PADsynth, you can make very beautifull pads and even some strange sounds + - Now is used the XML format for all zynaddsubfx parameters(.XMZ for master parameters, .XIZ for instrument parameters and .XSZ for scale parameters).You can import older parameters. All parameters files are compressed with gzip algorithm. + - Some parameters has changed and you might ecounter different sounds that you saved in the older versions of zynaddsubfx + - The instrument banks are no longer single files, but directories that contains instrument .XIZ files (you can organize them even with a file manager). Also, you can use more than 1 banks easily. + - Added a new effect called DynamicFilter that allows you to do WahWah,AutoWah, VocalMorpher and other effects + - Speedups + - Started to write a small sequencer that allows to load and play a midi file from zynaddsubfx (unfinished) + - ZynAddSubFX is available from CVS, too. Please look at the sourceforge project page to get more information ( http://sourceforge.net/projects/zynaddsubfx ) + - The waveform generator (OscilGen) has many new parameters :) also if you press the "Shift" key, you can draw the hamonics amplitude/phases + - Many user interface improvements + - You can load a file at the start of the program with "-l" command-line parameter and you can run zynaddsubfx w/o user interface with "-U" + - It is possible to dump all MIDI notes into a text file + - The instruments can contain comments and copyright information in order to encourage sharing of them + - FFT3W library is supported + - More "randomness" options + - Other impovements + - Many, many bugfixes + - Added the full changelog (since I started to write zynaddsubfx), most is in Romanian + - Other things + +1.4.3 (31 Aug 2003) + - added state variable filters and other types to analog filters + - small user interface improvememnts + - small bugfixes + +1.4.2 (17 Iul 2003) + - added full-featured, advanced formantic filters + - added mixer panel which lets you to see/change most important part settings, and shows a vu-meters for each part + - you can choose to process the instrument's kit items only with one Part effect (eg. you can make a instrument kit that contains a reverberated piano and flanged strings) + - enabled to launch more instances in Jack + - when is launched first time, it searches for default.bnk_zyn file into /usr/share/zynaddsubfx and /usr/local/share/zynaddsubfx directories (useful for binary packages for Linux distributions) + - bugfixes + +1.4.1 (8 May 2003) + - added single mode to the instrument kit who alows only one item to be played same time + - added "Spectrum Adjust" to the ADsynth oscillator + - added "drum mode" to the instrument, where all midi keys are mapped to 12tET + - added a parameter to the "440Hz" which make the freq to varies a bit according to the key pressed (very usefull to toms and other drums) + - (for OSS audio out) if it is launched with root privileges, the synth will gain realtime scheduling priority + - bugfixes + +1.4.0 (15 Apr 2003) + - added instrument's own effect (effects that are loaded/saved with the instrument) + - FreeMode Envelopes: all Envelopes can have any shape (not only ADSR) + - Added instrument kits: It is possible to use more than one instruments into one part (used for layered synths or drum kits) + - Amplitude envelopes can be linear or logarithmic + - added interpolation on the Resonance user interface + - user interface improvements and cleanups of it's code + - initiated a mailing list to allow users to share patches for ZynAddSubFX. Please share your ZynAddSubFX patches; look at http://lists.sourceforge.net/mailman/listinfo/zynaddsubfx-user for more information about the mailing list. + +1.2.1 (6 Apr 2003) + - improved filter interpolation + - bugfix: wav header is written correctly + - bugfix: NRPN works correctly (eg:the controller was 0x98 instead of 98), now you can controll all effects parametrer realtime via MIDI + - bugfix: pitch bend works OK in windows + - added master fine detune (-64..63 cents) + - it is possible to swap effects or copy them + - started to port ZynAddSubFX to VST (not functional, yet) + - the resonace can protect the fundamental freq. against damping + +1.2.0 (21 Mar 2003) + - ZynAddSubFX is ported to Windows ;-) + - added internal Virtual Keyboard + - added Configuration window + - added frequency tracking to filter + - improved the OscilGen (harmonic filter, RMS normalisation, etc..) + - improved the recorder (uses the WAV file format and it starts only when a key is pressed) + - added filter interpolation if the frequency is changed very fast (it removes some annoying clicks) + - other improovements, bugfixes, speedups and cleanups of the code + +1.0.9 (24 Feb 2003) + - added keylimit to Part + - you can use multiple filter stages in order to make very steep filter rolloffs (eg. 48 dB/octave) + - ADsynth - added noise mode and you can make fixed frequencies; added the "Punch" parameter + - added an external program "Controller" which enables you to use the mouse for MIDI controllers + - other improvements and bugfixes + +1.0.8 (14 Feb 2003) + - added mono mode and portamento + - added the EQ effect + - the output of a system effect can be sent to others system effects + - minor bugfixes and improvements + +1.0.7 (7 Feb 2003) + - some settings (like samplerate) are set at runtime (by comand line) + - added Distorsion effect + - added controllers, and NRPNs for changing all effects parameters by midi + - bugs removed and other improvements + +1.0.6 (30 Jan 2003) + - Added JACK output ;-) + - Minor improvements and bugfixes + +1.0.5 (24 Jan 2003) + - The bug that crashed ZynAddSubFX if you change some effect parameters, it is realy removed (I forgot to update the file before upload) + - Other bugfixes and code cleanups + - Added a Global Filter to SubSynth + - Added keyresponse limits to Part + - Added presets to Effects + - The fade is smaller on high frequecy content and larger on low frequecies; so you'll don't hear starting clicks on basses and audible fadeins on higher pitched sounds + - Added tunnings to Reverb: you can choose Random of Freeverb + +1.0.4 (7 Jan 2003) + - It is possible to load Scala (.scl and .kbm) files + - Added mapping from note number to scale degree is possible to load Scala kbm files + - Corrected small bugs related to Microtonal + - If you want to use ZynAddSubFX with OSS (or you don't have ALSA) you can modify the Makefile.inc file to compile with OSS only. + - It is shown the real detune (in cents) + - Made a new widget that replaces the Dial widget + - Removed a bug that crashed ZynAddSubFX if you change some effect parameters + +1.0.3 (23 Dec 2002) + - small bugfixes: "Bypass Global Filter" from ADnoteUI dissapears sometimes ; + removed the low amplitude noise produced by the reverb; + if you "acconect" zynaddsubfx with aseqview no note was processed a long time. + - added Notch Filter + - added the option to randomize the ressonance function + - added VU-Meter + - Change the Insertion effect modes behaves (it sounds a bit louder) + - Added to the project an external program called Spliter that splits the + keyboard and alows you to play two instruments same time. You can use this + program with ZynAddSubFX or any other synthesizer. + - Added a new function to OscilGen + +1.0.2-1 (13 Dec 2002) + - bug found and removed: sometimes when Master/Instrument is saved, the synth crashed + +1.0.2 (13 Dec 2002) + - Added instrument banks + - the BandPass Filter's output amplitude was increased + - few fixes of FFTwrapper. See the documentation from "FFTwrapper.h" if you got error messages. + +1.0.1 (6 Dec 2002) + - corrected a bug that made ZynAddSubFX to crash(sometimes) if you disable a part + - wrote Resonance + - added the BandPass filter + - added the recording feature + - added "New instrument" menuitem + +1.0.0 (25 Sep 2002) + - first release, done a lot before it :-) + diff --git a/plugins/zynaddsubfx/src/Input/ALSAMidiIn.C b/plugins/zynaddsubfx/src/Input/ALSAMidiIn.C new file mode 100644 index 000000000..2d19a5ece --- /dev/null +++ b/plugins/zynaddsubfx/src/Input/ALSAMidiIn.C @@ -0,0 +1,111 @@ +/* + ZynAddSubFX - a software synthesizer + + ALSAMidiIn.C - Midi input for ALSA (this creates an ALSA virtual port) + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include "ALSAMidiIn.h" +#include +#include + + +ALSAMidiIn::ALSAMidiIn(){ + int alsaport; + inputok=0; + char portname[50]; + sprintf(portname,"ZynAddSubFX"); + + midi_handle=NULL; + + if (snd_seq_open(&midi_handle,"default",SND_SEQ_OPEN_INPUT,0)!=0) return; + + snd_seq_set_client_name(midi_handle,"ZynAddSubFX");//thanks to Frank Neumann + + alsaport = snd_seq_create_simple_port(midi_handle,portname + ,SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE + ,SND_SEQ_PORT_TYPE_SYNTH); + if (alsaport<0) return; + + inputok=1; +}; + +ALSAMidiIn::~ALSAMidiIn(){ + if (midi_handle) + snd_seq_close(midi_handle); +}; + + +/* + * Get the midi command,channel and parameters + */ +void ALSAMidiIn::getmidicmd(MidiCmdType &cmdtype,unsigned char &cmdchan,int *cmdparams){ + snd_seq_event_t *midievent=NULL; + cmdtype=MidiNull; + + if (inputok==0){ + /* The input is broken. We need to block for a while anyway so other + non-RT threads get a chance to run. */ + sleep(1); + return; + }; + + snd_seq_event_input(midi_handle,&midievent); + + if (midievent==NULL) return; + switch (midievent->type){ + case SND_SEQ_EVENT_NOTEON: + cmdtype=MidiNoteON; + cmdchan=midievent->data.note.channel; + cmdparams[0]=midievent->data.note.note; + cmdparams[1]=midievent->data.note.velocity; + break; + case SND_SEQ_EVENT_NOTEOFF: + cmdtype=MidiNoteOFF; + cmdchan=midievent->data.note.channel; + cmdparams[0]=midievent->data.note.note; + break; + case SND_SEQ_EVENT_PITCHBEND: + cmdtype=MidiController; + cmdchan=midievent->data.control.channel; + cmdparams[0]=C_pitchwheel;//Pitch Bend + cmdparams[1]=midievent->data.control.value; + break; + case SND_SEQ_EVENT_CONTROLLER: + cmdtype=MidiController; + cmdchan=midievent->data.control.channel; + cmdparams[0]=getcontroller(midievent->data.control.param); + cmdparams[1]=midievent->data.control.value; + //fprintf(stderr,"t=%d val=%d\n",midievent->data.control.param,midievent->data.control.value); + break; + + }; +}; + + +int ALSAMidiIn::getalsaid() { + if (midi_handle) { + snd_seq_client_info_t* seq_info; + snd_seq_client_info_malloc(&seq_info); + snd_seq_get_client_info(midi_handle, seq_info); + int id = snd_seq_client_info_get_client(seq_info); + snd_seq_client_info_free(seq_info); + return id; + } + return -1; +} diff --git a/plugins/zynaddsubfx/src/Input/ALSAMidiIn.h b/plugins/zynaddsubfx/src/Input/ALSAMidiIn.h new file mode 100644 index 000000000..947d74ba2 --- /dev/null +++ b/plugins/zynaddsubfx/src/Input/ALSAMidiIn.h @@ -0,0 +1,43 @@ +/* + ZynAddSubFX - a software synthesizer + + ALSAMidiIn.h - Midi input for ALSA (this creates an ALSA virtual port) + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef ALSA_MIDI_IN_H +#define ALSA_MIDI_IN_H + +#include +#include "MidiIn.h" + + +class ALSAMidiIn:public MidiIn{ + public: + ALSAMidiIn(); + ~ALSAMidiIn(); + void getmidicmd(MidiCmdType &cmdtype,unsigned char &cmdchan,int *cmdparams); + int getalsaid(); + + private: + snd_seq_t *midi_handle; +}; + + +#endif + diff --git a/plugins/zynaddsubfx/src/Input/MidiIn.C b/plugins/zynaddsubfx/src/Input/MidiIn.C new file mode 100644 index 000000000..84e2373ca --- /dev/null +++ b/plugins/zynaddsubfx/src/Input/MidiIn.C @@ -0,0 +1,73 @@ +/* + ZynAddSubFX - a software synthesizer + + MidiIn.C - This class is inherited by all the Midi input classes + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include "../globals.h" +#include "MidiIn.h" + +int MidiIn::getcontroller(unsigned char b){ + int ctl=C_NULL; + switch (b){ + case 1:ctl=C_modwheel;//Modulation Wheel + break; + case 7:ctl=C_volume;//Volume + break; + case 10:ctl=C_panning;//Panning + break; + case 11:ctl=C_expression;//Expression + break; + case 64:ctl=C_sustain;//Sustain pedal + break; + case 65:ctl=C_portamento;//Portamento + break; + case 71:ctl=C_filterq;//Filter Q (Sound Timbre) + break; + case 74:ctl=C_filtercutoff;//Filter Cutoff (Brightness) + break; + case 75:ctl=C_bandwidth;//BandWidth + break; + case 76:ctl=C_fmamp;//FM amplitude + break; + case 77:ctl=C_resonance_center;//Resonance Center Frequency + break; + case 78:ctl=C_resonance_bandwidth;//Resonance Bandwith + break; + case 120:ctl=C_allsoundsoff;//All Sounds OFF + break; + case 121:ctl=C_resetallcontrollers;//Reset All Controllers + break; + case 123:ctl=C_allnotesoff;//All Notes OFF + break; + //RPN and NRPN + case 0x06:ctl=C_dataentryhi;//Data Entry (Coarse) + break; + case 0x26:ctl=C_dataentrylo;//Data Entry (Fine) + break; + case 99:ctl=C_nrpnhi;//NRPN (Coarse) + break; + case 98:ctl=C_nrpnlo;//NRPN (Fine) + break; + default:ctl=C_NULL;//unknown controller + //fprintf(stderr,"Controller=%d , par=%d\n",midievent->data.control.param,cmdparams[1]); + break; + }; + return(ctl); +}; diff --git a/plugins/zynaddsubfx/src/Input/MidiIn.h b/plugins/zynaddsubfx/src/Input/MidiIn.h new file mode 100644 index 000000000..196b6b739 --- /dev/null +++ b/plugins/zynaddsubfx/src/Input/MidiIn.h @@ -0,0 +1,42 @@ +/* + ZynAddSubFX - a software synthesizer + + MidiIn.h - This class is inherited by all the Midi input classes + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef MIDI_IN_H +#define MIDI_IN_H + +#include "../globals.h" + +enum MidiCmdType{MidiNull,MidiNoteOFF,MidiNoteON,MidiController}; +#define MP_MAX_BYTES 4000 //in case of loooong SYS_EXes + +class MidiIn{ + public: + virtual void getmidicmd(MidiCmdType &cmdtype,unsigned char &cmdchan,int *cmdparams){}; + virtual ~MidiIn(){}; + int getcontroller(unsigned char b); + protected: + int inputok;//1 if I can read midi bytes from input ports +}; + + +#endif + diff --git a/plugins/zynaddsubfx/src/Input/NULLMidiIn.C b/plugins/zynaddsubfx/src/Input/NULLMidiIn.C new file mode 100644 index 000000000..a0f339df8 --- /dev/null +++ b/plugins/zynaddsubfx/src/Input/NULLMidiIn.C @@ -0,0 +1,43 @@ +/* + ZynAddSubFX - a software synthesizer + + NULLMidiIn.C - a dummy Midi port + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include "NULLMidiIn.h" +#include +#include +#include + +NULLMidiIn::NULLMidiIn(){ +}; + +NULLMidiIn::~NULLMidiIn(){ +}; + + +/* + * Get the midi command,channel and parameters + * It returns MidiNull because it is a dummy driver + */ +void NULLMidiIn::getmidicmd(MidiCmdType &cmdtype,unsigned char &cmdchan,unsigned char *cmdparams){ + cmdtype=MidiNull; +}; + + diff --git a/plugins/zynaddsubfx/src/Input/NULLMidiIn.h b/plugins/zynaddsubfx/src/Input/NULLMidiIn.h new file mode 100644 index 000000000..2c2300641 --- /dev/null +++ b/plugins/zynaddsubfx/src/Input/NULLMidiIn.h @@ -0,0 +1,40 @@ +/* + ZynAddSubFX - a software synthesizer + + NULLMidiIn.h - a dummy Midi port + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef NULL_MIDI_IN_H +#define NULL_MIDI_IN_H + +#include "MidiIn.h" + + +class NULLMidiIn:public MidiIn{ + public: + NULLMidiIn(); + ~NULLMidiIn(); + void getmidicmd(MidiCmdType &cmdtype,unsigned char &cmdchan,unsigned char *cmdparams); + + private: +}; + + +#endif + diff --git a/plugins/zynaddsubfx/src/Input/OSSMidiIn.C b/plugins/zynaddsubfx/src/Input/OSSMidiIn.C new file mode 100644 index 000000000..67b745d7f --- /dev/null +++ b/plugins/zynaddsubfx/src/Input/OSSMidiIn.C @@ -0,0 +1,115 @@ +/* + ZynAddSubFX - a software synthesizer + + OSSMidiIn.C - Midi input for Open Sound System + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include "OSSMidiIn.h" +#include "../Misc/Util.h" + +OSSMidiIn::OSSMidiIn(){ + inputok=0; + midi_handle=open(config.cfg.LinuxOSSSeqInDev,O_RDONLY,0); + if (midi_handle!=-1) inputok=1; + + lastmidicmd=0; + cmdtype=0; + cmdchan=0; + +}; + +OSSMidiIn::~OSSMidiIn(){ + close(midi_handle); +}; + +unsigned char OSSMidiIn::readbyte(){ + unsigned char tmp[4]; + read(midi_handle,&tmp[0],1); + while (tmp[0]!=SEQ_MIDIPUTC){ + read(midi_handle,&tmp[0],4); + }; + return(tmp[1]); +}; + +unsigned char OSSMidiIn::getmidibyte(){ + unsigned char b; + do { + b=readbyte(); + } while (b==0xfe);//drops the Active Sense Messages + return(b); +}; + +/* + * Get the midi command,channel and parameters + */ +void OSSMidiIn::getmidicmd(MidiCmdType &cmdtype,unsigned char &cmdchan,int *cmdparams){ + unsigned char tmp,i; + if (inputok==0) { + cmdtype=MidiNull; + return; + }; + i=0; + if (lastmidicmd==0){//asteapta prima data pana cand vine prima comanda midi + while (tmp<0x80) tmp=getmidibyte(); + lastmidicmd=tmp; + }; + + tmp=getmidibyte(); + + if (tmp>=0x80) { + lastmidicmd=tmp; + tmp=getmidibyte(); + }; + + if ((lastmidicmd>=0x80)&&(lastmidicmd<=0x8f)){//Note OFF + cmdtype=MidiNoteOFF; + cmdchan=lastmidicmd%16; + cmdparams[0]=tmp;//note number + }; + + if ((lastmidicmd>=0x90)&&(lastmidicmd<=0x9f)){//Note ON + cmdtype=MidiNoteON; + cmdchan=lastmidicmd%16; + cmdparams[0]=tmp;//note number + cmdparams[1]=getmidibyte();//velocity + if (cmdparams[1]==0) cmdtype=MidiNoteOFF;//if velocity==0 then is note off + }; + if ((lastmidicmd>=0xB0)&&(lastmidicmd<=0xBF)){//Controllers + cmdtype=MidiController; + cmdchan=lastmidicmd%16; + cmdparams[0]=getcontroller(tmp); + cmdparams[1]=getmidibyte(); + }; + if ((lastmidicmd>=0xE0)&&(lastmidicmd<=0xEF)){//Pitch Wheel + cmdtype=MidiController; + cmdchan=lastmidicmd%16; + cmdparams[0]=C_pitchwheel; + cmdparams[1]=(tmp+getmidibyte()*(int) 128)-8192;//hope this is correct + }; +}; + + diff --git a/plugins/zynaddsubfx/src/Input/OSSMidiIn.h b/plugins/zynaddsubfx/src/Input/OSSMidiIn.h new file mode 100644 index 000000000..7780b38db --- /dev/null +++ b/plugins/zynaddsubfx/src/Input/OSSMidiIn.h @@ -0,0 +1,48 @@ +/* + ZynAddSubFX - a software synthesizer + + OSSMidiIn.h - Midi input for Open Sound System + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef OSS_MIDI_IN_H +#define OSS_MIDI_IN_H + +#include "MidiIn.h" + +class OSSMidiIn:public MidiIn{ + public: + OSSMidiIn(); + ~OSSMidiIn(); + unsigned char getmidibyte(); + unsigned char readbyte(); + + //Midi parser + void getmidicmd(MidiCmdType &cmdtype,unsigned char &cmdchan,int *cmdparams); + unsigned char cmdtype;//the Message Type (noteon,noteof,sysex..) + unsigned char cmdchan;//the channel number + + private: + int midi_handle; + unsigned char lastmidicmd;//last byte (>=80) received from the Midi + +}; + + +#endif + diff --git a/plugins/zynaddsubfx/src/Input/WINMidiIn.C b/plugins/zynaddsubfx/src/Input/WINMidiIn.C new file mode 100644 index 000000000..804378557 --- /dev/null +++ b/plugins/zynaddsubfx/src/Input/WINMidiIn.C @@ -0,0 +1,83 @@ +/* + ZynAddSubFX - a software synthesizer + + WINMidiIn.C - Midi input for Windows + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include +#include +#include +#include +#include + +#include "WINMidiIn.h" +#include "MidiIn.h" +#include "../Misc/Util.h" + +Master *winmaster; +HMIDIIN winmidiinhandle; +MidiIn midictl;//used to convert the controllers to ZynAddSubFX controllers + +void CALLBACK WinMidiInProc(HMIDIIN hMidiIn,UINT wMsg,DWORD dwInstance, + DWORD dwParam1,DWORD dwParam2){ + int midicommand=MidiNull; + if (wMsg==MIM_DATA){ + int cmd,par1,par2; + cmd=dwParam1&0xff; + if (cmd==0xfe) return; + par1=(dwParam1>>8)&0xff; + par2=dwParam1>>16; + //printf("%x %x %x\n",cmd,par1,par2);fflush(stdout); + int cmdchan=cmd&0x0f; + int cmdtype=(cmd>>4)&0x0f; + + int tmp=0; + pthread_mutex_lock(&winmaster->mutex); + switch(cmdtype){ + case(0x8)://noteon + winmaster->NoteOff(cmdchan,par1); + break; + case(0x9)://noteoff + winmaster->NoteOn(cmdchan,par1,par2&0xff); + break; + case(0xb)://controller + winmaster->SetController(cmdchan,midictl.getcontroller(par1),par2&0xff); + break; + case(0xe)://pitch wheel + tmp=(par1+par2*(long int) 128)-8192; + winmaster->SetController(cmdchan,C_pitchwheel,tmp); + break; + default:break; + }; + pthread_mutex_unlock(&winmaster->mutex); + + }; +}; + +void InitWinMidi(Master *master_){ + winmaster=master_; + + long int result=midiInOpen(&winmidiinhandle,config.cfg.WindowsMidiInId,(DWORD)WinMidiInProc,0,CALLBACK_FUNCTION); + result=midiInStart(winmidiinhandle); +}; + +void StopWinMidi(){ + midiInStop(winmidiinhandle); + midiInClose(winmidiinhandle); +}; diff --git a/plugins/zynaddsubfx/src/Input/WINMidiIn.h b/plugins/zynaddsubfx/src/Input/WINMidiIn.h new file mode 100644 index 000000000..d9cc036db --- /dev/null +++ b/plugins/zynaddsubfx/src/Input/WINMidiIn.h @@ -0,0 +1,34 @@ +/* + ZynAddSubFX - a software synthesizer + + WINMidiIn.h - Midi input for Windows + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef WIN_MIDI_IN_H +#define WIN_MIDI_IN_H + + +#include "../Misc/Master.h" + +void InitWinMidi(Master *master_); +void StopWinMidi(); + + +#endif + diff --git a/plugins/zynaddsubfx/src/Misc/Bank.C b/plugins/zynaddsubfx/src/Misc/Bank.C new file mode 100644 index 000000000..2a76cd74f --- /dev/null +++ b/plugins/zynaddsubfx/src/Misc/Bank.C @@ -0,0 +1,562 @@ +/* + ZynAddSubFX - a software synthesizer + + Bank.h - Instrument Bank + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include "Bank.h" +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "Config.h" + +#define INSTRUMENT_EXTENSION ".xiz" + +//if this file exists into a directory, this make the directory to be considered as a bank, even if it not contains a instrument file +#define FORCE_BANK_DIR_FILE ".bankdir" + +Bank::Bank(){ + + + ZERO(defaultinsname,PART_MAX_NAME_LEN); + snprintf(defaultinsname,PART_MAX_NAME_LEN,"%s"," "); + + for (int i=0;i=0) snprintf(tmpfilename,100,"%4d-%s",newslot+1,newname); + else snprintf(tmpfilename,100,"%4d-%s",ninstrument+1,newname); + + //add the zeroes at the start of filename + for (int i=0;i<4;i++) if (tmpfilename[i]==' ') tmpfilename[i]='0'; + + //make the filenames legal + for (int i=0;i<(int) strlen(tmpfilename);i++) { + char c=tmpfilename[i]; + if ((c>='0')&&(c<='9')) continue; + if ((c>='A')&&(c<='Z')) continue; + if ((c>='a')&&(c<='z')) continue; + if ((c=='-')||(c==' ')) continue; + + tmpfilename[i]='_'; + }; + + snprintf(newfilename,1000,"%s/%s.xiz",dirname,tmpfilename); + +// printf("rename %s -> %s\n",ins[ninstrument].filename,newfilename);////////////// + + rename(ins[ninstrument].filename,newfilename); + if (ins[ninstrument].filename) delete []ins[ninstrument].filename; + ins[ninstrument].filename=new char[strlen(newfilename)+5]; + snprintf(ins[ninstrument].filename,strlen(newfilename)+1,"%s",newfilename); + snprintf(ins[ninstrument].name,PART_MAX_NAME_LEN,"%s",&tmpfilename[5]); + +}; + +/* + * Check if there is no instrument on a slot from the bank + */ +int Bank::emptyslot(unsigned int ninstrument){ + if (ninstrument>=BANK_SIZE) return (1); + if (ins[ninstrument].filename==NULL) return(1); + + if (ins[ninstrument].used) return (0); + else return(1); +}; + +/* + * Removes the instrument from the bank + */ +void Bank::clearslot(unsigned int ninstrument){ + if (emptyslot(ninstrument)) return; + +// printf("remove %s \n",ins[ninstrument].filename);//////////////////////// + + + remove(ins[ninstrument].filename); + deletefrombank(ninstrument); +}; + +/* + * Save the instrument to a slot + */ +void Bank::savetoslot(unsigned int ninstrument,Part *part){ + clearslot(ninstrument); + + const int maxfilename=200; + char tmpfilename[maxfilename+20]; + ZERO(tmpfilename,maxfilename+20); + + snprintf(tmpfilename,maxfilename,"%4d-%s",ninstrument+1,(char *)part->Pname); + + //add the zeroes at the start of filename + for (int i=0;i<4;i++) if (tmpfilename[i]==' ') tmpfilename[i]='0'; + + //make the filenames legal + for (int i=0;i<(int)strlen(tmpfilename);i++) { + char c=tmpfilename[i]; + if ((c>='0')&&(c<='9')) continue; + if ((c>='A')&&(c<='Z')) continue; + if ((c>='a')&&(c<='z')) continue; + if ((c=='-')||(c==' ')) continue; + + tmpfilename[i]='_'; + }; + + strncat(tmpfilename,".xiz",maxfilename+10); + + int fnsize=strlen(dirname)+strlen(tmpfilename)+10; + char *filename=new char[fnsize+4]; + ZERO(filename,fnsize+2); + + snprintf(filename,fnsize,"%s/%s",dirname,tmpfilename); + + remove(filename); + part->saveXML(filename); + addtobank(ninstrument,tmpfilename,(char *) part->Pname); + + delete[]filename; +}; + +/* + * Loads the instrument from the bank + */ +void Bank::loadfromslot(unsigned int ninstrument,Part *part){ + if (emptyslot(ninstrument)) return; + + part->defaultsinstrument(); + +// printf("load: %s\n",ins[ninstrument].filename); + + part->loadXMLinstrument(ins[ninstrument].filename); + +}; + + +/* + * Makes current a bank directory + */ +int Bank::loadbank(const char *bankdirname){ + DIR *dir=opendir(bankdirname); + clearbank(); + + if (dir==NULL) return(-1); + + if (dirname!=NULL) delete[]dirname; + dirname=new char[strlen(bankdirname)+1]; + snprintf(dirname,strlen(bankdirname)+1,"%s",bankdirname); + + bankfiletitle=dirname; + + // printf("loadbank %s/\n",bankdirname); + struct dirent *fn; + + while ((fn=readdir(dir))){ + const char *filename= fn->d_name; + + //sa verific daca e si extensia dorita + if (strstr(filename,INSTRUMENT_EXTENSION)==NULL) continue; + + //verify if the name is like this NNNN-name (where N is a digit) + int no=0; + unsigned int startname=0; + + for (unsigned int i=0;i<4;i++) { + if (strlen(filename)<=i) break; + + if ((filename[i]>='0')&&(filename[i]<='9')) { + no=no*10+(filename[i]-'0'); + startname++; + }; + }; + + + if ((startname+1)=2;i--){ + if (name[i]=='.') { + name[i]='\0'; + break; + }; + }; + + if (no!=0){//the instrument position in the bank is found + addtobank(no-1,filename,&name[startname]); + } else { + addtobank(-1,filename,name); + }; + + }; + + + closedir(dir); + + if (dirname!=NULL) { + sprintf(config.cfg.currentBankDir,"%s",dirname); + }; + + return(0); +}; + +/* + * Makes a new bank, put it on a file and makes it current bank + */ +int Bank::newbank(const char *newbankdirname){ + int result; + char tmpfilename[MAX_STRING_SIZE]; + char bankdir[MAX_STRING_SIZE]; + snprintf(bankdir,MAX_STRING_SIZE,"%s",config.cfg.bankRootDirList[0]); + + if (((bankdir[strlen(bankdir)-1])!='/')&&((bankdir[strlen(bankdir)-1])!='\\')){ + strncat(bankdir,"/",MAX_STRING_SIZE); + }; + strncat(bankdir,newbankdirname,MAX_STRING_SIZE-1); +#ifdef OS_WINDOWS + result=mkdir(bankdir); +#else + result=mkdir(bankdir,S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); +#endif + if (result<0) return(-1); + + snprintf(tmpfilename,MAX_STRING_SIZE,"%s/%s",bankdir,FORCE_BANK_DIR_FILE); +// printf("%s\n",tmpfilename); + FILE *tmpfile=fopen(tmpfilename,"w+"); + fclose(tmpfile); + + return(loadbank(bankdir)); +}; + +/* + * Check if the bank is locked (i.e. the file opened was readonly) + */ +int Bank::locked(){ + return(dirname==NULL); +}; + +/* + * Swaps a slot with another + */ +void Bank::swapslot(unsigned int n1, unsigned int n2){ + if ((n1==n2)||(locked())) return; + if (emptyslot(n1)&&(emptyslot(n2))) return; + if (emptyslot(n1)){//change n1 to n2 in order to make + int tmp=n2;n2=n1;n1=tmp; + }; + + if (emptyslot(n2)){//this is just a movement from slot1 to slot2 + setname(n1,getname(n1),n2); + ins[n2]=ins[n1]; + ins[n1].used=false; + ins[n1].name[0]='\0'; + ins[n1].filename=NULL; + ins[n1].info.PADsynth_used=0; + } else {//if both slots are used + if (strcmp(ins[n1].name,ins[n2].name)==0){//change the name of the second instrument if the name are equal + strncat(ins[n2].name,"2",PART_MAX_NAME_LEN); + }; + setname(n1,getname(n1),n2); + setname(n2,getname(n2),n1); + ins_t tmp; + tmp.used=true; + strcpy(tmp.name,ins[n2].name); + char *tmpfilename=ins[n2].filename; + bool padsynth_used=ins[n2].info.PADsynth_used; + + ins[n2]=ins[n1]; + strcpy(ins[n1].name,tmp.name); + ins[n1].filename=tmpfilename; + ins[n1].info.PADsynth_used=padsynth_used; + }; + +}; + + +//a helper function that compares 2 banks[] arrays +int Bank_compar(const void *a,const void *b){ + struct Bank::bankstruct *bank1= (Bank::bankstruct *)a; + struct Bank::bankstruct *bank2= (Bank::bankstruct *)b; + if (((bank1->name)==NULL)||((bank2->name)==NULL)) return(0); + + int result=strcasecmp(bank1->name,bank2->name); + return(result<0); +}; + + +/* + * Re-scan for directories containing instrument banks + */ + +void Bank::rescanforbanks(){ + for (int i=0;id_name; + if (dirname[0]=='.') continue; + + snprintf(bank.dir,maxdirsize,"%s%s%s/",rootdir,separator,dirname); + snprintf(bank.name,maxdirsize,"%s",dirname); + //find out if the directory contains at least 1 instrument + bool isbank=false; + + DIR *d=opendir(bank.dir); + if (d==NULL) continue; + + struct dirent *fname; + + while((fname=readdir(d))){ + if ((strstr(fname->d_name,INSTRUMENT_EXTENSION)!=NULL)|| + (strstr(fname->d_name,FORCE_BANK_DIR_FILE)!=NULL)){ + isbank=true; + break;//aici as putea pune in loc de break un update la un counter care imi arata nr. de instrumente din bank + }; + }; + + closedir(d); + + if (isbank) { + int pos=-1; + for (int i=1;i=0) { + banks[pos].name=new char[maxdirsize]; + banks[pos].dir=new char[maxdirsize]; + snprintf(banks[pos].name,maxdirsize,"%s",bank.name); + snprintf(banks[pos].dir,maxdirsize,"%s",bank.dir); + }; + + }; + + }; + + closedir(dir); + +}; + +void Bank::clearbank(){ + for (int i=0;i=0)&&(pos=BANK_SIZE) pos=-1; + + + if (pos<0) {//find a free position + for (int i=BANK_SIZE-1;i>=0;i--) + if (!ins[i].used) { + pos=i; + break; + }; + + }; + + if (pos<0) return (-1);//the bank is full + + // printf("%s %d\n",filename,pos); + + deletefrombank(pos); + + ins[pos].used=true; + snprintf(ins[pos].name,PART_MAX_NAME_LEN,"%s",name); + + snprintf(tmpinsname[pos],PART_MAX_NAME_LEN+10," "); + + int len=strlen(filename)+1+strlen(dirname); + ins[pos].filename=new char[len+2]; + ins[pos].filename[len+1]=0; + snprintf(ins[pos].filename,len+1,"%s/%s",dirname,filename); + + //see if PADsynth is used + if (config.cfg.CheckPADsynth){ + XMLwrapper *xml=new XMLwrapper(); + xml->checkfileinformation(ins[pos].filename); + + ins[pos].info.PADsynth_used=xml->information.PADsynth_used; + delete xml; + } else ins[pos].info.PADsynth_used=false; + + return(0); +}; + +bool Bank::isPADsynth_used(unsigned int ninstrument){ + if (config.cfg.CheckPADsynth==0) return(0); + else return(ins[ninstrument].info.PADsynth_used); +}; + + +void Bank::deletefrombank(int pos){ + if ((pos<0)||(pos>=BANK_SIZE)) return; + ins[pos].used=false; + ZERO(ins[pos].name,PART_MAX_NAME_LEN+1); + if (ins[pos].filename!=NULL) { + delete []ins[pos].filename; + ins[pos].filename=NULL; + }; + + ZERO(tmpinsname[pos],PART_MAX_NAME_LEN+20); + +}; + diff --git a/plugins/zynaddsubfx/src/Misc/Bank.h b/plugins/zynaddsubfx/src/Misc/Bank.h new file mode 100644 index 000000000..dc35d77aa --- /dev/null +++ b/plugins/zynaddsubfx/src/Misc/Bank.h @@ -0,0 +1,100 @@ +/* + ZynAddSubFX - a software synthesizer + + Bank.C - Instrument Bank + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef BANK_H +#define BANK_H + +#include "../globals.h" +#include "XMLwrapper.h" +#include "Part.h" + +#define BANK_SIZE 160 + +/* + * The max. number of banks that are used + */ +#define MAX_NUM_BANKS 400 + + +class Bank{ + public: + Bank(); + ~Bank(); + char *getname(unsigned int ninstrument); + char *getnamenumbered(unsigned int ninstrument); + void setname(unsigned int ninstrument,const char *newname,int newslot);//if newslot==-1 then this is ignored, else it will be put on that slot + bool isPADsynth_used(unsigned int ninstrument); + + //returns 0 if the slot is not empty or 1 if the slot is empty + int emptyslot(unsigned int ninstrument); + + void clearslot(unsigned int ninstrument); + void savetoslot(unsigned int ninstrument,Part *part); + void loadfromslot(unsigned int ninstrument,Part *part); + + void swapslot(unsigned int n1,unsigned int n2); + + int loadbank(const char *bankdirname); + int newbank(const char *newbankdirname); + + char *bankfiletitle; //this is shown on the UI of the bank (the title of the window) + int locked(); + + void rescanforbanks(); + + struct bankstruct{ + char *dir; + char *name; + }; + + bankstruct banks[MAX_NUM_BANKS]; + + private: + + //it adds a filename to the bank + //if pos is -1 it try to find a position + //returns -1 if the bank is full, or 0 if the instrument was added + int addtobank(int pos,const char* filename,const char* name); + + void deletefrombank(int pos); + + void clearbank(); + + char defaultinsname[PART_MAX_NAME_LEN]; + char tmpinsname[BANK_SIZE][PART_MAX_NAME_LEN+20];//this keeps the numbered names + + struct ins_t{ + bool used; + char name[PART_MAX_NAME_LEN+1]; + char *filename; + struct{ + bool PADsynth_used; + } info; + }ins[BANK_SIZE]; + + char *dirname; + + void scanrootdir(char *rootdir);//scans a root dir for banks +}; + +#endif + diff --git a/plugins/zynaddsubfx/src/Misc/Config.C b/plugins/zynaddsubfx/src/Misc/Config.C new file mode 100644 index 000000000..e8f54f8d6 --- /dev/null +++ b/plugins/zynaddsubfx/src/Misc/Config.C @@ -0,0 +1,331 @@ +/* + ZynAddSubFX - a software synthesizer + + Config.C - Configuration file functions + Copyright (C) 2003-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ +#include +#include +#include +#include + +#ifdef OS_WINDOWS +#include +#include +#endif + +#include "Config.h" +#include "XMLwrapper.h" + +Config::Config(){ +}; +void Config::init(){ + maxstringsize=MAX_STRING_SIZE;//for ui + //defaults + cfg.SampleRate=44100; + cfg.SoundBufferSize=256; + cfg.OscilSize=1024; + cfg.SwapStereo=0; + + cfg.LinuxOSSWaveOutDev=new char[MAX_STRING_SIZE]; + snprintf(cfg.LinuxOSSWaveOutDev,MAX_STRING_SIZE,"/dev/dsp"); + cfg.LinuxOSSSeqInDev=new char[MAX_STRING_SIZE]; + snprintf(cfg.LinuxOSSSeqInDev,MAX_STRING_SIZE,"/dev/sequencer"); + + cfg.DumpFile=new char[MAX_STRING_SIZE]; + snprintf(cfg.DumpFile,MAX_STRING_SIZE,"zynaddsubfx_dump.txt"); + + cfg.WindowsWaveOutId=0; + cfg.WindowsMidiInId=0; + + cfg.BankUIAutoClose=0; + cfg.DumpNotesToFile=0; + cfg.DumpAppend=1; + + cfg.GzipCompression=3; + + cfg.Interpolation=0; + cfg.CheckPADsynth=1; + + cfg.UserInterfaceMode=0; + cfg.VirKeybLayout=1; + winwavemax=1;winmidimax=1; +//try to find out how many input midi devices are there +#ifdef WINMIDIIN + winmidimax=midiInGetNumDevs(); + if (winmidimax==0) winmidimax=1; +#endif + winmididevices=new winmidionedevice[winmidimax]; + for (int i=0;iloadXMLfile(filename)<0) return; + if (xmlcfg->enterbranch("CONFIGURATION")){ + cfg.SampleRate=xmlcfg->getpar("sample_rate",cfg.SampleRate,4000,1024000); + cfg.SoundBufferSize=xmlcfg->getpar("sound_buffer_size",cfg.SoundBufferSize,16,8192); + cfg.OscilSize=xmlcfg->getpar("oscil_size",cfg.OscilSize,MAX_AD_HARMONICS*2,131072); + cfg.SwapStereo=xmlcfg->getpar("swap_stereo",cfg.SwapStereo,0,1); + cfg.BankUIAutoClose=xmlcfg->getpar("bank_window_auto_close",cfg.BankUIAutoClose,0,1); + + cfg.DumpNotesToFile=xmlcfg->getpar("dump_notes_to_file",cfg.DumpNotesToFile,0,1); + cfg.DumpAppend=xmlcfg->getpar("dump_append",cfg.DumpAppend,0,1); + xmlcfg->getparstr("dump_file",cfg.DumpFile,MAX_STRING_SIZE); + + cfg.GzipCompression=xmlcfg->getpar("gzip_compression",cfg.GzipCompression,0,9); + + xmlcfg->getparstr("bank_current",cfg.currentBankDir,MAX_STRING_SIZE); + cfg.Interpolation=xmlcfg->getpar("interpolation",cfg.Interpolation,0,1); + + cfg.CheckPADsynth=xmlcfg->getpar("check_pad_synth",cfg.CheckPADsynth,0,1); + + + cfg.UserInterfaceMode=xmlcfg->getpar("user_interface_mode",cfg.UserInterfaceMode,0,2); + cfg.VirKeybLayout=xmlcfg->getpar("virtual_keyboard_layout",cfg.VirKeybLayout,0,10); + + //get bankroot dirs + for (int i=0;ienterbranch("BANKROOT",i)){ + cfg.bankRootDirList[i]=new char[MAX_STRING_SIZE]; + xmlcfg->getparstr("bank_root",cfg.bankRootDirList[i],MAX_STRING_SIZE); + xmlcfg->exitbranch(); + }; + }; + + //get preset root dirs + for (int i=0;ienterbranch("PRESETSROOT",i)){ + cfg.presetsDirList[i]=new char[MAX_STRING_SIZE]; + xmlcfg->getparstr("presets_root",cfg.presetsDirList[i],MAX_STRING_SIZE); + xmlcfg->exitbranch(); + }; + }; + + //linux stuff + xmlcfg->getparstr("linux_oss_wave_out_dev",cfg.LinuxOSSWaveOutDev,MAX_STRING_SIZE); + xmlcfg->getparstr("linux_oss_seq_in_dev",cfg.LinuxOSSSeqInDev,MAX_STRING_SIZE); + + //windows stuff + cfg.WindowsWaveOutId=xmlcfg->getpar("windows_wave_out_id",cfg.WindowsWaveOutId,0,winwavemax); + cfg.WindowsMidiInId=xmlcfg->getpar("windows_midi_in_id",cfg.WindowsMidiInId,0,winmidimax); + + xmlcfg->exitbranch(); + }; + delete(xmlcfg); + + cfg.OscilSize=(int) pow(2,ceil(log (cfg.OscilSize-1.0)/log(2.0))); + +}; + +void Config::saveConfig(const char *filename){ + XMLwrapper *xmlcfg=new XMLwrapper(); + + xmlcfg->beginbranch("CONFIGURATION"); + + xmlcfg->addpar("sample_rate",cfg.SampleRate); + xmlcfg->addpar("sound_buffer_size",cfg.SoundBufferSize); + xmlcfg->addpar("oscil_size",cfg.OscilSize); + xmlcfg->addpar("swap_stereo",cfg.SwapStereo); + xmlcfg->addpar("bank_window_auto_close",cfg.BankUIAutoClose); + + xmlcfg->addpar("dump_notes_to_file",cfg.DumpNotesToFile); + xmlcfg->addpar("dump_append",cfg.DumpAppend); + xmlcfg->addparstr("dump_file",cfg.DumpFile); + + xmlcfg->addpar("gzip_compression",cfg.GzipCompression); + + xmlcfg->addpar("check_pad_synth",cfg.CheckPADsynth); + + xmlcfg->addparstr("bank_current",cfg.currentBankDir); + + xmlcfg->addpar("user_interface_mode",cfg.UserInterfaceMode); + xmlcfg->addpar("virtual_keyboard_layout",cfg.VirKeybLayout); + + + for (int i=0;ibeginbranch("BANKROOT",i); + xmlcfg->addparstr("bank_root",cfg.bankRootDirList[i]); + xmlcfg->endbranch(); + }; + + for (int i=0;ibeginbranch("PRESETSROOT",i); + xmlcfg->addparstr("presets_root",cfg.presetsDirList[i]); + xmlcfg->endbranch(); + }; + + xmlcfg->addpar("interpolation",cfg.Interpolation); + + //linux stuff + xmlcfg->addparstr("linux_oss_wave_out_dev",cfg.LinuxOSSWaveOutDev); + xmlcfg->addparstr("linux_oss_seq_in_dev",cfg.LinuxOSSSeqInDev); + + //windows stuff + xmlcfg->addpar("windows_wave_out_id",cfg.WindowsWaveOutId); + xmlcfg->addpar("windows_midi_in_id",cfg.WindowsMidiInId); + + xmlcfg->endbranch(); + + int tmp=cfg.GzipCompression; + cfg.GzipCompression=0; + xmlcfg->saveXMLfile(filename); + cfg.GzipCompression=tmp; + + delete(xmlcfg); +}; + +void Config::getConfigFileName(char *name, int namesize){ + name[0]=0; +#ifdef OS_LINUX + snprintf(name,namesize,"%s%s",getenv("HOME"),"/.zynaddsubfxXML.cfg"); +#else + snprintf(name,namesize,"%s","zynaddsubfxXML.cfg"); +#endif + +}; + diff --git a/plugins/zynaddsubfx/src/Misc/Config.h b/plugins/zynaddsubfx/src/Misc/Config.h new file mode 100644 index 000000000..597d62bc2 --- /dev/null +++ b/plugins/zynaddsubfx/src/Misc/Config.h @@ -0,0 +1,67 @@ +/* + ZynAddSubFX - a software synthesizer + + Config.h - Configuration file functions + Copyright (C) 2003-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef CONFIG_H +#define CONFIG_H +#include "../globals.h" +#define MAX_STRING_SIZE 4000 +#define MAX_BANK_ROOT_DIRS 100 + +class Config{ + public: + Config(); + ~Config(); + struct { + char *LinuxOSSWaveOutDev,*LinuxOSSSeqInDev; + int SampleRate,SoundBufferSize,OscilSize,SwapStereo; + int WindowsWaveOutId,WindowsMidiInId; + int BankUIAutoClose; + int DumpNotesToFile,DumpAppend; + int GzipCompression; + int Interpolation; + char *DumpFile; + char *bankRootDirList[MAX_BANK_ROOT_DIRS],*currentBankDir; + char *presetsDirList[MAX_BANK_ROOT_DIRS]; + int CheckPADsynth; + int UserInterfaceMode; + int VirKeybLayout; + } cfg; + int winwavemax,winmidimax;//number of wave/midi devices on Windows + int maxstringsize; + + struct winmidionedevice{ + char *name; + }; + winmidionedevice *winmididevices; + + void clearbankrootdirlist(); + void clearpresetsdirlist(); + void init(); + void save(); + + private: + void readConfig(const char *filename); + void saveConfig(const char *filename); + void getConfigFileName(char *name,int namesize); +}; +#endif + diff --git a/plugins/zynaddsubfx/src/Misc/Dump.C b/plugins/zynaddsubfx/src/Misc/Dump.C new file mode 100644 index 000000000..bf26d9e32 --- /dev/null +++ b/plugins/zynaddsubfx/src/Misc/Dump.C @@ -0,0 +1,99 @@ +/* + ZynAddSubFX - a software synthesizer + + Dump.C - It dumps the notes to a text file + + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#include +#include +#include "Util.h" +#include "Dump.h" + +Dump dump; + +Dump::Dump(){ + file=NULL; + tick=0; + k=0; + keyspressed=0; +}; + +Dump::~Dump(){ + if (file!=NULL) { + double duration=(double)tick*(double) SOUND_BUFFER_SIZE/(double) SAMPLE_RATE; + fprintf(file,"\n# statistics: duration = %d seconds; keyspressed = %d\n\n\n\n",(int) duration,keyspressed); + fclose(file); + }; +}; + +void Dump::startnow(){ + if (file!=NULL) return;//the file is already open + + if (config.cfg.DumpNotesToFile!=0){ + if (config.cfg.DumpAppend!=0) file=fopen(config.cfg.DumpFile,"a"); + else file=fopen(config.cfg.DumpFile,"w"); + if (file==NULL) return; + if (config.cfg.DumpAppend!=0) fprintf(file,"%s","#************************************\n"); + + time_t tm=time(NULL); + + fprintf(file,"#date/time = %s\n",ctime(&tm)); + fprintf(file,"#1 tick = %g milliseconds\n",SOUND_BUFFER_SIZE*1000.0/SAMPLE_RATE); + fprintf(file,"SAMPLERATE = %d\n",SAMPLE_RATE); + fprintf(file,"TICKSIZE = %d #samples\n",SOUND_BUFFER_SIZE); + fprintf(file,"\n\nSTART\n"); + }; +}; + +void Dump::inctick(){ + tick++; +}; + + +void Dump::dumpnote(char chan,char note, char vel){ + if (file==NULL) return; + if (note==0) return; + if (vel==0) fprintf(file,"n %d -> %d %d \n",tick,chan,note);//note off + else fprintf(file,"N %d -> %d %d %d \n",tick,chan,note,vel);//note on + + if (vel!=0) keyspressed++; +#ifndef JACKAUDIOOUT + if (k++>25) { + fflush(file); + k=0; + }; +#endif +}; + +void Dump::dumpcontroller(char chan,unsigned int type,int par){ + if (file==NULL) return; + switch(type){ + case C_pitchwheel:fprintf(file,"P %d -> %d %d\n",tick,chan,par); + break; + default:fprintf(file,"C %d -> %d %d %d\n",tick,chan,type,par); + break; + }; +#ifndef JACKAUDIOOUT + if (k++>25) { + fflush(file); + k=0; + }; +#endif +}; + + diff --git a/plugins/zynaddsubfx/src/Misc/Dump.h b/plugins/zynaddsubfx/src/Misc/Dump.h new file mode 100644 index 000000000..8304ddd61 --- /dev/null +++ b/plugins/zynaddsubfx/src/Misc/Dump.h @@ -0,0 +1,43 @@ +/* + ZynAddSubFX - a software synthesizer + + Dump.h - It dumps the notes to a text file + + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#ifndef DUMP_H +#define DUMP_H + +#include + +class Dump{ + public: + Dump(); + ~Dump(); + void startnow(); + void inctick(); + + void dumpnote(char chan,char note, char vel); + void dumpcontroller(char chan,unsigned int type,int par); + + private: + FILE *file; + int tick; + int k; + int keyspressed; +}; +#endif diff --git a/plugins/zynaddsubfx/src/Misc/Master.C b/plugins/zynaddsubfx/src/Misc/Master.C new file mode 100644 index 000000000..095eba469 --- /dev/null +++ b/plugins/zynaddsubfx/src/Misc/Master.C @@ -0,0 +1,738 @@ +/* + ZynAddSubFX - a software synthesizer + + Master.C - It sends Midi Messages to Parts, receives samples from parts, + process them with system/insertion effects and mix them + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include "Master.h" + +#include +#include +#include + +#include + +Master::Master(){ + swaplr=0; + + pthread_mutex_init(&mutex,NULL); + fft=new FFTwrapper(OSCIL_SIZE); + + tmpmixl=new REALTYPE[SOUND_BUFFER_SIZE]; + tmpmixr=new REALTYPE[SOUND_BUFFER_SIZE]; + audiooutl=new REALTYPE[SOUND_BUFFER_SIZE]; + audiooutr=new REALTYPE[SOUND_BUFFER_SIZE]; + + ksoundbuffersample=-1;//this is only time when this is -1; this means that the GetAudioOutSamples was never called + ksoundbuffersamplelow=0.0; + oldsamplel=0.0;oldsampler=0.0; + shutup=0; + for (int npart=0;npartdefaults(); + part[npart]->Prcvchn=npart%NUM_MIDI_CHANNELS; + }; + + partonoff(0,1);//enable the first part + + for (int nefx=0;nefxdefaults(); + Pinsparts[nefx]=-1; + }; + + //System Effects init + for (int nefx=0;nefxdefaults(); + for (int npart=0;npartchangeeffect(1); + microtonal.defaults(); + ShutUp(); +}; + +/* + * Note On Messages (velocity=0 for NoteOff) + */ +void Master::NoteOn(unsigned char chan,unsigned char note,unsigned char velocity){ + dump.dumpnote(chan,note,velocity); + + noteon(chan,note,velocity); +}; + +/* + * Internal Note On (velocity=0 for NoteOff) + */ +void Master::noteon(unsigned char chan,unsigned char note,unsigned char velocity){ + int npart; + if (velocity!=0){ + for (npart=0;npartPrcvchn){ + fakepeakpart[npart]=velocity*2; + if (part[npart]->Penabled!=0) part[npart]->NoteOn(note,velocity,keyshift); + }; + }; + }else{ + this->NoteOff(chan,note); + }; + HDDRecorder.triggernow(); +}; + +/* + * Note Off Messages + */ +void Master::NoteOff(unsigned char chan,unsigned char note){ + dump.dumpnote(chan,note,0); + + noteoff(chan,note); +}; + +/* + * Internal Note Off + */ +void Master::noteoff(unsigned char chan,unsigned char note){ + int npart; + for (npart=0;npartPrcvchn) && (part[npart]->Penabled!=0)) + part[npart]->NoteOff(note); + }; +}; + +/* + * Controllers + */ +void Master::SetController(unsigned char chan,unsigned int type,int par){ + dump.dumpcontroller(chan,type,par); + + setcontroller(chan,type,par); +}; + +/* + * Internal Controllers + */ +void Master::setcontroller(unsigned char chan,unsigned int type,int par){ + if ((type==C_dataentryhi)||(type==C_dataentrylo)|| + (type==C_nrpnhi)||(type==C_nrpnlo)){//Process RPN and NRPN by the Master (ignore the chan) + ctl.setparameternumber(type,par); + + int parhi=-1,parlo=-1,valhi=-1,vallo=-1; + if (ctl.getnrpn(&parhi,&parlo,&valhi,&vallo)==0){//this is NRPN + //fprintf(stderr,"rcv. NRPN: %d %d %d %d\n",parhi,parlo,valhi,vallo); + switch (parhi){ + case 0x04://System Effects + if (parloseteffectpar_nolock(valhi,vallo); + }; + break; + case 0x08://Insertion Effects + if (parloseteffectpar_nolock(valhi,vallo); + }; + break; + + }; + }; + } else {//other controllers + for (int npart=0;npartPrcvchn) && (part[npart]->Penabled!=0)) + part[npart]->SetController(type,par); + }; + }; +}; + + +/* + * Enable/Disable a part + */ +void Master::partonoff(int npart,int what){ + if (npart>=NUM_MIDI_PARTS) return; + if (what==0){//disable part + fakepeakpart[npart]=0; + part[npart]->Penabled=0; + part[npart]->cleanup(); + for (int nefx=0;nefxcleanup(); + }; + }; + } else {//enabled + part[npart]->Penabled=1; + fakepeakpart[npart]=0; + }; +}; + +/* + * Master audio out (the final sound) + */ +void Master::AudioOut(REALTYPE *outl,REALTYPE *outr){ + int i,npart,nefx; + +/* //test!!!!!!!!!!!!! se poate bloca aici (mutex) + if (seq.play){ + int type,par1,par2,again,midichan; + int ntrack=1; +// do{ + again=seq.getevent(ntrack,&midichan,&type,&par1,&par2); + if (type>0) { +// printf("aaa\n"); + + if (type==1){//note_on or note_off + if (par2!=0) NoteOn(midichan,par1,par2); + else NoteOff(midichan,par1); + }; + }; +// } while (again); + }; +*/ + + +// printf("zzzz\n"); + + + //Swaps the Left channel with Right Channel (if it is asked for) + if (swaplr!=0){ + REALTYPE *tmp=outl; + outl=outr; + outr=tmp; + }; + + //clean up the output samples + for (i=0;ipartoutl,partoutr + for (npart=0;npartPenabled!=0) part[npart]->ComputePartSmps(); + + //Insertion effects + for (nefx=0;nefx=0) { + int efxpart=Pinsparts[nefx]; + if (part[efxpart]->Penabled!=0) + insefx[nefx]->out(part[efxpart]->partoutl,part[efxpart]->partoutr); + }; + }; + + + //Apply the part volumes and pannings (after insertion effects) + for (npart=0;npartPenabled==0) continue; + + REALTYPE newvol_l=part[npart]->volume; + REALTYPE newvol_r=part[npart]->volume; + REALTYPE oldvol_l=part[npart]->oldvolumel; + REALTYPE oldvol_r=part[npart]->oldvolumer; + REALTYPE pan=part[npart]->panning; + if (pan<0.5) newvol_l*=pan*2.0; + else newvol_r*=(1.0-pan)*2.0; + + if (ABOVE_AMPLITUDE_THRESHOLD(oldvol_l,newvol_l)|| + ABOVE_AMPLITUDE_THRESHOLD(oldvol_r,newvol_r)){//the volume or the panning has changed and needs interpolation + + for (i=0;ipartoutl[i]*=vol_l; + part[npart]->partoutr[i]*=vol_r; + }; + part[npart]->oldvolumel=newvol_l; + part[npart]->oldvolumer=newvol_r; + + } else { + for (i=0;ipartoutl[i]*=newvol_l; + part[npart]->partoutr[i]*=newvol_r; + }; + }; + }; + + + //System effects + for (nefx=0;nefxgeteffect()==0) continue;//the effect is disabled + + //Clean up the samples used by the system effects + for (i=0;iPenabled==0) continue; + + //the output volume of each part to system effect + REALTYPE vol=sysefxvol[nefx][npart]; + for (i=0;ipartoutl[i]*vol; + tmpmixr[i]+=part[npart]->partoutr[i]*vol; + }; + }; + + // system effect send to next ones + for (int nefxfrom=0;nefxfromefxoutl[i]*v; + tmpmixr[i]+=sysefx[nefxfrom]->efxoutr[i]*v; + }; + }; + }; + + sysefx[nefx]->out(tmpmixl,tmpmixr); + + //Add the System Effect to sound output + REALTYPE outvol=sysefx[nefx]->sysefxgetvolume(); + for (i=0;ipartoutl[i]; + outr[i]+=part[npart]->partoutr[i]; + }; + }; + + //Insertion effects for Master Out + for (nefx=0;nefxout(outl,outr); + }; + + //Master Volume + for (i=0;ivuoutpeakl) vuoutpeakl=fabs(outl[i]); + if (fabs(outr[i])>vuoutpeakr) vuoutpeakr=fabs(outr[i]); + }; + if ((vuoutpeakl>1.0)||(vuoutpeakr>1.0)) vuclipped=1; + if (vumaxoutpeaklPenabled!=0) { + REALTYPE *outl=part[npart]->partoutl, + *outr=part[npart]->partoutr; + for (i=0;ivuoutpeakpart[npart]) vuoutpeakpart[npart]=tmp; + }; + vuoutpeakpart[npart]*=volume; + } else { + if (fakepeakpart[npart]>1) fakepeakpart[npart]--; + }; + }; + + + //Shutup if it is asked (with fade-out) + if (shutup!=0){ + for (i=0;i=SOUND_BUFFER_SIZE){ + AudioOut(&audiooutl[0],&audiooutr[0]); + ksoundbuffersample=0; + }; + }; + } else {//Resample + int ksample=0; + REALTYPE srinc=SAMPLE_RATE/(REALTYPE)samplerate; + + while (ksample=1.0){ + ksoundbuffersample+=(int) floor(ksoundbuffersamplelow); + ksoundbuffersamplelow=ksoundbuffersamplelow-floor(ksoundbuffersamplelow); + }; + + if (ksoundbuffersample>=SOUND_BUFFER_SIZE){ + oldsamplel=audiooutl[SOUND_BUFFER_SIZE-1]; + oldsampler=audiooutr[SOUND_BUFFER_SIZE-1]; + AudioOut(&audiooutl[0],&audiooutr[0]); + ksoundbuffersample=0; + }; + }; + }; +}; + + +Master::~Master(){ + for (int npart=0;npartcleanup(); + fakepeakpart[npart]=0; + }; + for (int nefx=0;nefxcleanup(); + for (int nefx=0;nefxcleanup(); + vuresetpeaks(); + shutup=0; +}; + + +/* + * Reset peaks and clear the "cliped" flag (for VU-meter) + */ +void Master::vuresetpeaks(){ + vuoutpeakl=1e-9;vuoutpeakr=1e-9;vumaxoutpeakl=1e-9;vumaxoutpeakr=1e-9; + vuclipped=0; +}; + + + +void Master::applyparameters(){ + for (int npart=0;npartapplyparameters(); + }; +}; + +void Master::add2XML(XMLwrapper *xml){ + xml->addpar("volume",Pvolume); + xml->addpar("key_shift",Pkeyshift); + xml->addparbool("nrpn_receive",ctl.NRPN.receive); + + xml->beginbranch("MICROTONAL"); + microtonal.add2XML(xml); + xml->endbranch(); + + for (int npart=0;npartbeginbranch("PART",npart); + part[npart]->add2XML(xml); + xml->endbranch(); + }; + + xml->beginbranch("SYSTEM_EFFECTS"); + for (int nefx=0;nefxbeginbranch("SYSTEM_EFFECT",nefx); + xml->beginbranch("EFFECT"); + sysefx[nefx]->add2XML(xml); + xml->endbranch(); + + for (int pefx=0;pefxbeginbranch("VOLUME",pefx); + xml->addpar("vol",Psysefxvol[nefx][pefx]); + xml->endbranch(); + }; + + for (int tonefx=nefx+1;tonefxbeginbranch("SENDTO",tonefx); + xml->addpar("send_vol",Psysefxsend[nefx][tonefx]); + xml->endbranch(); + }; + + + xml->endbranch(); + }; + xml->endbranch(); + + xml->beginbranch("INSERTION_EFFECTS"); + for (int nefx=0;nefxbeginbranch("INSERTION_EFFECT",nefx); + xml->addpar("part",Pinsparts[nefx]); + + xml->beginbranch("EFFECT"); + insefx[nefx]->add2XML(xml); + xml->endbranch(); + xml->endbranch(); + }; + + xml->endbranch(); + +}; + + +int Master::getalldata(char **data){ + XMLwrapper *xml=new XMLwrapper(); + + xml->beginbranch("MASTER"); + + pthread_mutex_lock(&mutex); + add2XML(xml); + pthread_mutex_unlock(&mutex); + + xml->endbranch(); + + *data=xml->getXMLdata(); + delete (xml); + return(strlen(*data)+1); +}; + +void Master::putalldata(char *data,int size){ + XMLwrapper *xml=new XMLwrapper(); + if (!xml->putXMLdata(data)) { + delete(xml); + return; + }; + + if (xml->enterbranch("MASTER")==0) return; + + pthread_mutex_lock(&mutex); + getfromXML(xml); + pthread_mutex_unlock(&mutex); + + xml->exitbranch(); + + delete(xml); +}; + +int Master::saveXML(char *filename){ + XMLwrapper *xml=new XMLwrapper(); + + xml->beginbranch("MASTER"); + add2XML(xml); + xml->endbranch(); + + int result=xml->saveXMLfile(filename); + delete (xml); + return(result); +}; + + + +int Master::loadXML(char *filename){ + XMLwrapper *xml=new XMLwrapper(); + if (xml->loadXMLfile(filename)<0) { + delete(xml); + return(-1); + }; + + if (xml->enterbranch("MASTER")==0) return(-10); + getfromXML(xml); + xml->exitbranch(); + + delete(xml); + return(0); +}; + +void Master::getfromXML(XMLwrapper *xml){ + setPvolume(xml->getpar127("volume",Pvolume)); + setPkeyshift(xml->getpar127("key_shift",Pkeyshift)); + ctl.NRPN.receive=xml->getparbool("nrpn_receive",ctl.NRPN.receive); + + + part[0]->Penabled=0; + for (int npart=0;npartenterbranch("PART",npart)==0) continue; + part[npart]->getfromXML(xml); + xml->exitbranch(); + }; + + if (xml->enterbranch("MICROTONAL")){ + microtonal.getfromXML(xml); + xml->exitbranch(); + }; + + sysefx[0]->changeeffect(0); + if (xml->enterbranch("SYSTEM_EFFECTS")){ + for (int nefx=0;nefxenterbranch("SYSTEM_EFFECT",nefx)==0) continue; + if (xml->enterbranch("EFFECT")){ + sysefx[nefx]->getfromXML(xml); + xml->exitbranch(); + }; + + for (int partefx=0;partefxenterbranch("VOLUME",partefx)==0) continue; + setPsysefxvol(partefx,nefx,xml->getpar127("vol",Psysefxvol[partefx][nefx])); + xml->exitbranch(); + }; + + for (int tonefx=nefx+1;tonefxenterbranch("SENDTO",tonefx)==0) continue; + setPsysefxsend(nefx,tonefx,xml->getpar127("send_vol",Psysefxsend[nefx][tonefx])); + xml->exitbranch(); + }; + xml->exitbranch(); + }; + xml->exitbranch(); + }; + + + if (xml->enterbranch("INSERTION_EFFECTS")){ + for (int nefx=0;nefxenterbranch("INSERTION_EFFECT",nefx)==0) continue; + Pinsparts[nefx]=xml->getpar("part",Pinsparts[nefx],-2,NUM_MIDI_PARTS); + if (xml->enterbranch("EFFECT")){ + insefx[nefx]->getfromXML(xml); + xml->exitbranch(); + }; + xml->exitbranch(); + + }; + + xml->exitbranch(); + }; + + +}; + + + + diff --git a/plugins/zynaddsubfx/src/Misc/Master.h b/plugins/zynaddsubfx/src/Misc/Master.h new file mode 100644 index 000000000..527670e36 --- /dev/null +++ b/plugins/zynaddsubfx/src/Misc/Master.h @@ -0,0 +1,165 @@ +/* + ZynAddSubFX - a software synthesizer + + Master.h - It sends Midi Messages to Parts, receives samples from parts, + process them with system/insertion effects and mix them + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef MASTER_H +#define MASTER_H + +#include "../globals.h" +#include "../Effects/EffectMgr.h" +#include "Part.h" +#include "../Output/Recorder.h" +#include "Microtonal.h" + +#include "Bank.h" +#include "Dump.h" +#include "../Seq/Sequencer.h" +#include "XMLwrapper.h" + +extern Dump dump; +class Master{ + public: + Master(); + ~Master(); + + //saves all settings to a XML file + //returns 0 for ok or <0 if there is an error + int saveXML(char *filename); + + //this adds the parameters to the XML data + void add2XML(XMLwrapper *xml); + + void defaults(); + + + //loads all settings from a XML file + //returns 0 for ok or -1 if there is an error + int loadXML(char *filename); + void applyparameters(); + + void getfromXML(XMLwrapper *xml); + + //get all data to a newly allocated array (used for VST) + //returns the datasize + int getalldata(char **data); + //put all data from the *data array to zynaddsubfx parameters (used for VST) + void putalldata(char *data,int size); + + + + //Midi IN + void NoteOn(unsigned char chan,unsigned char note,unsigned char velocity); + void NoteOff(unsigned char chan,unsigned char note); + void SetController(unsigned char chan,unsigned int type,int par); + //void NRPN... + + + void ShutUp(); + int shutup; + + //Audio Output + void AudioOut(REALTYPE *outl,REALTYPE *outr); + //Audio Output (for callback mode). This allows the program to be controled by an external program + void GetAudioOutSamples(int nsamples,int samplerate,REALTYPE *outl,REALTYPE *outr); + + + void partonoff(int npart,int what); + + //parts + Part *part[NUM_MIDI_PARTS]; + + //parameters + unsigned char Pvolume; + unsigned char Pkeyshift; + unsigned char Psysefxvol[NUM_SYS_EFX][NUM_MIDI_PARTS]; + unsigned char Psysefxsend[NUM_SYS_EFX][NUM_SYS_EFX]; + + //parameters control + void setPvolume(char Pvolume_); + void setPkeyshift(char Pkeyshift_); + void setPsysefxvol(int Ppart,int Pefx,char Pvol); + void setPsysefxsend(int Pefxfrom,int Pefxto,char Pvol); + + //effects + EffectMgr *sysefx[NUM_SYS_EFX];//system + EffectMgr *insefx[NUM_INS_EFX];//insertion +// void swapcopyeffects(int what,int type,int neff1,int neff2); + + //HDD recorder + Recorder HDDRecorder; + + //part that's apply the insertion effect; -1 to disable + short int Pinsparts[NUM_INS_EFX]; + + //peaks for VU-meter + void vuresetpeaks(); + REALTYPE vuoutpeakl,vuoutpeakr,vumaxoutpeakl,vumaxoutpeakr,vurmspeakl,vurmspeakr; + int vuclipped; + + //peaks for part VU-meters + REALTYPE vuoutpeakpart[NUM_MIDI_PARTS]; + unsigned char fakepeakpart[NUM_MIDI_PARTS];//this is used to compute the "peak" when the part is disabled + + Controller ctl; + int swaplr;//1 if L and R are swapped + + //Sequencer + Sequencer seq; + + //other objects + Microtonal microtonal; + Bank bank; + + FFTwrapper *fft; + pthread_mutex_t mutex; + + private: + REALTYPE volume; + REALTYPE sysefxvol[NUM_SYS_EFX][NUM_MIDI_PARTS]; + REALTYPE sysefxsend[NUM_SYS_EFX][NUM_SYS_EFX]; + + //Temporary mixing samples for part samples which is sent to system effect + REALTYPE *tmpmixl; + REALTYPE *tmpmixr; + + + int keyshift; + + //Audio Output samples (if it used GetAudioOutSamples - eg. for Jack output; elsewhere is unused) + REALTYPE *audiooutl; + REALTYPE *audiooutr; + + int ksoundbuffersample;//this is used to know if there is need to call AudioOut by GetAudioOutSamples method + REALTYPE ksoundbuffersamplelow;//this is used for resampling (eg. if Jack samplerate!= SAMPLE_RATE) + REALTYPE oldsamplel,oldsampler;//this is used for resampling + + //Theese are called by the NoteOn, NoteOff,SetController (which are from external sources like MIDI, Virtual Keyboard) + //and are called by internal parts of the program (like sequencer) + void noteon(unsigned char chan,unsigned char note,unsigned char velocity); + void noteoff(unsigned char chan,unsigned char note); + void setcontroller(unsigned char chan,unsigned int type,int par); + +}; + + +#endif + diff --git a/plugins/zynaddsubfx/src/Misc/Microtonal.C b/plugins/zynaddsubfx/src/Misc/Microtonal.C new file mode 100644 index 000000000..14eab7439 --- /dev/null +++ b/plugins/zynaddsubfx/src/Misc/Microtonal.C @@ -0,0 +1,514 @@ +/* + ZynAddSubFX - a software synthesizer + + Microtonal.C - Tuning settings and microtonal capabilities + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include +#include +#include "Microtonal.h" + +#define MAX_LINE_SIZE 80 + +Microtonal::Microtonal(){ + Pname=new unsigned char[MICROTONAL_MAX_NAME_LEN]; + Pcomment=new unsigned char[MICROTONAL_MAX_NAME_LEN]; + defaults(); +}; + +void Microtonal::defaults(){ + Pinvertupdown=0; + Pinvertupdowncenter=60; + octavesize=12; + Penabled=0; + PAnote=69; + PAfreq=440.0; + Pscaleshift=64; + + Pfirstkey=0;Plastkey=127; + Pmiddlenote=60;Pmapsize=12; + Pmappingenabled=0; + + for (int i=0;i<128;i++) Pmapping[i]=i; + + for (int i=0;iPlastkey)) return (-1.0); + //Compute how many mapped keys are from middle note to reference note + //and find out the proportion between the freq. of middle note and "A" note + int tmp=PAnote-Pmiddlenote,minus=0; + if (tmp<0) { tmp=-tmp; minus=1; }; + int deltanote=0; + for (int i=0;i=0) deltanote++; + REALTYPE rap_anote_middlenote=(deltanote==0) ? (1.0) : (octave[(deltanote-1)%octavesize].tuning); + if (deltanote!=0) rap_anote_middlenote*=pow(octave[octavesize-1].tuning,(deltanote-1)/octavesize); + if (minus!=0) rap_anote_middlenote=1.0/rap_anote_middlenote; + + //Convert from note (midi) to degree (note from the tunning) + int degoct=(note-(int)Pmiddlenote+(int) Pmapsize*200)/(int)Pmapsize-200; + int degkey=(note-Pmiddlenote+(int)Pmapsize*100)%Pmapsize; + degkey=Pmapping[degkey]; + if (degkey<0) return(-1.0);//this key is not mapped + + //invert the keyboard upside-down if it is asked for + //TODO: do the right way by using Pinvertupdowncenter + if (Pinvertupdown!=0){ + degkey=octavesize-degkey-1; + degoct=-degoct; + }; + //compute the frequency of the note + degkey=degkey+scaleshift; + degoct+=degkey/octavesize; + degkey%=octavesize; + + REALTYPE freq=(degkey==0) ? (1.0):octave[degkey-1].tuning; + freq*=pow(octave[octavesize-1].tuning,degoct); + freq*=PAfreq/rap_anote_middlenote; + freq*=globalfinedetunerap; + if (scaleshift!=0) freq/=octave[scaleshift-1].tuning; + return(freq*rap_keyshift); + } else {//if the mapping is disabled + int nt=note-PAnote+scaleshift; + int ntkey=(nt+(int)octavesize*100)%octavesize; + int ntoct=(nt-ntkey)/octavesize; + + REALTYPE oct=octave[octavesize-1].tuning; + REALTYPE freq=octave[(ntkey+octavesize-1)%octavesize].tuning*pow(oct,ntoct)*PAfreq; + if (ntkey==0) freq/=oct; + if (scaleshift!=0) freq/=octave[scaleshift-1].tuning; +// fprintf(stderr,"note=%d freq=%.3f cents=%d\n",note,freq,(int)floor(log(freq/PAfreq)/log(2.0)*1200.0+0.5)); + freq*=globalfinedetunerap; + return(freq*rap_keyshift); + }; +}; + + +/* + * Convert a line to tunings; returns -1 if it ok + */ +int Microtonal::linetotunings(unsigned int nline,const char *line){ + int x1=-1,x2=-1,type=-1; + REALTYPE x=-1.0,tmp,tuning=1.0; + if (strstr(line,"/")==NULL){ + if (strstr(line,".")==NULL){// M case (M=M/1) + sscanf(line,"%d",&x1); + x2=1; + type=2;//division + } else {// float number case + sscanf(line,"%f",&x); + if (x<0.000001) return(1); + type=1;//float type(cents) + }; + } else {// M/N case + sscanf(line,"%d/%d",&x1,&x2); + if ((x1<0)||(x2<0)) return(1); + if (x2==0) x2=1; + type=2;//division + }; + + if (x1<=0) x1=1;//not allow zero frequency sounds (consider 0 as 1) + + //convert to float if the number are too big + if ((type==2)&&((x1>(128*128*128-1))||(x2>(128*128*128-1)))){ + type=1; + x=((REALTYPE) x1)/x2; + }; + switch (type){ + case 1: x1=(int) floor(x); + tmp=fmod(x,1.0); + x2=(int) (floor (tmp*1e6)); + tuning=pow(2.0,x/1200.0); + break; + case 2: x=((REALTYPE)x1)/x2; + tuning=x; + break; + }; + + tmpoctave[nline].tuning=tuning; + tmpoctave[nline].type=type; + tmpoctave[nline].x1=x1; + tmpoctave[nline].x2=x2; + + return(-1);//ok +}; + +/* + * Convert the text to tunnings + */ +int Microtonal::texttotunings(const char *text){ + unsigned int i,k=0,nl=0; + char *lin; + lin=new char[MAX_LINE_SIZE+1]; + while (kMAX_OCTAVE_SIZE) nl=MAX_OCTAVE_SIZE; + if (nl==0) return(-2);//the input is empty + octavesize=nl; + for (i=0;i127) break; + }; + delete [] lin; + + if (tx==0) tx=1; + Pmapsize=tx; +}; + +/* + * Convert tunning to text line + */ +void Microtonal::tuningtoline(int n,char *line,int maxn){ + if ((n>octavesize) || (n>MAX_OCTAVE_SIZE)) { + line[0]='\0'; + return; + }; + if (octave[n].type==1) snprintf(line,maxn,"%d.%d",octave[n].x1,octave[n].x2); + if (octave[n].type==2) snprintf(line,maxn,"%d/%d",octave[n].x1,octave[n].x2); +}; + + +int Microtonal::loadline(FILE *file,char *line){ + do { + if (fgets(line,500,file)==0) return(1); + } while (line[0]=='!'); + return(0); +}; +/* + * Loads the tunnings from a scl file + */ +int Microtonal::loadscl(const char *filename){ + FILE *file=fopen(filename, "r"); + char tmp[500]; + fseek(file,0,SEEK_SET); + //loads the short description + if (loadline(file,&tmp[0])!=0) return(2); + for (int i=0;i<500;i++) if (tmp[i]<32) tmp[i]=0; + snprintf((char *) Pname,MICROTONAL_MAX_NAME_LEN,"%s",tmp); + snprintf((char *) Pcomment,MICROTONAL_MAX_NAME_LEN,"%s",tmp); + //loads the number of the notes + if (loadline(file,&tmp[0])!=0) return(2); + int nnotes=MAX_OCTAVE_SIZE; + sscanf(&tmp[0],"%d",&nnotes); + if (nnotes>MAX_OCTAVE_SIZE) return (2); + //load the tunnings + for (int nline=0;nline127) x=127;//just in case... + Pmapsize=x; + //loads first MIDI note to retune + if (loadline(file,&tmp[0])!=0) return(2); + if (sscanf(&tmp[0],"%d",&x)==0) return(2); + if (x<1) x=0;if (x>127) x=127;//just in case... + Pfirstkey=x; + //loads last MIDI note to retune + if (loadline(file,&tmp[0])!=0) return(2); + if (sscanf(&tmp[0],"%d",&x)==0) return(2); + if (x<1) x=0;if (x>127) x=127;//just in case... + Plastkey=x; + //loads last the middle note where scale fro scale degree=0 + if (loadline(file,&tmp[0])!=0) return(2); + if (sscanf(&tmp[0],"%d",&x)==0) return(2); + if (x<1) x=0;if (x>127) x=127;//just in case... + Pmiddlenote=x; + //loads the reference note + if (loadline(file,&tmp[0])!=0) return(2); + if (sscanf(&tmp[0],"%d",&x)==0) return(2); + if (x<1) x=0;if (x>127) x=127;//just in case... + PAnote=x; + //loads the reference freq. + if (loadline(file,&tmp[0])!=0) return(2); + REALTYPE tmpPAfreq=440.0; + if (sscanf(&tmp[0],"%f",&tmpPAfreq)==0) return(2); + PAfreq=tmpPAfreq; + + //the scale degree(which is the octave) is not loaded, it is obtained by the tunnings with getoctavesize() method + if (loadline(file,&tmp[0])!=0) return(2); + + //load the mappings + if (Pmapsize!=0){ + for (int nline=0;nlineaddparstr("name",(char *) Pname); + xml->addparstr("comment",(char *) Pcomment); + + xml->addparbool("invert_up_down",Pinvertupdown); + xml->addparbool("invert_up_down_center",Pinvertupdowncenter); + + xml->addparbool("enabled",Penabled); + xml->addpar("global_fine_detune",Pglobalfinedetune); + + xml->addpar("a_note",PAnote); + xml->addparreal("a_freq",PAfreq); + + if ((Penabled==0)&&(xml->minimal)) return; + + xml->beginbranch("SCALE"); + xml->addpar("scale_shift",Pscaleshift); + xml->addpar("first_key",Pfirstkey); + xml->addpar("last_key",Plastkey); + xml->addpar("middle_note",Pmiddlenote); + + xml->beginbranch("OCTAVE"); + xml->addpar("octave_size",octavesize); + for (int i=0;ibeginbranch("DEGREE",i); + if (octave[i].type==1){ + xml->addparreal("cents",octave[i].tuning); + }; + if (octave[i].type==2){ + xml->addpar("numerator",octave[i].x1); + xml->addpar("denominator",octave[i].x2); + }; + xml->endbranch(); + }; + xml->endbranch(); + + xml->beginbranch("KEYBOARD_MAPPING"); + xml->addpar("map_size",Pmapsize); + xml->addpar("mapping_enabled",Pmappingenabled); + for (int i=0;ibeginbranch("KEYMAP",i); + xml->addpar("degree",Pmapping[i]); + xml->endbranch(); + }; + xml->endbranch(); + xml->endbranch(); +}; + +void Microtonal::getfromXML(XMLwrapper *xml){ + xml->getparstr("name",(char *) Pname,MICROTONAL_MAX_NAME_LEN); + xml->getparstr("comment",(char *) Pcomment,MICROTONAL_MAX_NAME_LEN); + + Pinvertupdown=xml->getparbool("invert_up_down",Pinvertupdown); + Pinvertupdowncenter=xml->getparbool("invert_up_down_center",Pinvertupdowncenter); + + Penabled=xml->getparbool("enabled",Penabled); + Pglobalfinedetune=xml->getpar127("global_fine_detune",Pglobalfinedetune); + + PAnote=xml->getpar127("a_note",PAnote); + PAfreq=xml->getparreal("a_freq",PAfreq,1.0,10000.0); + + if (xml->enterbranch("SCALE")){ + Pscaleshift=xml->getpar127("scale_shift",Pscaleshift); + Pfirstkey=xml->getpar127("first_key",Pfirstkey); + Plastkey=xml->getpar127("last_key",Plastkey); + Pmiddlenote=xml->getpar127("middle_note",Pmiddlenote); + + if (xml->enterbranch("OCTAVE")){ + octavesize=xml->getpar127("octave_size",octavesize); + for (int i=0;ienterbranch("DEGREE",i)==0) continue; + octave[i].x2=0; + octave[i].tuning=xml->getparreal("cents",octave[i].tuning); + octave[i].x1=xml->getpar127("numerator",octave[i].x1); + octave[i].x2=xml->getpar127("denominator",octave[i].x2); + + if (octave[i].x2!=0) octave[i].type=2; + else octave[i].type=1; + + xml->exitbranch(); + }; + xml->exitbranch(); + }; + + if (xml->enterbranch("KEYBOARD_MAPPING")){ + Pmapsize=xml->getpar127("map_size",Pmapsize); + Pmappingenabled=xml->getpar127("mapping_enabled",Pmappingenabled); + for (int i=0;ienterbranch("KEYMAP",i)==0) continue; + Pmapping[i]=xml->getpar127("degree",Pmapping[i]); + xml->exitbranch(); + }; + xml->exitbranch(); + }; + xml->exitbranch(); + }; +}; + + +int Microtonal::saveXML(char *filename){ + XMLwrapper *xml=new XMLwrapper(); + + xml->beginbranch("MICROTONAL"); + add2XML(xml); + xml->endbranch(); + + int result=xml->saveXMLfile(filename); + delete (xml); + return(result); +}; + +int Microtonal::loadXML(char *filename){ + XMLwrapper *xml=new XMLwrapper(); + if (xml->loadXMLfile(filename)<0) { + delete(xml); + return(-1); + }; + + if (xml->enterbranch("MICROTONAL")==0) return(-10); + getfromXML(xml); + xml->exitbranch(); + + delete(xml); + return(0); +}; + + diff --git a/plugins/zynaddsubfx/src/Misc/Microtonal.h b/plugins/zynaddsubfx/src/Misc/Microtonal.h new file mode 100644 index 000000000..8aff5fe26 --- /dev/null +++ b/plugins/zynaddsubfx/src/Misc/Microtonal.h @@ -0,0 +1,111 @@ +/* + ZynAddSubFX - a software synthesizer + + Microtonal.h - Tuning settings and microtonal capabilities + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef MICROTONAL_H +#define MICROTONAL_H + +#include "../globals.h" +#include "XMLwrapper.h" + +#define MAX_OCTAVE_SIZE 128 +#define MICROTONAL_MAX_NAME_LEN 120 + +#include + +class Microtonal{ + public: + Microtonal(); + ~Microtonal(); + void defaults(); + REALTYPE getnotefreq(int note,int keyshift); + + + //Parameters + //if the keys are inversed (the pitch is lower to keys from the right direction) + unsigned char Pinvertupdown; + + //the central key of the inversion + unsigned char Pinvertupdowncenter; + + //0 for 12 key temperate scale, 1 for microtonal + unsigned char Penabled; + + //the note of "A" key + unsigned char PAnote; + + //the frequency of the "A" note + REALTYPE PAfreq; + + //if the scale is "tuned" to a note, you can tune to other note + unsigned char Pscaleshift; + + //first and last key (to retune) + unsigned char Pfirstkey; + unsigned char Plastkey; + + //The middle note where scale degree 0 is mapped to + unsigned char Pmiddlenote; + + //Map size + unsigned char Pmapsize; + + //Mapping ON/OFF + unsigned char Pmappingenabled; + //Mapping (keys) + short int Pmapping[128]; + + unsigned char Pglobalfinedetune; + + // Functions + unsigned char getoctavesize(); + void tuningtoline(int n,char *line,int maxn); + int loadscl(const char *filename);//load the tunnings from a .scl file + int loadkbm(const char *filename);//load the mapping from .kbm file + int texttotunings(const char *text); + void texttomapping(const char *text); + unsigned char *Pname; + unsigned char *Pcomment; + + void add2XML(XMLwrapper *xml); + void getfromXML(XMLwrapper *xml); + int saveXML(char *filename); + int loadXML(char *filename); + + private: + int linetotunings(unsigned int nline,const char *line); + int loadline(FILE *file,char *line);//loads a line from the text file, while ignoring the lines beggining with "!" + unsigned char octavesize; + struct { + unsigned char type;//1 for cents or 2 for division + + // the real tuning (eg. +1.05946 for one halftone) + // or 2.0 for one octave + REALTYPE tuning; + + //the real tunning is x1/x2 + unsigned int x1,x2; + + } octave[MAX_OCTAVE_SIZE],tmpoctave[MAX_OCTAVE_SIZE]; + +}; + +#endif diff --git a/plugins/zynaddsubfx/src/Misc/Part.C b/plugins/zynaddsubfx/src/Misc/Part.C new file mode 100644 index 000000000..d54cf6f61 --- /dev/null +++ b/plugins/zynaddsubfx/src/Misc/Part.C @@ -0,0 +1,1077 @@ +/* + ZynAddSubFX - a software synthesizer + + Part.C - Part implementation + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include "Part.h" +#include "Microtonal.h" +#include +#include +#include + +Part::Part(Microtonal *microtonal_,FFTwrapper *fft_, pthread_mutex_t *mutex_){ + microtonal=microtonal_; + fft=fft_; + mutex=mutex_; + partoutl=new REALTYPE [SOUND_BUFFER_SIZE]; + partoutr=new REALTYPE [SOUND_BUFFER_SIZE]; + tmpoutl=new REALTYPE [SOUND_BUFFER_SIZE]; + tmpoutr=new REALTYPE [SOUND_BUFFER_SIZE]; + + for (int n=0;ndefaults(); + kit[0].subpars->defaults(); + kit[0].padpars->defaults(); + + for (int nefx=0;nefxdefaults(); + Pefxroute[nefx]=0;//route to next effect + }; + +}; + + + +/* + * Cleanup the part + */ +void Part::cleanup(){ + for (int k=0;kcleanup(); + for (int n=0;nPmaxkey)) return; + + // MonoMem stuff: + if (Ppolymode==0){ // If Poly is off + monomemnotes.push_back(note); // Add note to the list. + monomem[note].velocity=velocity; // Store this note's velocity. + monomem[note].mkeyshift=masterkeyshift; /* Store masterkeyshift too, + I'm not sure why though... */ + if ((partnote[lastpos].status!=KEY_PLAYING) + && (partnote[lastpos].status!=KEY_RELASED_AND_SUSTAINED)){ + ismonofirstnote=true; // No other keys are held or sustained. + } + } else { + // Poly mode is On so just make sure the list is empty. + if (not monomemnotes.empty()) monomemnotes.clear(); + } + + lastnote=note; + + pos=-1; + for (i=0;i POLIPHONY) - (Part.C::NoteOn(..))\n"); + } else { + + //start the note + partnote[pos].status=KEY_PLAYING; + partnote[pos].note=note; + if (legatomodevalid){ + partnote[posb].status=KEY_PLAYING; + partnote[posb].note=note; + } + + //this computes the velocity sensing of the part + REALTYPE vel=VelF(velocity/127.0,Pvelsns); + + //compute the velocity offset + vel+=(Pveloffs-64.0)/64.0; + if (vel<0.0) vel=0.0; else if (vel>1.0) vel=1.0; + + //compute the keyshift + int partkeyshift=(int)Pkeyshift-64; + int keyshift=masterkeyshift+partkeyshift; + + //initialise note frequency + REALTYPE notebasefreq; + if (Pdrummode==0){ + notebasefreq=microtonal->getnotefreq(note,keyshift); + if (notebasefreq<0.0) return;//the key is no mapped + } else { + notebasefreq=440.0*pow(2.0,(note-69.0)/12.0); + }; + + //Portamento + if (oldfreq<1.0) oldfreq=notebasefreq;//this is only the first note is played + + // For Mono/Legato: Force Portamento Off on first + // notes. That means it is required that the previous note is + // still held down or sustained for the Portamento to activate + // (that's like Legato). + int portamento=0; + if ((Ppolymode!=0) || (not ismonofirstnote)){ + // I added a third argument to the + // ctl.initportamento(...) function to be able + // to tell it if we're doing a legato note. + portamento=ctl.initportamento(oldfreq,notebasefreq,doinglegato); + } + + if (portamento!=0) ctl.portamento.noteusing=pos; + oldfreq=notebasefreq; + + lastpos=pos; // Keep a trace of used pos. + + if (doinglegato){ + // Do Legato note + if (Pkitmode==0){ // "normal mode" legato note + if ((kit[0].Padenabled!=0) + && (partnote[pos].kititem[0].adnote!=NULL) + && (partnote[posb].kititem[0].adnote!=NULL)){ + partnote[pos].kititem[0].adnote->ADlegatonote(notebasefreq, vel, portamento, note, true);//'true' is to tell it it's being called from here. + partnote[posb].kititem[0].adnote->ADlegatonote(notebasefreq, vel, portamento, note, true); + } + + if ((kit[0].Psubenabled!=0) + && (partnote[pos].kititem[0].subnote!=NULL) + && (partnote[posb].kititem[0].subnote!=NULL)){ + partnote[pos].kititem[0].subnote->SUBlegatonote(notebasefreq, vel, portamento, note, true); + partnote[posb].kititem[0].subnote->SUBlegatonote(notebasefreq, vel, portamento, note, true); + } + + if ((kit[0].Ppadenabled!=0) + && (partnote[pos].kititem[0].padnote!=NULL) + && (partnote[posb].kititem[0].padnote!=NULL)){ + partnote[pos].kititem[0].padnote->PADlegatonote(notebasefreq, vel, portamento, note, true); + partnote[posb].kititem[0].padnote->PADlegatonote(notebasefreq, vel, portamento, note, true); + } + + } else { // "kit mode" legato note + int ci=0; + for (int item=0;itemkit[item].Pmaxkey)) continue; + + if ((lastnotecopykit[item].Pmaxkey)) + continue; // We will not perform legato across 2 key regions. + + partnote[pos].kititem[ci].sendtoparteffect=( kit[item].PsendtoparteffectADlegatonote(notebasefreq,vel,portamento,note,true); + partnote[posb].kititem[ci].adnote->ADlegatonote(notebasefreq,vel,portamento,note,true); + } + if ((kit[item].Psubenabled!=0) && (kit[item].subpars!=NULL) + && (partnote[pos].kititem[ci].subnote!=NULL) + && (partnote[posb].kititem[ci].subnote!=NULL)){ + partnote[pos].kititem[ci].subnote->SUBlegatonote(notebasefreq,vel,portamento,note,true); + partnote[posb].kititem[ci].subnote->SUBlegatonote(notebasefreq,vel,portamento,note,true); + } + if ((kit[item].Ppadenabled!=0) && (kit[item].padpars!=NULL) + && (partnote[pos].kititem[ci].padnote!=NULL) + && (partnote[posb].kititem[ci].padnote!=NULL)){ + partnote[pos].kititem[ci].padnote->PADlegatonote(notebasefreq,vel,portamento,note,true); + partnote[posb].kititem[ci].padnote->PADlegatonote(notebasefreq,vel,portamento,note,true); + } + + if ((kit[item].adpars!=NULL)||(kit[item].subpars!=NULL)||(kit[item].padpars!=NULL)) { + ci++; + if ( ((kit[item].Padenabled!=0)||(kit[item].Psubenabled!=0)||(kit[item].Ppadenabled!=0)) && (Pkitmode==2) ) break; + } + } + if (ci==0){ + // No legato were performed at all, so pretend nothing happened: + monomemnotes.pop_back(); // Remove last note from the list. + lastnote=lastnotecopy; // Set lastnote back to previous value. + } + } + return; // Ok, Legato note done, return. + } + + partnote[pos].itemsplaying=0; + if (legatomodevalid) partnote[posb].itemsplaying=0; + + if (Pkitmode==0){//init the notes for the "normal mode" + partnote[pos].kititem[0].sendtoparteffect=0; + if (kit[0].Padenabled!=0) partnote[pos].kititem[0].adnote=new ADnote(kit[0].adpars,&ctl,notebasefreq,vel,portamento,note,false); + if (kit[0].Psubenabled!=0) partnote[pos].kititem[0].subnote=new SUBnote(kit[0].subpars,&ctl,notebasefreq,vel,portamento,note,false); + if (kit[0].Ppadenabled!=0) partnote[pos].kititem[0].padnote=new PADnote(kit[0].padpars,&ctl,notebasefreq,vel,portamento,note,false); + if ((kit[0].Padenabled!=0)||(kit[0].Psubenabled!=0)||(kit[0].Ppadenabled!=0)) partnote[pos].itemsplaying++; + + // Spawn another note (but silent) if legatomodevalid==true + if (legatomodevalid){ + partnote[posb].kititem[0].sendtoparteffect=0; + if (kit[0].Padenabled!=0) partnote[posb].kititem[0].adnote=new ADnote(kit[0].adpars,&ctl,notebasefreq,vel,portamento,note,true);//true for silent. + if (kit[0].Psubenabled!=0) partnote[posb].kititem[0].subnote=new SUBnote(kit[0].subpars,&ctl,notebasefreq,vel,portamento,note,true); + if (kit[0].Ppadenabled!=0) partnote[posb].kititem[0].padnote=new PADnote(kit[0].padpars,&ctl,notebasefreq,vel,portamento,note,true); + if ((kit[0].Padenabled!=0)||(kit[0].Psubenabled!=0)||(kit[0].Ppadenabled!=0)) partnote[posb].itemsplaying++; + } + + } else {//init the notes for the "kit mode" + for (int item=0;itemkit[item].Pmaxkey)) continue; + + int ci=partnote[pos].itemsplaying;//ci=current item + + partnote[pos].kititem[ci].sendtoparteffect=( kit[item].Psendtoparteffect=0;i--){ //first note in, is first out if there are same note multiple times + if ((partnote[i].status==KEY_PLAYING)&&(partnote[i].note==note)) { + if (ctl.sustain.sustain==0){ //the sustain pedal is not pushed + if ((Ppolymode==0) && (not monomemnotes.empty())){ + MonoMemRenote(); // To play most recent still held note. + } else { + RelaseNotePos(i); + /// break; + } + } else {//the sustain pedal is pushed + partnote[i].status=KEY_RELASED_AND_SUSTAINED; + } + } + } +}; + +/* + * Controllers + */ +void Part::SetController(unsigned int type,int par){ + switch (type){ + case C_pitchwheel:ctl.setpitchwheel(par); + break; + case C_expression:ctl.setexpression(par); + setPvolume(Pvolume);//update the volume + break; + case C_portamento:ctl.setportamento(par); + break; + case C_panning:ctl.setpanning(par); + setPpanning(Ppanning);//update the panning + break; + case C_filtercutoff:ctl.setfiltercutoff(par); + break; + case C_filterq:ctl.setfilterq(par); + break; + case C_bandwidth:ctl.setbandwidth(par); + break; + case C_modwheel:ctl.setmodwheel(par); + break; + case C_fmamp:ctl.setfmamp(par); + break; + case C_volume:ctl.setvolume(par); + if (ctl.volume.receive!=0) volume=ctl.volume.volume; + else setPvolume(Pvolume); + break; + case C_sustain:ctl.setsustain(par); + if (ctl.sustain.sustain==0) RelaseSustainedKeys(); + break; + case C_allsoundsoff:AllNotesOff();//Panic + break; + case C_resetallcontrollers: + ctl.resetall(); + RelaseSustainedKeys(); + if (ctl.volume.receive!=0) volume=ctl.volume.volume; + else setPvolume(Pvolume); + setPvolume(Pvolume);//update the volume + setPpanning(Ppanning);//update the panning + + for (int item=0;itemGlobalPar.Reson-> + sendcontroller(C_resonance_center,1.0); + + kit[item].adpars->GlobalPar.Reson-> + sendcontroller(C_resonance_bandwidth,1.0); + }; + //more update to add here if I add controllers + break; + case C_allnotesoff:RelaseAllKeys(); + break; + case C_resonance_center: + ctl.setresonancecenter(par); + for (int item=0;itemGlobalPar.Reson-> + sendcontroller(C_resonance_center,ctl.resonancecenter.relcenter); + }; + break; + case C_resonance_bandwidth: + ctl.setresonancebw(par); + kit[0].adpars->GlobalPar.Reson-> + sendcontroller(C_resonance_bandwidth,ctl.resonancebandwidth.relbw); + break; + }; +}; +/* + * Relase the sustained keys + */ + +void Part::RelaseSustainedKeys(){ + // Let's call MonoMemRenote() on some conditions: + if ((Ppolymode==0) && (not monomemnotes.empty())) + if (monomemnotes.back()!=lastnote) // Sustain controller manipulation would cause repeated same note respawn without this check. + MonoMemRenote(); // To play most recent still held note. + + for (int i=0;irelasekey(); + + if (partnote[pos].kititem[j].subnote!=NULL) + if (partnote[pos].kititem[j].subnote!=NULL) + partnote[pos].kititem[j].subnote->relasekey(); + + if (partnote[pos].kititem[j].padnote!=NULL) + if (partnote[pos].kititem[j].padnote) + partnote[pos].kititem[j].padnote->relasekey(); + }; + partnote[pos].status=KEY_RELASED; +}; + + +/* + * Kill note at position + */ +void Part::KillNotePos(int pos){ + partnote[pos].status=KEY_OFF; + partnote[pos].note=-1; + partnote[pos].time=0; + partnote[pos].itemsplaying=0; + + for (int j=0;jPkeylimit=Pkeylimit; + int keylimit=Pkeylimit; + if (keylimit==0) keylimit=POLIPHONY-5; + + //release old keys if the number of notes>keylimit + if (Ppolymode!=0){ + int notecount=0; + for (int i=0;ikeylimit){//find out the oldest note + for (int i=0;imaxtime)){ + maxtime=partnote[i].time; + oldestnotepos=i; + }; + }; + }; + if (oldestnotepos!=-1) RelaseNotePos(oldestnotepos); + }; +}; + + +/* + * Prepare all notes to be turned off + */ +void Part::AllNotesOff(){ + killallnotes=1; +}; + + +/* + * Compute Part samples and store them in the partoutl[] and partoutr[] + */ +void Part::ComputePartSmps(){ + int i,k; + int noteplay;//0 if there is nothing activated + for (int nefx=0;nefxready!=0) adnote->noteout(&tmpoutl[0],&tmpoutr[0]); + else for (i=0;ifinished()!=0){ + delete (adnote); + partnote[k].kititem[item].adnote=NULL; + }; + for (i=0;iready!=0) subnote->noteout(&tmpoutl[0],&tmpoutr[0]); + else for (i=0;ifinished()!=0){ + delete (subnote); + partnote[k].kititem[item].subnote=NULL; + }; + }; + //get from the PADnote + if (padnote!=NULL) { + noteplay++; + if (padnote->ready!=0) padnote->noteout(&tmpoutl[0],&tmpoutr[0]); + else for (i=0;ifinished()!=0){ + delete (padnote); + partnote[k].kititem[item].padnote=NULL; + }; + for (i=0;iout(partfxinputl[nefx],partfxinputr[nefx]); + if (Pefxroute[nefx]==2){ + for (i=0;iefxoutl[i]; + partfxinputr[nefx+1][i]+=partefx[nefx]->efxoutr[i]; + }; + }; + }; + int routeto=((Pefxroute[nefx]==0) ? nefx+1 : NUM_PART_EFX); + for (i=0;icleanup(); + }; + }; + ctl.updateportamento(); +}; + +/* + * Parameter control + */ +void Part::setPvolume(char Pvolume_){ + Pvolume=Pvolume_; + volume=dB2rap((Pvolume-96.0)/96.0*40.0)*ctl.expression.relvolume; +}; + +void Part::setPpanning(char Ppanning_){ + Ppanning=Ppanning_; + panning=Ppanning/127.0+ctl.panning.pan; + if (panning<0.0) panning=0.0;else if (panning>1.0) panning=1.0; + +}; + +/* + * Enable or disable a kit item + */ +void Part::setkititemstatus(int kititem,int Penabled_){ + if ((kititem==0)&&(kititem>=NUM_KIT_ITEMS)) return;//nonexistent kit item and the first kit item is always enabled + kit[kititem].Penabled=Penabled_; + + bool resetallnotes=false; + if (Penabled_==0){ + if (kit[kititem].adpars!=NULL) delete (kit[kititem].adpars); + if (kit[kititem].subpars!=NULL) delete (kit[kititem].subpars); + if (kit[kititem].padpars!=NULL) { + delete (kit[kititem].padpars); + resetallnotes=true; + }; + kit[kititem].adpars=NULL;kit[kititem].subpars=NULL;kit[kititem].padpars=NULL; + kit[kititem].Pname[0]='\0'; + } else { + if (kit[kititem].adpars==NULL) kit[kititem].adpars=new ADnoteParameters(fft); + if (kit[kititem].subpars==NULL) kit[kititem].subpars=new SUBnoteParameters(); + if (kit[kititem].padpars==NULL) kit[kititem].padpars=new PADnoteParameters(fft,mutex); + }; + + if (resetallnotes) for (int k=0;kbeginbranch("INFO"); + xml->addparstr("name",(char *)Pname); + xml->addparstr("author",(char *)info.Pauthor); + xml->addparstr("comments",(char *)info.Pcomments); + xml->addpar("type",info.Ptype); + xml->endbranch(); + + + xml->beginbranch("INSTRUMENT_KIT"); + xml->addpar("kit_mode",Pkitmode); + xml->addparbool("drum_mode",Pdrummode); + + for (int i=0;ibeginbranch("INSTRUMENT_KIT_ITEM",i); + xml->addparbool("enabled",kit[i].Penabled); + if (kit[i].Penabled!=0) { + xml->addparstr("name",(char *)kit[i].Pname); + + xml->addparbool("muted",kit[i].Pmuted); + xml->addpar("min_key",kit[i].Pminkey); + xml->addpar("max_key",kit[i].Pmaxkey); + + xml->addpar("send_to_instrument_effect",kit[i].Psendtoparteffect); + + xml->addparbool("add_enabled",kit[i].Padenabled); + if ((kit[i].Padenabled!=0)&&(kit[i].adpars!=NULL)){ + xml->beginbranch("ADD_SYNTH_PARAMETERS"); + kit[i].adpars->add2XML(xml); + xml->endbranch(); + }; + + xml->addparbool("sub_enabled",kit[i].Psubenabled); + if ((kit[i].Psubenabled!=0)&&(kit[i].subpars!=NULL)){ + xml->beginbranch("SUB_SYNTH_PARAMETERS"); + kit[i].subpars->add2XML(xml); + xml->endbranch(); + }; + + xml->addparbool("pad_enabled",kit[i].Ppadenabled); + if ((kit[i].Ppadenabled!=0)&&(kit[i].padpars!=NULL)){ + xml->beginbranch("PAD_SYNTH_PARAMETERS"); + kit[i].padpars->add2XML(xml); + xml->endbranch(); + }; + + }; + xml->endbranch(); + }; + xml->endbranch(); + + xml->beginbranch("INSTRUMENT_EFFECTS"); + for (int nefx=0;nefxbeginbranch("INSTRUMENT_EFFECT",nefx); + xml->beginbranch("EFFECT"); + partefx[nefx]->add2XML(xml); + xml->endbranch(); + + xml->addpar("route",Pefxroute[nefx]); + partefx[nefx]->setdryonly(Pefxroute[nefx]==2); + xml->addparbool("bypass",Pefxbypass[nefx]); + xml->endbranch(); + }; + xml->endbranch(); +}; + + +void Part::add2XML(XMLwrapper *xml){ + //parameters + xml->addparbool("enabled",Penabled); + if ((Penabled==0)&&(xml->minimal)) return; + + xml->addpar("volume",Pvolume); + xml->addpar("panning",Ppanning); + + xml->addpar("min_key",Pminkey); + xml->addpar("max_key",Pmaxkey); + xml->addpar("key_shift",Pkeyshift); + xml->addpar("rcv_chn",Prcvchn); + + xml->addpar("velocity_sensing",Pvelsns); + xml->addpar("velocity_offset",Pveloffs); + + xml->addparbool("note_on",Pnoteon); + xml->addparbool("poly_mode",Ppolymode); + xml->addpar("legato_mode",Plegatomode); + xml->addpar("key_limit",Pkeylimit); + + xml->beginbranch("INSTRUMENT"); + add2XMLinstrument(xml); + xml->endbranch(); + + xml->beginbranch("CONTROLLER"); + ctl.add2XML(xml); + xml->endbranch(); +}; + +int Part::saveXML(char *filename){ + XMLwrapper *xml; + xml=new XMLwrapper(); + + xml->beginbranch("INSTRUMENT"); + add2XMLinstrument(xml); + xml->endbranch(); + + int result=xml->saveXMLfile(filename); + delete (xml); + return(result); +}; + +int Part::loadXMLinstrument(const char *filename){ + XMLwrapper *xml=new XMLwrapper(); + if (xml->loadXMLfile(filename)<0) { + delete(xml); + return(-1); + }; + + if (xml->enterbranch("INSTRUMENT")==0) return(-10); + getfromXMLinstrument(xml); + xml->exitbranch(); + + delete(xml); + return(0); +}; + + +void Part::applyparameters(){ + for (int n=0;napplyparameters(true); + }; +}; + +void Part::getfromXMLinstrument(XMLwrapper *xml){ + if (xml->enterbranch("INFO")){ + xml->getparstr("name",(char *)Pname,PART_MAX_NAME_LEN); + xml->getparstr("author",(char *)info.Pauthor,MAX_INFO_TEXT_SIZE); + xml->getparstr("comments",(char *)info.Pcomments,MAX_INFO_TEXT_SIZE); + info.Ptype=xml->getpar("type",info.Ptype,0,16); + + xml->exitbranch(); + }; + + if (xml->enterbranch("INSTRUMENT_KIT")){ + Pkitmode=xml->getpar127("kit_mode",Pkitmode); + Pdrummode=xml->getparbool("drum_mode",Pdrummode); + + setkititemstatus(0,0); + for (int i=0;ienterbranch("INSTRUMENT_KIT_ITEM",i)==0) continue; + setkititemstatus(i,xml->getparbool("enabled",kit[i].Penabled)); + if (kit[i].Penabled==0) { + xml->exitbranch(); + continue; + }; + + xml->getparstr("name",(char *)kit[i].Pname,PART_MAX_NAME_LEN); + + kit[i].Pmuted=xml->getparbool("muted",kit[i].Pmuted); + kit[i].Pminkey=xml->getpar127("min_key",kit[i].Pminkey); + kit[i].Pmaxkey=xml->getpar127("max_key",kit[i].Pmaxkey); + + kit[i].Psendtoparteffect=xml->getpar127("send_to_instrument_effect",kit[i].Psendtoparteffect); + + kit[i].Padenabled=xml->getparbool("add_enabled",kit[i].Padenabled); + if (xml->enterbranch("ADD_SYNTH_PARAMETERS")){ + kit[i].adpars->getfromXML(xml); + xml->exitbranch(); + }; + + kit[i].Psubenabled=xml->getparbool("sub_enabled",kit[i].Psubenabled); + if (xml->enterbranch("SUB_SYNTH_PARAMETERS")){ + kit[i].subpars->getfromXML(xml); + xml->exitbranch(); + }; + + kit[i].Ppadenabled=xml->getparbool("pad_enabled",kit[i].Ppadenabled); + if (xml->enterbranch("PAD_SYNTH_PARAMETERS")){ + kit[i].padpars->getfromXML(xml); + xml->exitbranch(); + }; + + xml->exitbranch(); + }; + + xml->exitbranch(); + }; + + + if (xml->enterbranch("INSTRUMENT_EFFECTS")){ + for (int nefx=0;nefxenterbranch("INSTRUMENT_EFFECT",nefx)==0) continue; + if (xml->enterbranch("EFFECT")){ + partefx[nefx]->getfromXML(xml); + xml->exitbranch(); + }; + + Pefxroute[nefx]=xml->getpar("route",Pefxroute[nefx],0,NUM_PART_EFX); + partefx[nefx]->setdryonly(Pefxroute[nefx]==2); + Pefxbypass[nefx]=xml->getparbool("bypass",Pefxbypass[nefx]); + xml->exitbranch(); + }; + xml->exitbranch(); + }; + +}; + +void Part::getfromXML(XMLwrapper *xml){ + Penabled=xml->getparbool("enabled",Penabled); + + setPvolume(xml->getpar127("volume",Pvolume)); + setPpanning(xml->getpar127("panning",Ppanning)); + + Pminkey=xml->getpar127("min_key",Pminkey); + Pmaxkey=xml->getpar127("max_key",Pmaxkey); + Pkeyshift=xml->getpar127("key_shift",Pkeyshift); + Prcvchn=xml->getpar127("rcv_chn",Prcvchn); + + Pvelsns=xml->getpar127("velocity_sensing",Pvelsns); + Pveloffs=xml->getpar127("velocity_offset",Pveloffs); + + Pnoteon=xml->getparbool("note_on",Pnoteon); + Ppolymode=xml->getparbool("poly_mode",Ppolymode); + Plegatomode=xml->getparbool("legato_mode",Plegatomode);//older versions + if (!Plegatomode) Plegatomode=xml->getpar127("legato_mode",Plegatomode); + Pkeylimit=xml->getpar127("key_limit",Pkeylimit); + + + if (xml->enterbranch("INSTRUMENT")){ + getfromXMLinstrument(xml); + xml->exitbranch(); + }; + + if (xml->enterbranch("CONTROLLER")){ + ctl.getfromXML(xml); + xml->exitbranch(); + }; + +}; + + + diff --git a/plugins/zynaddsubfx/src/Misc/Part.h b/plugins/zynaddsubfx/src/Misc/Part.h new file mode 100644 index 000000000..5cf6ea320 --- /dev/null +++ b/plugins/zynaddsubfx/src/Misc/Part.h @@ -0,0 +1,195 @@ +/* + ZynAddSubFX - a software synthesizer + + Part.h - Part implementation + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef PART_H +#define PART_H + +#define MAX_INFO_TEXT_SIZE 1000 + +#include "../globals.h" +#include "../Params/ADnoteParameters.h" +#include "../Params/SUBnoteParameters.h" +#include "../Params/PADnoteParameters.h" +#include "../Synth/ADnote.h" +#include "../Synth/SUBnote.h" +#include "../Synth/PADnote.h" +#include "../Params/Controller.h" +#include "../Misc/Microtonal.h" +#include "../DSP/FFTwrapper.h" +#include "../Effects/EffectMgr.h" +#include "XMLwrapper.h" + +#include // For the monomemnotes list. + +class Part{ + + public: + Part(Microtonal *microtonal_,FFTwrapper *fft_,pthread_mutex_t *mutex_); + ~Part(); + + /* Midi commands implemented */ + void NoteOn(unsigned char note,unsigned char velocity,int masterkeyshift); + void NoteOff(unsigned char note); + void AllNotesOff();//panic + void SetController(unsigned int type,int par); + void RelaseSustainedKeys();//this is called when the sustain pedal is relased + void RelaseAllKeys();//this is called on AllNotesOff controller + + /* The synthesizer part output */ + void ComputePartSmps();//Part output + + //instrumentonly: 0 - save all, 1 - save only instrumnet, 2 - save only instrument without the name(used in bank) + + + //saves the instrument settings to a XML file + //returns 0 for ok or <0 if there is an error + int saveXML(char *filename); + int loadXMLinstrument(const char *filename); + + void add2XML(XMLwrapper *xml); + void add2XMLinstrument(XMLwrapper *xml); + + void defaults(); + void defaultsinstrument(); + + void applyparameters(); + + void getfromXML(XMLwrapper *xml); + void getfromXMLinstrument(XMLwrapper *xml); + + void cleanup(); + +// ADnoteParameters *ADPartParameters; +// SUBnoteParameters *SUBPartParameters; + + //the part's kit + struct { + unsigned char Penabled,Pmuted,Pminkey,Pmaxkey; + unsigned char *Pname; + unsigned char Padenabled,Psubenabled,Ppadenabled; + unsigned char Psendtoparteffect; + ADnoteParameters *adpars; + SUBnoteParameters *subpars; + PADnoteParameters *padpars; + } kit[NUM_KIT_ITEMS]; + + + //Part parameters + void setkeylimit(unsigned char Pkeylimit); + void setkititemstatus(int kititem,int Penabled_); + + unsigned char Penabled;//if the part is enabled + unsigned char Pvolume;//part volume + unsigned char Pminkey;//the minimum key that the part receives noteon messages + unsigned char Pmaxkey;//the maximum key that the part receives noteon messages + void setPvolume(char Pvolume); + unsigned char Pkeyshift;//Part keyshift + unsigned char Prcvchn;//from what midi channel it receive commnads + unsigned char Ppanning;//part panning + void setPpanning(char Ppanning); + unsigned char Pvelsns;//velocity sensing (amplitude velocity scale) + unsigned char Pveloffs;//velocity offset + unsigned char Pnoteon;//if the part receives NoteOn messages + unsigned char Pkitmode;//if the kitmode is enabled + unsigned char Pdrummode;//if all keys are mapped and the system is 12tET (used for drums) + + unsigned char Ppolymode;//Part mode - 0=monophonic , 1=polyphonic + unsigned char Plegatomode;// 0=normal, 1=legato + unsigned char Pkeylimit;//how many keys are alowed to be played same time (0=off), the older will be relased + + unsigned char *Pname; //name of the instrument + struct{//instrument additional information + unsigned char Ptype; + unsigned char Pauthor[MAX_INFO_TEXT_SIZE+1]; + unsigned char Pcomments[MAX_INFO_TEXT_SIZE+1]; + } info; + + + REALTYPE *partoutl;//Left channel output of the part + REALTYPE *partoutr;//Right channel output of the part + + REALTYPE *partfxinputl[NUM_PART_EFX+1],*partfxinputr[NUM_PART_EFX+1];//Left and right signal that pass thru part effects; partfxinput l/r [NUM_PART_EFX] is for "no effect" buffer + + enum NoteStatus{KEY_OFF,KEY_PLAYING,KEY_RELASED_AND_SUSTAINED,KEY_RELASED}; + + REALTYPE volume,oldvolumel,oldvolumer;//this is applied by Master + REALTYPE panning;//this is applied by Master, too + + Controller ctl;//Part controllers + + EffectMgr *partefx[NUM_PART_EFX];//insertion part effects (they are part of the instrument) + unsigned char Pefxroute[NUM_PART_EFX];//how the effect's output is routed(to next effect/to out) + bool Pefxbypass[NUM_PART_EFX+1];//if the effects are bypassed + + + pthread_mutex_t *mutex; + + int lastnote; + + private: + void KillNotePos(int pos); + void RelaseNotePos(int pos); + void MonoMemRenote(); // MonoMem stuff. + + int killallnotes;//is set to 1 if I want to kill all notes + + struct PartNotes{ + NoteStatus status; + int note;//if there is no note playing, the "note"=-1 + int itemsplaying; + struct { + ADnote *adnote; + SUBnote *subnote; + PADnote *padnote; + int sendtoparteffect; + } kititem[NUM_KIT_ITEMS]; + int time; + }; + + int lastpos, lastposb; // To keep track of previously used pos and posb. + bool lastlegatomodevalid; // To keep track of previous legatomodevalid. + + // MonoMem stuff + std::list monomemnotes; // A list to remember held notes. + struct { + unsigned char velocity; + int mkeyshift;// I'm not sure masterkeyshift should be remembered. + } monomem[256]; /* 256 is to cover all possible note values. + monomem[] is used in conjunction with the list to + store the velocity and masterkeyshift values of a + given note (the list only store note values). + For example 'monomem[note].velocity' would be the + velocity value of the note 'note'. + */ + + PartNotes partnote[POLIPHONY]; + + REALTYPE *tmpoutl;//used to get the note + REALTYPE *tmpoutr; + + REALTYPE oldfreq;//this is used for portamento + Microtonal *microtonal; + FFTwrapper *fft; +}; + +#endif + diff --git a/plugins/zynaddsubfx/src/Misc/Util.C b/plugins/zynaddsubfx/src/Misc/Util.C new file mode 100644 index 000000000..049e5e898 --- /dev/null +++ b/plugins/zynaddsubfx/src/Misc/Util.C @@ -0,0 +1,112 @@ +/* + ZynAddSubFX - a software synthesizer + + Util.C - Miscellaneous functions + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include "Util.h" +#include +#include + +#include +#include +#include +#include +#include +#include + +int SAMPLE_RATE=44100; +int SOUND_BUFFER_SIZE=256; +int OSCIL_SIZE=1024; + +Config config; +REALTYPE *denormalkillbuf; + + +/* + * Transform the velocity according the scaling parameter (velocity sensing) + */ +REALTYPE VelF(REALTYPE velocity,unsigned char scaling){ + REALTYPE x; + x=pow(VELOCITY_MAX_SCALE,(64.0-scaling)/64.0); + if ((scaling==127)||(velocity>0.99)) return(1.0); + else return(pow(velocity,x)); +}; + +/* + * Get the detune in cents + */ +REALTYPE getdetune(unsigned char type,unsigned short int coarsedetune,unsigned short int finedetune){ + REALTYPE det=0.0,octdet=0.0,cdet=0.0,findet=0.0; + //Get Octave + int octave=coarsedetune/1024; + if (octave>=8) octave-=16; + octdet=octave*1200.0; + + //Coarse and fine detune + int cdetune=coarsedetune%1024; + if (cdetune>512) cdetune-=1024; + + int fdetune=finedetune-8192; + + switch (type){ +// case 1: is used for the default (see below) + case 2: cdet=fabs(cdetune*10.0); + findet=fabs(fdetune/8192.0)*10.0; + break; + case 3: cdet=fabs(cdetune*100); + findet=pow(10,fabs(fdetune/8192.0)*3.0)/10.0-0.1; + break; + case 4: cdet=fabs(cdetune*701.95500087);//perfect fifth + findet=(pow(2,fabs(fdetune/8192.0)*12.0)-1.0)/4095*1200; + break; + //case ...: need to update N_DETUNE_TYPES, if you'll add more + default:cdet=fabs(cdetune*50.0); + findet=fabs(fdetune/8192.0)*35.0;//almost like "Paul's Sound Designer 2" + break; + }; + if (finedetune<8192) findet=-findet; + if (cdetune<0) cdet=-cdet; + + det=octdet+cdet+findet; + return(det); +}; + + +bool fileexists(char *filename){ + struct stat tmp; + int result=stat(filename,&tmp); + if (result>=0) return(true); + + return(false); +}; + +void newFFTFREQS(FFTFREQS *f,int size){ + f->c=new REALTYPE[size]; + f->s=new REALTYPE[size]; + for (int i=0;ic[i]=0.0;f->s[i]=0.0; + }; +}; +void deleteFFTFREQS(FFTFREQS *f){ + delete[] f->c; + delete[] f->s; + f->c=f->s=NULL; +}; + diff --git a/plugins/zynaddsubfx/src/Misc/Util.h b/plugins/zynaddsubfx/src/Misc/Util.h new file mode 100644 index 000000000..6bb8fded4 --- /dev/null +++ b/plugins/zynaddsubfx/src/Misc/Util.h @@ -0,0 +1,45 @@ +/* + ZynAddSubFX - a software synthesizer + + Util.h - Miscellaneous functions + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef UTIL_H +#define UTIL_H + +#include +#include "../globals.h" +#include "Microtonal.h" +#include "../DSP/FFTwrapper.h" +#include "Config.h" + +//Velocity Sensing function +extern REALTYPE VelF(REALTYPE velocity,unsigned char scaling); + +bool fileexists(char *filename); + +#define N_DETUNE_TYPES 4 //the number of detune types +extern REALTYPE getdetune(unsigned char type,unsigned short int coarsedetune,unsigned short int finedetune); + +extern REALTYPE *denormalkillbuf;//the buffer to add noise in order to avoid denormalisation + +extern Config config; + +#endif + diff --git a/plugins/zynaddsubfx/src/Misc/XMLwrapper.C b/plugins/zynaddsubfx/src/Misc/XMLwrapper.C new file mode 100644 index 000000000..b7e9164f8 --- /dev/null +++ b/plugins/zynaddsubfx/src/Misc/XMLwrapper.C @@ -0,0 +1,533 @@ +/* + ZynAddSubFX - a software synthesizer + + XMLwrapper.C - XML wrapper + Copyright (C) 2003-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include "XMLwrapper.h" +#include +#include +#include + +#include "../globals.h" +#include "Util.h" + +int xml_k=0; +char tabs[STACKSIZE+2]; + +const char *XMLwrapper_whitespace_callback(mxml_node_t *node,int where){ + const char *name=node->value.element.name; + + if ((where==MXML_WS_BEFORE_OPEN)&&(!strcmp(name,"?xml"))) return(NULL); + if ((where==MXML_WS_BEFORE_CLOSE)&&(!strcmp(name,"string"))) return(NULL); + + if ((where==MXML_WS_BEFORE_OPEN)||(where==MXML_WS_BEFORE_CLOSE)) { +/* const char *tmp=node->value.element.name; + if (tmp!=NULL) { + if ((strstr(tmp,"par")!=tmp)&&(strstr(tmp,"string")!=tmp)) { + printf("%s ",tmp); + if (where==MXML_WS_BEFORE_OPEN) xml_k++; + if (where==MXML_WS_BEFORE_CLOSE) xml_k--; + if (xml_k>=STACKSIZE) xml_k=STACKSIZE-1; + if (xml_k<0) xml_k=0; + printf("%d\n",xml_k); + printf("\n"); + }; + + }; + int i=0; + for (i=1;i"); + char *end=strstr(xmldata,""); + + if ((start==NULL)||(end==NULL)||(start>end)) { + delete []xmldata; + return(false); + }; + end+=strlen(""); + end[0]='\0'; + + tree=mxmlNewElement(MXML_NO_PARENT,"?xml"); + node=root=mxmlLoadString(tree,xmldata,MXML_OPAQUE_CALLBACK); + if (root==NULL) { + delete []xmldata; + mxmlDelete(tree); + node=root=tree=NULL; + return(false); + }; + + root=mxmlFindElement(tree,tree,"INFORMATION",NULL,NULL,MXML_DESCEND); + push(root); + + if (root==NULL){ + delete []xmldata; + mxmlDelete(tree); + node=root=tree=NULL; + return(false); + }; + + information.PADsynth_used=getparbool("PADsynth_used",false); + + exitbranch(); + if (tree!=NULL) mxmlDelete(tree); + delete []xmldata; + node=root=tree=NULL; + + return(true); +}; + + +/* SAVE XML members */ + +int XMLwrapper::saveXMLfile(const char *filename){ + char *xmldata=getXMLdata(); + if (xmldata==NULL) return(-2); + + int compression=config.cfg.GzipCompression; + + int fnsize=strlen(filename)+100; + char *filenamenew=new char [fnsize]; + snprintf(filenamenew,fnsize,"%s",filename); + + int result=dosavefile(filenamenew,compression,xmldata); + + delete []filenamenew; + free(xmldata); + return(result); +}; + +char *XMLwrapper::getXMLdata(){ + xml_k=0; + ZERO(tabs,STACKSIZE+2); + + mxml_node_t *oldnode=node; + + node=info; + //Info storing + addparbool("PADsynth_used",information.PADsynth_used); + + node=oldnode; + char *xmldata=mxmlSaveAllocString(tree,XMLwrapper_whitespace_callback); + + return(xmldata); +}; + + +int XMLwrapper::dosavefile(const char *filename,int compression,const char *xmldata){ + if (compression==0){ + FILE *file; + file=fopen(filename,"w"); + if (file==NULL) return(-1); + fputs(xmldata,file); + fclose(file); + } else { + if (compression>9) compression=9; + if (compression<1) compression=1; + char options[10]; + snprintf(options,10,"wb%d",compression); + + gzFile gzfile; + gzfile=gzopen(filename,options); + if (gzfile==NULL) return(-1); + gzputs(gzfile,xmldata); + gzclose(gzfile); + }; + + return(0); +}; + + + +void XMLwrapper::addpar(const char *name,int val){ + addparams2("par","name",name,"value",int2str(val)); +}; + +void XMLwrapper::addparreal(const char *name,REALTYPE val){ + addparams2("par_real","name",name,"value",real2str(val)); +}; + +void XMLwrapper::addparbool(const char *name,int val){ + if (val!=0) addparams2("par_bool","name",name,"value","yes"); + else addparams2("par_bool","name",name,"value","no"); +}; + +void XMLwrapper::addparstr(const char *name,const char *val){ + mxml_node_t *element=mxmlNewElement(node,"string"); + mxmlElementSetAttr(element,"name",name); + mxmlNewText(element,0,val); +}; + + +void XMLwrapper::beginbranch(const char *name){ + push(node); + node=addparams0(name); +}; + +void XMLwrapper::beginbranch(const char *name,int id){ + push(node); + node=addparams1(name,"id",int2str(id)); +}; + +void XMLwrapper::endbranch(){ + node=pop(); +}; + + + +/* LOAD XML members */ + +int XMLwrapper::loadXMLfile(const char *filename){ + if (tree!=NULL) mxmlDelete(tree); + tree=NULL; + + ZERO(&parentstack,(int)sizeof(parentstack)); + ZERO(&values,(int)sizeof(values)); + + stackpos=0; + + const char *xmldata=doloadfile(filename); + if (xmldata==NULL) return(-1);//the file could not be loaded or uncompressed + + root=tree=mxmlLoadString(NULL,xmldata,MXML_OPAQUE_CALLBACK); + + delete []xmldata; + + if (tree==NULL) return(-2);//this is not XML + + + node=root=mxmlFindElement(tree,tree,"ZynAddSubFX-data",NULL,NULL,MXML_DESCEND); + if (root==NULL) return(-3);//the XML doesnt embbed zynaddsubfx data + push(root); + + values.xml_version.major=str2int(mxmlElementGetAttr(root,"version-major")); + values.xml_version.minor=str2int(mxmlElementGetAttr(root,"version-minor")); + + return(0); +}; + + +char *XMLwrapper::doloadfile(const char *filename){ + char *xmldata=NULL; + int filesize=-1; + + //try get filesize as gzip data (first) + gzFile gzfile=gzopen(filename,"rb"); + if (gzfile!=NULL){//this is a gzip file + // first check it's size + while(!gzeof(gzfile)) { + gzseek (gzfile,1024*1024,SEEK_CUR); + if (gztell(gzfile)>10000000) { + gzclose(gzfile); + goto notgzip;//the file is too big + }; + }; + filesize=gztell(gzfile); + + //rewind the file and load the data + xmldata=new char[filesize+1]; + ZERO(xmldata,filesize+1); + + gzrewind(gzfile); + gzread(gzfile,xmldata,filesize); + + gzclose(gzfile); + return (xmldata); + } else {//this is not a gzip file + notgzip: + FILE *file=fopen(filename,"rb"); + if (file==NULL) return(NULL); + fseek(file,0,SEEK_END); + filesize=ftell(file); + + xmldata=new char [filesize+1]; + ZERO(xmldata,filesize+1); + + rewind(file); + fread(xmldata,filesize,1,file); + + fclose(file); + return(xmldata); + }; +}; + +bool XMLwrapper::putXMLdata(const char *xmldata){ + if (tree!=NULL) mxmlDelete(tree); + tree=NULL; + + ZERO(&parentstack,(int)sizeof(parentstack)); + ZERO(&values,(int)sizeof(values)); + + stackpos=0; + + if (xmldata==NULL) return (false); + + root=tree=mxmlLoadString(NULL,xmldata,MXML_OPAQUE_CALLBACK); + + if (tree==NULL) return(false); + + node=root=mxmlFindElement(tree,tree,"ZynAddSubFX-data",NULL,NULL,MXML_DESCEND); + if (root==NULL) return (false);; + push(root); + + return(true); +}; + + + +int XMLwrapper::enterbranch(const char *name){ + node=mxmlFindElement(peek(),peek(),name,NULL,NULL,MXML_DESCEND_FIRST); + if (node==NULL) return(0); + + push(node); + return(1); +}; + +int XMLwrapper::enterbranch(const char *name,int id){ + snprintf(tmpstr,TMPSTR_SIZE,"%d",id); + node=mxmlFindElement(peek(),peek(),name,"id",tmpstr,MXML_DESCEND_FIRST); + if (node==NULL) return(0); + + push(node); + return(1); +}; + + +void XMLwrapper::exitbranch(){ + pop(); +}; + + +int XMLwrapper::getbranchid(int min, int max){ + int id=str2int(mxmlElementGetAttr(node,"id")); + if ((min==0)&&(max==0)) return(id); + + if (idmax) id=max; + + return(id); +}; + +int XMLwrapper::getpar(const char *name,int defaultpar,int min,int max){ + node=mxmlFindElement(peek(),peek(),"par","name",name,MXML_DESCEND_FIRST); + if (node==NULL) return(defaultpar); + + const char *strval=mxmlElementGetAttr(node,"value"); + if (strval==NULL) return(defaultpar); + + int val=str2int(strval); + if (valmax) val=max; + + return(val); +}; + +int XMLwrapper::getpar127(const char *name,int defaultpar){ + return(getpar(name,defaultpar,0,127)); +}; + +int XMLwrapper::getparbool(const char *name,int defaultpar){ + node=mxmlFindElement(peek(),peek(),"par_bool","name",name,MXML_DESCEND_FIRST); + if (node==NULL) return(defaultpar); + + const char *strval=mxmlElementGetAttr(node,"value"); + if (strval==NULL) return(defaultpar); + + if ((strval[0]=='Y')||(strval[0]=='y')) return(1); + else return(0); +}; + +void XMLwrapper::getparstr(const char *name,char *par,int maxstrlen){ + ZERO(par,maxstrlen); + node=mxmlFindElement(peek(),peek(),"string","name",name,MXML_DESCEND_FIRST); + + if (node==NULL) return; + if (node->child==NULL) return; + if (node->child->type!=MXML_OPAQUE) return; + + snprintf(par,maxstrlen,"%s",node->child->value.element.name); + +}; + +REALTYPE XMLwrapper::getparreal(const char *name,REALTYPE defaultpar){ + node=mxmlFindElement(peek(),peek(),"par_real","name",name,MXML_DESCEND_FIRST); + if (node==NULL) return(defaultpar); + + const char *strval=mxmlElementGetAttr(node,"value"); + if (strval==NULL) return(defaultpar); + + return(str2real(strval)); +}; + +REALTYPE XMLwrapper::getparreal(const char *name,REALTYPE defaultpar,REALTYPE min,REALTYPE max){ + REALTYPE result=getparreal(name,defaultpar); + + if (resultmax) result=max; + return(result); +}; + + +/** Private members **/ + +char *XMLwrapper::int2str(int x){ + snprintf(tmpstr,TMPSTR_SIZE,"%d",x); + return(tmpstr); +}; + +char *XMLwrapper::real2str(REALTYPE x){ + snprintf(tmpstr,TMPSTR_SIZE,"%g",x); + return(tmpstr); +}; + +int XMLwrapper::str2int(const char *str){ + if (str==NULL) return(0); + int result=strtol(str,NULL,10); + return(result); +}; + +REALTYPE XMLwrapper::str2real(const char *str){ + if (str==NULL) return(0.0); + REALTYPE result=strtod(str,NULL); + return(result); +}; + + +mxml_node_t *XMLwrapper::addparams0(const char *name){ + mxml_node_t *element=mxmlNewElement(node,name); + return(element); +}; + +mxml_node_t *XMLwrapper::addparams1(const char *name,const char *par1,const char *val1){ + mxml_node_t *element=mxmlNewElement(node,name); + mxmlElementSetAttr(element,par1,val1); + return(element); +}; + +mxml_node_t *XMLwrapper::addparams2(const char *name,const char *par1,const char *val1,const char *par2, const char *val2){ + mxml_node_t *element=mxmlNewElement(node,name); + mxmlElementSetAttr(element,par1,val1); + mxmlElementSetAttr(element,par2,val2); + return(element); +}; + + + + +void XMLwrapper::push(mxml_node_t *node){ + if (stackpos>=STACKSIZE-1) { + printf("BUG!: XMLwrapper::push() - full parentstack\n"); + return; + }; + stackpos++; + parentstack[stackpos]=node; + +// printf("push %d - %s\n",stackpos,node->value.element.name); + +}; +mxml_node_t *XMLwrapper::pop(){ + if (stackpos<=0) { + printf("BUG!: XMLwrapper::pop() - empty parentstack\n"); + return (root); + }; + mxml_node_t *node=parentstack[stackpos]; + parentstack[stackpos]=NULL; + +// printf("pop %d - %s\n",stackpos,node->value.element.name); + + stackpos--; + return(node); +}; + +mxml_node_t *XMLwrapper::peek(){ + if (stackpos<=0) { + printf("BUG!: XMLwrapper::peek() - empty parentstack\n"); + return (root); + }; + return(parentstack[stackpos]); +}; + + + diff --git a/plugins/zynaddsubfx/src/Misc/XMLwrapper.h b/plugins/zynaddsubfx/src/Misc/XMLwrapper.h new file mode 100644 index 000000000..7346e0c88 --- /dev/null +++ b/plugins/zynaddsubfx/src/Misc/XMLwrapper.h @@ -0,0 +1,175 @@ +/* + ZynAddSubFX - a software synthesizer + + XML.h - XML wrapper + Copyright (C) 2003-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include +#ifndef REALTYPE +#define REALTYPE float +#endif + +#ifndef XML_WRAPPER_H +#define XML_WRAPPER_H + +#define TMPSTR_SIZE 50 + +//the maxim tree depth +#define STACKSIZE 100 + +class XMLwrapper{ + public: + XMLwrapper(); + ~XMLwrapper(); + + /********************************/ + /* SAVE to XML */ + /********************************/ + + //returns 0 if ok or -1 if the file cannot be saved + int saveXMLfile(const char *filename); + + //returns the new allocated string that contains the XML data (used for clipboard) + //the string is NULL terminated + char *getXMLdata(); + + //add simple parameter (name and value) + void addpar(const char *name,int val); + void addparreal(const char *name,REALTYPE val); + + //add boolean parameter (name and boolean value) + //if the value is 0 => "yes", else "no" + void addparbool(const char *name,int val); + + //add string parameter (name and string) + void addparstr(const char *name,const char *val); + + //add a branch + void beginbranch(const char *name); + void beginbranch(const char *name, int id); + + //this must be called after each branch (nodes that contains child nodes) + void endbranch(); + + /********************************/ + /* LOAD from XML */ + /********************************/ + + //returns 0 if ok or -1 if the file cannot be loaded + int loadXMLfile(const char *filename); + + //used by the clipboard + bool putXMLdata(const char *xmldata); + + //enter into the branch + //returns 1 if is ok, or 0 otherwise + int enterbranch(const char *name); + + + //enter into the branch with id + //returns 1 if is ok, or 0 otherwise + int enterbranch(const char *name, int id); + + //exits from a branch + void exitbranch(); + + //get the the branch_id and limits it between the min and max + //if min==max==0, it will not limit it + //if there isn't any id, will return min + //this must be called only imediately after enterbranch() + int getbranchid(int min, int max); + + //it returns the parameter and limits it between min and max + //if min==max==0, it will not limit it + //if no parameter will be here, the defaultpar will be returned + int getpar(const char *name,int defaultpar,int min,int max); + + //the same as getpar, but the limits are 0 and 127 + int getpar127(const char *name,int defaultpar); + + int getparbool(const char *name,int defaultpar); + + void getparstr(const char *name,char *par,int maxstrlen); + REALTYPE getparreal(const char *name,REALTYPE defaultpar); + REALTYPE getparreal(const char *name,REALTYPE defaultpar,REALTYPE min,REALTYPE max); + + bool minimal;//false if all parameters will be stored (used only for clipboard) + + struct { + bool PADsynth_used; + }information; + + //opens a file and parse only the "information" data on it + //returns "true" if all went ok or "false" on errors + bool checkfileinformation(const char *filename); + + private: + + int dosavefile(const char *filename,int compression,const char *xmldata); + char *doloadfile(const char *filename); + + + mxml_node_t *tree;//all xml data + mxml_node_t *root;//xml data used by zynaddsubfx + mxml_node_t *node;//current node + mxml_node_t *info;//this node is used to store the information about the data + + //adds params like this: + // + //returns the node + mxml_node_t *addparams0(const char *name); + + //adds params like this: + // + //returns the node + mxml_node_t *addparams1(const char *name,const char *par1,const char *val1); + + //adds params like this: + // + //returns the node + mxml_node_t *addparams2(const char *name,const char *par1,const char *val1,const char *par2, const char *val2); + + char *int2str(int x); + char *real2str(REALTYPE x); + + int str2int(const char *str); + REALTYPE str2real(const char *str); + + char tmpstr[TMPSTR_SIZE]; + + + //this is used to store the parents + mxml_node_t *parentstack[STACKSIZE]; + int stackpos; + + + void push(mxml_node_t *node); + mxml_node_t *pop(); + mxml_node_t *peek(); + + //theese are used to store the values + struct{ + struct { + int major,minor; + }xml_version; + }values; + +}; + +#endif diff --git a/plugins/zynaddsubfx/src/Output/DSSIaudiooutput.C b/plugins/zynaddsubfx/src/Output/DSSIaudiooutput.C new file mode 100644 index 000000000..15e878b55 --- /dev/null +++ b/plugins/zynaddsubfx/src/Output/DSSIaudiooutput.C @@ -0,0 +1,279 @@ +/* + ZynAddSubFX - a software synthesizer + + DSSIaudiooutput.C - Audio functions for DSSI + Copyright (C) 2002 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +//this file contains code used from trivial_synth.c from +//the DSSI (published by Steve Harris under public domain) as a template +//the code is incomplete +#include +#include "DSSIaudiooutput.h" + +static LADSPA_Descriptor *tsLDescriptor = NULL; +static DSSI_Descriptor *tsDDescriptor = NULL; + +typedef struct { + LADSPA_Data *outl; + LADSPA_Data *outr; +// note_data data[MIDI_NOTES]; +// float omega[MIDI_NOTES]; +} TS; + + +static void cleanupTS(LADSPA_Handle instance){ + free(instance); +} +static void connectPortTS(LADSPA_Handle instance, unsigned long port, + LADSPA_Data * data){ + TS *plugin; + plugin = (TS *) instance; + switch (port) { + case 0: + plugin->outl = data; + break; + case 1: + plugin->outr = data; + break; + } +} + +const LADSPA_Descriptor *ladspa_descriptor(unsigned long index){ + switch (index) { + case 0: + return tsLDescriptor; + default: + return NULL; + } +} + +const DSSI_Descriptor *dssi_descriptor(unsigned long index){ +// FILE *a=fopen("/tmp/zzzzz11z","w"); +// fprintf(a,"aaaaaaaaaaa TEST\n"); +// fclose(a); + switch (index) { + case 0: + return tsDDescriptor; + default: + return NULL; + } +} + +static LADSPA_Handle instantiateTS(const LADSPA_Descriptor * descriptor, + unsigned long s_rate) +{ + + TS *plugin_data = (TS *) malloc(sizeof(TS)); +/* for (i=0; iomega[i] = M_PI * 2.0 / (double)s_rate * + pow(2.0, (i-69.0) / 12.0); + } +*/ + return (LADSPA_Handle) plugin_data; +} + +static void activateTS(LADSPA_Handle instance) +{ + TS *plugin_data = (TS *) instance; + +// for (i=0; idata[i].active = 0; +// } +} + + +static void runTS(LADSPA_Handle instance, unsigned long sample_count, + snd_seq_event_t *events, unsigned long event_count){ + TS *plugin_data = (TS *) instance; +// LADSPA_Data *const output = plugin_data->output; +// LADSPA_Data freq = *(plugin_data->freq); +// LADSPA_Data vol = *(plugin_data->vol); +// note_data *data = plugin_data->data; + unsigned long pos; + unsigned long event_pos; + unsigned long note; + +/* if (freq < 1.0) { + freq = 440.0f; + } + if (vol < 0.000001) { + vol = 1.0f; + } + + if (event_count > 0) { + printf("trivial_synth: have %ld events\n", event_count); + } + + for (pos = 0, event_pos = 0; pos < sample_count; pos++) { + + while (event_pos < event_count + && pos == events[event_pos].time.tick) { + + printf("trivial_synth: event type %d\n", events[event_pos].type); + + if (events[event_pos].type == SND_SEQ_EVENT_NOTEON) { + data[events[event_pos].data.note.note].amp = + events[event_pos].data.note.velocity / 512.0f; + data[events[event_pos].data.note.note]. + active = events[event_pos].data.note.velocity > 0; + data[events[event_pos].data.note.note]. + phase = 0.0; + } else if (events[event_pos].type == SND_SEQ_EVENT_NOTEOFF) { + data[events[event_pos].data.note.note]. + active = 0; + } + event_pos++; + } + + output[pos] = 0.0f; + for (note = 0; note < MIDI_NOTES; note++) { + if (data[note].active) { + output[pos] += sin(data[note].phase) * data[note].amp * vol; + data[note].phase += plugin_data->omega[note] * freq; + if (data[note].phase > M_PI * 2.0) { + data[note].phase -= M_PI * 2.0; + } + } + } + } + */ +} + + +static void runTSWrapper(LADSPA_Handle instance, + unsigned long sample_count){ + runTS(instance, sample_count, NULL, 0); +} + +int getControllerTS(LADSPA_Handle instance, unsigned long port){ + return -1; +} + +void _init(){ + char **port_names; + LADSPA_PortDescriptor *port_descriptors; + LADSPA_PortRangeHint *port_range_hints; + + FILE *a=fopen("/tmp/zzzzzz","w"); + fprintf(a,"aaaaaaaaaaa TEST\n"); + fclose(a); + + + tsLDescriptor = (LADSPA_Descriptor *) malloc(sizeof(LADSPA_Descriptor)); + if (tsLDescriptor) { + tsLDescriptor->UniqueID = 100; + tsLDescriptor->Label = "ZASF"; + tsLDescriptor->Properties = 0; + tsLDescriptor->Name = "ZynAddSubFX"; + tsLDescriptor->Maker = "Nasca Octavian Paul "; + tsLDescriptor->Copyright = "GNU General Public License v.2"; + tsLDescriptor->PortCount = 2; + + port_descriptors = (LADSPA_PortDescriptor *) + calloc(tsLDescriptor->PortCount, sizeof + (LADSPA_PortDescriptor)); + tsLDescriptor->PortDescriptors = + (const LADSPA_PortDescriptor *) port_descriptors; + + port_range_hints = (LADSPA_PortRangeHint *) + calloc(tsLDescriptor->PortCount, sizeof + (LADSPA_PortRangeHint)); + tsLDescriptor->PortRangeHints = + (const LADSPA_PortRangeHint *) port_range_hints; + + port_names = (char **) calloc(tsLDescriptor->PortCount, sizeof(char *)); + tsLDescriptor->PortNames = (const char **) port_names; + + port_descriptors[0] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO; + port_names[0] = "Output L"; + port_range_hints[0].HintDescriptor = 0; + port_descriptors[1] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO; + port_names[1] = "Output R"; + port_range_hints[1].HintDescriptor = 0; + + tsLDescriptor->activate = activateTS; + tsLDescriptor->cleanup = cleanupTS; + tsLDescriptor->connect_port = connectPortTS; + tsLDescriptor->deactivate = NULL; + tsLDescriptor->instantiate = instantiateTS; + tsLDescriptor->run = runTSWrapper; + tsLDescriptor->run_adding = NULL; + tsLDescriptor->set_run_adding_gain = NULL; + } + + tsDDescriptor = (DSSI_Descriptor *) malloc(sizeof(DSSI_Descriptor)); + if (tsDDescriptor) { + tsDDescriptor->DSSI_API_Version = 1; + tsDDescriptor->LADSPA_Plugin = tsLDescriptor; + tsDDescriptor->configure = NULL; + tsDDescriptor->get_program = NULL; + tsDDescriptor->get_midi_controller_for_port = getControllerTS; + tsDDescriptor->select_program = NULL; + tsDDescriptor->run_synth = runTS; + tsDDescriptor->run_synth_adding = NULL; + tsDDescriptor->run_multiple_synths = NULL; + tsDDescriptor->run_multiple_synths_adding = NULL; + } + +}; + +void _fini(){ +}; + + + + + + + +//the constructor and the destructor are defined in main.C +/* +void VSTSynth::process (float **inputs, float **outputs, long sampleframes){ + float *outl=outputs[0]; + float *outr=outputs[1]; + pthread_mutex_lock(&vmaster->mutex); + vmaster->GetAudioOutSamples(sampleframes,(int) getSampleRate(),outl,outr); + pthread_mutex_unlock(&vmaster->mutex); +}; + +void VSTSynth::processReplacing (float **inputs, float **outputs, long sampleframes){ + process(inputs,outputs,sampleframes); +}; + +long int VSTSynth::canDo(char *txt){ + if (strcmp(txt,"receiveVstEvents")==0) return (1); + if (strcmp(txt,"receiveVstMidiEvent")==0) return (1); + return(-1); +}; + +bool VSTSynth::getVendorString(char *txt){ + strcpy(txt,"Nasca O. Paul"); + return(true); +}; + +bool VSTSynth::getProductString(char *txt){ + strcpy(txt,"ZynAddSubFX"); + return(true); +}; + +void VSTSynth::resume(){ + wantEvents(); +}; + +*/ diff --git a/plugins/zynaddsubfx/src/Output/DSSIaudiooutput.h b/plugins/zynaddsubfx/src/Output/DSSIaudiooutput.h new file mode 100644 index 000000000..fb93c40c5 --- /dev/null +++ b/plugins/zynaddsubfx/src/Output/DSSIaudiooutput.h @@ -0,0 +1,59 @@ +/* + ZynAddSubFX - a software synthesizer + + VSTaudiooutput.h - Audio output for VST + Copyright (C) 2002 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ +#ifndef VST_AUDIO_OUTPUT_H +#define VST_AUDIO_OUTPUT_H + +#include + +#include "../globals.h" +#include "../Misc/Master.h" +#include "../UI/MasterUI.h" + +#include +#include + +/* +class VSTSynth:public AudioEffectX{ + public: + VSTSynth (audioMasterCallback audioMaster); + ~VSTSynth(); + + virtual void process (float **inputs, float **outputs, long sampleframes); + virtual void processReplacing (float **inputs, float **outputs, long sampleframes); + virtual long processEvents(VstEvents *events);//this is used for Midi input + virtual long int canDo(char *txt); + virtual bool getVendorString(char *txt); + virtual bool getProductString(char *txt); + virtual void resume(); + + virtual long getChunk(void** data,bool isPreset=false); + virtual void setChunk(void *data,long size,bool isPreset=false); + + MasterUI *ui; + int Pexitprogram; + + Master *vmaster; + pthread_t thr; +}; +*/ +#endif + diff --git a/plugins/zynaddsubfx/src/Output/JACK_RTaudiooutput.C b/plugins/zynaddsubfx/src/Output/JACK_RTaudiooutput.C new file mode 100644 index 000000000..90af1975d --- /dev/null +++ b/plugins/zynaddsubfx/src/Output/JACK_RTaudiooutput.C @@ -0,0 +1,198 @@ +/* + ZynAddSubFX - a software synthesizer + + JACKaudiooutput.C - Audio output for JACK + Copyright (C) 2002 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include +#include +#include +#include + + +extern "C" { +#include +}; +#include "JACKaudiooutput.h" + +Master *jackmaster; +jack_client_t *jackclient; +jack_port_t *outport_left,*outport_right; +jack_ringbuffer_t *rb=NULL; + +REALTYPE *jackoutl,*jackoutr; +int jackfinish=0; + +void *thread_blocked(void *arg); +int jackprocess(jack_nframes_t nframes,void *arg); +int jacksrate(jack_nframes_t nframes,void *arg); +void jackshutdown(void *arg); + +pthread_cond_t more_data=PTHREAD_COND_INITIALIZER; +pthread_mutex_t zyn_thread_lock=PTHREAD_MUTEX_INITIALIZER; + +pthread_t bthr; + + +bool JACKaudiooutputinit(Master *master_){ + jackmaster=master_; + jackclient=0; + char tmpstr[100]; + + jackoutl=new REALTYPE [SOUND_BUFFER_SIZE]; + jackoutr=new REALTYPE [SOUND_BUFFER_SIZE]; + + int rbbufsize=SOUND_BUFFER_SIZE*sizeof (REALTYPE)*2*2; + printf("%d\n",rbbufsize); + rb=jack_ringbuffer_create(rbbufsize); + for (int i=0;ibuf[i]=0.0; + + + for (int i=0;i<15;i++){ + if (i!=0) snprintf(tmpstr,100,"ZynAddSubFX_%d",i); + else snprintf(tmpstr,100,"ZynAddSubFX"); + jackclient=jack_client_new(tmpstr); + if (jackclient!=0) break; + }; + + if (jackclient==0) { + fprintf(stderr,"\nERROR: Cannot make a jack client (possible reasons: JACK server is not running or jackd is launched by root and zynaddsubfx by another user.).\n\n\n"); + return(false); + }; + + fprintf(stderr,"Internal SampleRate = %d\nJack Output SampleRate= %d\n",SAMPLE_RATE,jack_get_sample_rate(jackclient)); + if ((unsigned int)jack_get_sample_rate(jackclient)!=(unsigned int) SAMPLE_RATE) + fprintf(stderr,"It is recomanded that the both samplerates to be equal.\n"); + + jack_set_process_callback(jackclient,jackprocess,0); + jack_set_sample_rate_callback(jackclient,jacksrate,0); + jack_on_shutdown(jackclient,jackshutdown,0); + + outport_left=jack_port_register(jackclient,"out_1", + JACK_DEFAULT_AUDIO_TYPE,JackPortIsOutput|JackPortIsTerminal,0); + outport_right=jack_port_register(jackclient,"out_2", + JACK_DEFAULT_AUDIO_TYPE,JackPortIsOutput|JackPortIsTerminal,0); + + if (jack_activate(jackclient)){ + fprintf(stderr,"Cannot activate jack client\n"); + return(false); + }; + + pthread_create(&bthr,NULL,thread_blocked,NULL); + + /* + jack_connect(jackclient,jack_port_name(outport_left),"alsa_pcm:out_1"); + jack_connect(jackclient,jack_port_name(outport_right),"alsa_pcm:out_2"); + */ + + return(true); +}; + +void *thread_blocked(void *arg){ + int datasize=SOUND_BUFFER_SIZE*sizeof (REALTYPE); + + //try to get realtime + sched_param sc; + sc.sched_priority=50; + int err=sched_setscheduler(0,SCHED_FIFO,&sc); + + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL); + pthread_mutex_lock(&zyn_thread_lock); + + while (jackfinish==0){ + while (jack_ringbuffer_write_space(rb)>=datasize){ + pthread_mutex_lock(&jackmaster->mutex); + jackmaster->GetAudioOutSamples(SOUND_BUFFER_SIZE,jack_get_sample_rate(jackclient),jackoutl,jackoutr); + pthread_mutex_unlock(&jackmaster->mutex); + + jack_ringbuffer_write(rb, (char *) jackoutl,datasize); + jack_ringbuffer_write(rb, (char *) jackoutr,datasize); + }; + pthread_cond_wait(&more_data,&zyn_thread_lock); + }; + pthread_mutex_unlock(&zyn_thread_lock); + + return(0); +}; + + +int jackprocess(jack_nframes_t nframes,void *arg){ + jack_default_audio_sample_t *outl=(jack_default_audio_sample_t *) jack_port_get_buffer (outport_left, nframes); + jack_default_audio_sample_t *outr=(jack_default_audio_sample_t *) jack_port_get_buffer (outport_right, nframes); + + int datasize=nframes*sizeof (REALTYPE); + int incoming_datasize=SOUND_BUFFER_SIZE*sizeof (REALTYPE); + int data_read=0; + + + if (jack_ringbuffer_read_space(rb)>=(2*incoming_datasize)){ + if (datasize>incoming_datasize){ + data_read=0; + while (data_read < datasize){ + jack_ringbuffer_read(rb, (char *) outl+data_read,datasize); + jack_ringbuffer_read(rb, (char *) outr+data_read,datasize); + data_read+=incoming_datasize; + }; + } else if (datasize==incoming_datasize){ + jack_ringbuffer_read(rb, (char *) outl,datasize); + jack_ringbuffer_read(rb, (char *) outr,datasize); + } else { + }; + } else {//the ringbuffer is empty or there are too small amount of samples in it + for (int i=0;i=datasize){ + jack_ringbuffer_read(rb, (char *) outl,datasize); + jack_ringbuffer_read(rb, (char *) outr,datasize); + } else {//the ringbuffer is empty or there are too small amount of samples in it + for (int i=0;i +#include +#include "JACKaudiooutput.h" + +Master *jackmaster; +jack_client_t *jackclient; +char jackname[100]; +jack_port_t *outport_left,*outport_right,*midi_inport; + +int jackprocess(jack_nframes_t nframes,void *arg); +int jacksrate(jack_nframes_t nframes,void *arg); +void jackshutdown(void *arg); + +bool JACKaudiooutputinit(Master *master_){ + jackmaster=master_; + jackclient=0; + + for (int i=0;i<15;i++){ + if (i!=0) snprintf(jackname,100,"ZynAddSubFX_%d",i); + else snprintf(jackname,100,"ZynAddSubFX"); + jackclient=jack_client_new(jackname); + if (jackclient!=0) break; + }; + + if (jackclient==0) { + fprintf(stderr,"\nERROR: Cannot make a jack client (possible reasons: JACK server is not running or jackd is launched by root and zynaddsubfx by another user.).\n"); + return(false); + }; + + fprintf(stderr,"Internal SampleRate = %d\nJack Output SampleRate= %d\n",SAMPLE_RATE,jack_get_sample_rate(jackclient)); + if ((unsigned int)jack_get_sample_rate(jackclient)!=(unsigned int) SAMPLE_RATE) + fprintf(stderr,"It is recomanded that the both samplerates to be equal.\n"); + + jack_set_process_callback(jackclient,jackprocess,0); + jack_set_sample_rate_callback(jackclient,jacksrate,0); + jack_on_shutdown(jackclient,jackshutdown,0); + + outport_left=jack_port_register(jackclient,"out_1", + JACK_DEFAULT_AUDIO_TYPE,JackPortIsOutput|JackPortIsTerminal,0); + outport_right=jack_port_register(jackclient,"out_2", + JACK_DEFAULT_AUDIO_TYPE,JackPortIsOutput|JackPortIsTerminal,0); + midi_inport=jack_port_register(jackclient,"midi_input", + JACK_DEFAULT_MIDI_TYPE,JackPortIsInput|JackPortIsTerminal,0); + + if (jack_activate(jackclient)){ + fprintf(stderr,"Cannot activate jack client\n"); + return(false); + }; + + /* + jack_connect(jackclient,jack_port_name(outport_left),"alsa_pcm:out_1"); + jack_connect(jackclient,jack_port_name(outport_right),"alsa_pcm:out_2"); + */ + return(true); +}; + +int jackprocess(jack_nframes_t nframes,void *arg){ + jack_default_audio_sample_t *outl=(jack_default_audio_sample_t *) jack_port_get_buffer (outport_left, nframes); + jack_default_audio_sample_t *outr=(jack_default_audio_sample_t *) jack_port_get_buffer (outport_right, nframes); + + if (!pthread_mutex_trylock(&jackmaster->mutex)) { + JACKhandlemidi(nframes); + jackmaster->GetAudioOutSamples(nframes,jack_get_sample_rate(jackclient),outl,outr); + pthread_mutex_unlock(&jackmaster->mutex); + } + else { + memset(outl, 0, sizeof(jack_default_audio_sample_t) * nframes); + memset(outr, 0, sizeof(jack_default_audio_sample_t) * nframes); + } + + return(0); +}; + +void JACKfinish(){ + jack_client_close(jackclient); +}; + +int jacksrate(jack_nframes_t nframes,void *arg){ + + return(0); +}; + +void jackshutdown(void *arg){ +}; + + +void JACKhandlemidi(unsigned long frames) { + + // We must have the master mutex before we run this function + + // XXX This is really nasty, not only do we lose the sample accuracy of + // JACK MIDI, but any accuracy at all below the buffer size + + void* midi_buf = jack_port_get_buffer(midi_inport, frames); + jack_midi_event_t jack_midi_event; + jack_nframes_t event_index = 0; + jack_nframes_t event_count = + jack_midi_port_get_info(midi_buf, frames)->event_count; + unsigned char* midi_data; + unsigned char type, chan; + + while (event_index < event_count) { + + jack_midi_event_get(&jack_midi_event, midi_buf, event_index, frames); + midi_data = jack_midi_event.buffer; + type = midi_data[0] & 0xF0; + chan = midi_data[0] & 0x0F; + + switch (type) { + + case 0x80: /* note-off */ + jackmaster->NoteOff(chan, midi_data[1]); + break; + + case 0x90: /* note-on */ + jackmaster->NoteOn(chan, midi_data[1], midi_data[2]); + break; + + case 0xB0: /* controller */ + jackmaster->SetController(chan, midi_data[1], midi_data[2]); + break; + + case 0xE0: /* pitch bend */ + jackmaster->SetController(chan, C_pitchwheel, + ((midi_data[2] << 7) | midi_data[1])); + break; + + /* XXX TODO: handle MSB/LSB controllers and RPNs and NRPNs */ + } + + event_index++; + } + +} + + +const char* JACKgetname() { + if (jackclient != NULL) + return jackname; + return NULL; +} diff --git a/plugins/zynaddsubfx/src/Output/JACKaudiooutput.h b/plugins/zynaddsubfx/src/Output/JACKaudiooutput.h new file mode 100644 index 000000000..6b3f3360f --- /dev/null +++ b/plugins/zynaddsubfx/src/Output/JACKaudiooutput.h @@ -0,0 +1,47 @@ +/* + ZynAddSubFX - a software synthesizer + + JACKaudiooutput.h - Audio output for JACK + Copyright (C) 2002 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ +#ifndef JACK_AUDIO_OUTPUT_H +#define JACK_AUDIO_OUTPUT_H + +#include + +#include "../globals.h" +#include "../Misc/Master.h" + + +#if (REALTYPE!=jack_default_audio_sample_t) +#error "The internal sample datatype of ZynAddSubFX and the datatype of jack differs.\ + In order to compile ZynAddSubFX the 'REALTYPE' and 'jack_default_audio_sample_t' must be equal.\ + Set the 'REALTYPE' data type (which is defined in 'globals.h') to what is defined \ + in the file types.h from jack include directory as 'jack_default_audio_sample_t' (as float or double)." +#endif + + + + +bool JACKaudiooutputinit(Master *master_); +void JACKfinish(); +void JACKhandlemidi(unsigned long frames); +const char* JACKgetname(); + +#endif + diff --git a/plugins/zynaddsubfx/src/Output/OSSaudiooutput.C b/plugins/zynaddsubfx/src/Output/OSSaudiooutput.C new file mode 100644 index 000000000..aea0b444e --- /dev/null +++ b/plugins/zynaddsubfx/src/Output/OSSaudiooutput.C @@ -0,0 +1,87 @@ +/* + ZynAddSubFX - a software synthesizer + + OSSaudiooutput.C - Audio output for Open Sound System + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include "OSSaudiooutput.h" +#include "../Misc/Util.h" + +OSSaudiooutput::OSSaudiooutput(){ + int i; + int snd_bitsize=16; + snd_fragment=0x00080009;//fragment size (?) + snd_stereo=1;//stereo + snd_format=AFMT_S16_LE; + snd_samplerate=SAMPLE_RATE; + + smps=new short int[SOUND_BUFFER_SIZE*2]; + for (i=0;i1.0) l=1.0; + if (r<-1.0) r=-1.0; else if (r>1.0) r=1.0; + + smps[i*2]=(short int) (l*32767.0); + smps[i*2+1]=(short int) (r*32767.0); + }; + write(snd_handle,smps,SOUND_BUFFER_SIZE*4);// *2 because is 16 bit, again * 2 because is stereo +}; + + +OSSaudiooutput::~OSSaudiooutput(){ + close(snd_handle); + delete [] smps; +}; + diff --git a/plugins/zynaddsubfx/src/Output/OSSaudiooutput.h b/plugins/zynaddsubfx/src/Output/OSSaudiooutput.h new file mode 100644 index 000000000..43d47aa6f --- /dev/null +++ b/plugins/zynaddsubfx/src/Output/OSSaudiooutput.h @@ -0,0 +1,48 @@ +/* + ZynAddSubFX - a software synthesizer + + OSSaudiooutput.h - Audio output for Open Sound System + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef OSS_AUDIO_OUTPUT_H +#define OSS_AUDIO_OUTPUT_H + + +#include +#include "../globals.h" +class OSSaudiooutput{ + public: + OSSaudiooutput(); + ~OSSaudiooutput(); + + //the out is [-1.0 .. 1.0] + /* smp_left[] and smp_right[] has the size of SOUND_BUFFER_SIZE */ + void OSSout(REALTYPE *smp_left,REALTYPE *smp_right); + private: + int snd_handle; + int snd_fragment; + int snd_stereo; + int snd_format; + int snd_samplerate; + + short int *smps;//Samples to be sent to soundcard +}; + +#endif + diff --git a/plugins/zynaddsubfx/src/Output/PAaudiooutput.C b/plugins/zynaddsubfx/src/Output/PAaudiooutput.C new file mode 100644 index 000000000..6c5b9dc78 --- /dev/null +++ b/plugins/zynaddsubfx/src/Output/PAaudiooutput.C @@ -0,0 +1,70 @@ +/* + ZynAddSubFX - a software synthesizer + + PAaudiooutput.C - Audio output for PortAudio + Copyright (C) 2002 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include "PAaudiooutput.h" + +Master *PAmaster; +PaStream *stream; +REALTYPE *outl,*outr; + +int PAprocess(void *inputBuffer,void *outputBuffer, + unsigned long framesPerBuffer, + PaTimestamp outTime,void *userData){ + + if (framesPerBuffer!=SOUND_BUFFER_SIZE) { + fprintf(stderr,"Bug: PAudioOutput::PAprocess SOUND_BUFFER_SIZE!=framesPerBuffer"); + fprintf(stderr,"%d %d\n",framesPerBuffer,SOUND_BUFFER_SIZE); + }; + + pthread_mutex_lock(&PAmaster->mutex); + PAmaster->GetAudioOutSamples(SOUND_BUFFER_SIZE,SAMPLE_RATE,outl,outr); + pthread_mutex_unlock(&PAmaster->mutex); + + float *out=(float *)outputBuffer; + + for (int i=0;i=SOUND_BUFFER_SIZE) break;//this should never happens, except only when framesPerBuffer!>SOUND_BUFFER_SIZE + out[i*2]=outl[i]; + out[i*2+1]=outr[i]; + }; + + return(0); +}; + +void PAaudiooutputinit(Master *master_){ + PAmaster=master_; + outl=new REALTYPE [SOUND_BUFFER_SIZE]; + outr=new REALTYPE [SOUND_BUFFER_SIZE]; + Pa_Initialize(); + Pa_OpenDefaultStream(&stream,0,2,paFloat32,SAMPLE_RATE,SOUND_BUFFER_SIZE,0,PAprocess,NULL); + Pa_StartStream(stream); +}; + +void PAfinish(){ + Pa_StopStream(stream); + delete (outl); + delete (outr); +}; + + + + diff --git a/plugins/zynaddsubfx/src/Output/PAaudiooutput.h b/plugins/zynaddsubfx/src/Output/PAaudiooutput.h new file mode 100644 index 000000000..c416156ec --- /dev/null +++ b/plugins/zynaddsubfx/src/Output/PAaudiooutput.h @@ -0,0 +1,34 @@ +/* + ZynAddSubFX - a software synthesizer + + PAaudiooutput.h - Audio output for PortAudio + Copyright (C) 2002 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ +#ifndef PA_AUDIO_OUTPUT_H +#define PA_AUDIO_OUTPUT_H + +#include + +#include "../globals.h" +#include "../Misc/Master.h" + +void PAaudiooutputinit(Master *master_); +void PAfinish(); + +#endif + diff --git a/plugins/zynaddsubfx/src/Output/Recorder.C b/plugins/zynaddsubfx/src/Output/Recorder.C new file mode 100644 index 000000000..3851f3faf --- /dev/null +++ b/plugins/zynaddsubfx/src/Output/Recorder.C @@ -0,0 +1,106 @@ +/* + ZynAddSubFX - a software synthesizer + + Recorder.C - Records sound to a file + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "Recorder.h" +#include + +Recorder::Recorder(){ + recordbuf_16bit=new short int [SOUND_BUFFER_SIZE*2]; + status=0; + notetrigger=0; + for (int i=0;i32767) tmp=32767; + recordbuf_16bit[i*2]=tmp; + + tmp=(int)(outr[i]*32767.0); + if (tmp<-32768) tmp=-32768; + if (tmp>32767) tmp=32767; + recordbuf_16bit[i*2+1]=tmp; + }; + wav.write(SOUND_BUFFER_SIZE,recordbuf_16bit); +}; + +void Recorder::triggernow(){ + if (status==2) notetrigger=1; +}; diff --git a/plugins/zynaddsubfx/src/Output/Recorder.h b/plugins/zynaddsubfx/src/Output/Recorder.h new file mode 100644 index 000000000..cb089c0d8 --- /dev/null +++ b/plugins/zynaddsubfx/src/Output/Recorder.h @@ -0,0 +1,53 @@ +/* + ZynAddSubFX - a software synthesizer + + Recorder.h - Records sound to a file + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef RECORDER_H +#define RECORDER_H + +#include "../globals.h" +#include "WAVaudiooutput.h" + +class Recorder{ + public: + Recorder(); + ~Recorder(); + int preparefile(char *filename_,int overwrite);//returns 1 if the file exists + void start(); + void stop(); + void pause(); + int recording(); + void triggernow(); + void recordbuffer(REALTYPE *outl,REALTYPE *outr); + + /* Status: + 0 - not ready(no file selected), + 1 - ready + 2 - recording */ + int status; + + private: + WAVaudiooutput wav; + short int *recordbuf_16bit; + int notetrigger; +}; + +#endif diff --git a/plugins/zynaddsubfx/src/Output/VSTaudiooutput.C b/plugins/zynaddsubfx/src/Output/VSTaudiooutput.C new file mode 100644 index 000000000..9d564cad1 --- /dev/null +++ b/plugins/zynaddsubfx/src/Output/VSTaudiooutput.C @@ -0,0 +1,59 @@ +/* + ZynAddSubFX - a software synthesizer + + VSTaudiooutput.C - Audio output for VST + Copyright (C) 2002 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ +#include +#include "VSTaudiooutput.h" + +//the constructor and the destructor are defined in main.C + +void VSTSynth::process (float **inputs, float **outputs, long sampleframes){ + float *outl=outputs[0]; + float *outr=outputs[1]; + pthread_mutex_lock(&vmaster->mutex); + vmaster->GetAudioOutSamples(sampleframes,(int) getSampleRate(),outl,outr); + pthread_mutex_unlock(&vmaster->mutex); +}; + +void VSTSynth::processReplacing (float **inputs, float **outputs, long sampleframes){ + process(inputs,outputs,sampleframes); +}; + +long int VSTSynth::canDo(char *txt){ + if (strcmp(txt,"receiveVstEvents")==0) return (1); + if (strcmp(txt,"receiveVstMidiEvent")==0) return (1); + return(-1); +}; + +bool VSTSynth::getVendorString(char *txt){ + strcpy(txt,"Nasca O. Paul"); + return(true); +}; + +bool VSTSynth::getProductString(char *txt){ + strcpy(txt,"ZynAddSubFX"); + return(true); +}; + +void VSTSynth::resume(){ + wantEvents(); +}; + + diff --git a/plugins/zynaddsubfx/src/Output/VSTaudiooutput.h b/plugins/zynaddsubfx/src/Output/VSTaudiooutput.h new file mode 100644 index 000000000..0a027968e --- /dev/null +++ b/plugins/zynaddsubfx/src/Output/VSTaudiooutput.h @@ -0,0 +1,57 @@ +/* + ZynAddSubFX - a software synthesizer + + VSTaudiooutput.h - Audio output for VST + Copyright (C) 2002 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ +#ifndef VST_AUDIO_OUTPUT_H +#define VST_AUDIO_OUTPUT_H + +#include + +#include "../globals.h" +#include "../Misc/Master.h" +#include "../UI/MasterUI.h" + +#include "../../../vstsdk2/source/common/audioeffectx.h" + +class VSTSynth:public AudioEffectX{ + public: + VSTSynth (audioMasterCallback audioMaster); + ~VSTSynth(); + + virtual void process (float **inputs, float **outputs, long sampleframes); + virtual void processReplacing (float **inputs, float **outputs, long sampleframes); + virtual long processEvents(VstEvents *events);//this is used for Midi input + virtual long int canDo(char *txt); + virtual bool getVendorString(char *txt); + virtual bool getProductString(char *txt); + virtual void resume(); + + virtual long getChunk(void** data,bool isPreset=false); + virtual long setChunk(void *data,long size,bool isPreset=false); + + MasterUI *ui; + int Pexitprogram; + + Master *vmaster; + pthread_t thr; +}; + +#endif + diff --git a/plugins/zynaddsubfx/src/Output/WAVaudiooutput.C b/plugins/zynaddsubfx/src/Output/WAVaudiooutput.C new file mode 100644 index 000000000..d305b54ad --- /dev/null +++ b/plugins/zynaddsubfx/src/Output/WAVaudiooutput.C @@ -0,0 +1,85 @@ +/* + Copyright (C) 2006 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include "WAVaudiooutput.h" +using namespace std; + +WAVaudiooutput::WAVaudiooutput(){ + file=NULL; + sampleswritten=0; + samplerate=44100; +}; + +WAVaudiooutput::~WAVaudiooutput(){ + close(); +}; + +bool WAVaudiooutput::newfile(string filename,int samplerate,int channels){ + close();//inchide un posibil fisier existent + file=fopen(filename.c_str(),"w"); + if (!file) return false; + this->samplerate=samplerate; + this->channels=channels; + sampleswritten=0; + char tmp[44]; + fwrite(tmp,1,44,file); + return(true); +}; + +void WAVaudiooutput::close(){ + if (file){ + unsigned int chunksize; + rewind(file); + + fwrite("RIFF",4,1,file); + chunksize=sampleswritten*4+36; + fwrite(&chunksize,4,1,file); + + fwrite("WAVEfmt ",8,1,file); + chunksize=16; + fwrite(&chunksize,4,1,file); + unsigned short int formattag=1;//uncompresed wave + fwrite(&formattag,2,1,file); + unsigned short int nchannels=channels;//stereo + fwrite(&nchannels,2,1,file); + unsigned int samplerate_=samplerate;//samplerate + fwrite(&samplerate_,4,1,file); + unsigned int bytespersec=samplerate*2*channels;//bytes/sec + fwrite(&bytespersec,4,1,file); + unsigned short int blockalign=2*channels;//2 channels * 16 bits/8 + fwrite(&blockalign,2,1,file); + unsigned short int bitspersample=16; + fwrite(&bitspersample,2,1,file); + + fwrite("data",4,1,file); + chunksize=sampleswritten*blockalign; + fwrite(&chunksize,4,1,file); + + fclose(file); + file=NULL; + }; +}; + +void WAVaudiooutput::write(int nsmps,short int *smps){ + if (!file) return; + fwrite(smps,nsmps,4,file); + sampleswritten+=nsmps; +}; + diff --git a/plugins/zynaddsubfx/src/Output/WAVaudiooutput.h b/plugins/zynaddsubfx/src/Output/WAVaudiooutput.h new file mode 100644 index 000000000..2ae2539f3 --- /dev/null +++ b/plugins/zynaddsubfx/src/Output/WAVaudiooutput.h @@ -0,0 +1,41 @@ +/* + + Copyright (C) 2008 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef WAVOUTPUT_H +#define WAVOUTPUT_H +#include +#include + +class WAVaudiooutput{ + public: + WAVaudiooutput(); + ~WAVaudiooutput(); + + bool newfile(std::string filename,int samplerate,int channels); + void close(); + + void write(int nsmps, short int *smps); + + private: + int sampleswritten; + int samplerate; + int channels; + FILE *file; +}; +#endif diff --git a/plugins/zynaddsubfx/src/Params/ADnoteParameters.C b/plugins/zynaddsubfx/src/Params/ADnoteParameters.C new file mode 100644 index 000000000..c8ea7ef4f --- /dev/null +++ b/plugins/zynaddsubfx/src/Params/ADnoteParameters.C @@ -0,0 +1,637 @@ +/* + ZynAddSubFX - a software synthesizer + + ADnoteParameters.C - Parameters for ADnote (ADsynth) + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include +#include +#include + +#include "ADnoteParameters.h" + +ADnoteParameters::ADnoteParameters(FFTwrapper *fft_):Presets(){ + setpresettype("Padsyth"); + fft=fft_; + + GlobalPar.FreqEnvelope=new EnvelopeParams(0,0); + GlobalPar.FreqEnvelope->ASRinit(64,50,64,60); + GlobalPar.FreqLfo=new LFOParams(70,0,64,0,0,0,0,0); + + GlobalPar.AmpEnvelope=new EnvelopeParams(64,1); + GlobalPar.AmpEnvelope->ADSRinit_dB(0,40,127,25); + GlobalPar.AmpLfo=new LFOParams(80,0,64,0,0,0,0,1); + + GlobalPar.GlobalFilter=new FilterParams(2,94,40); + GlobalPar.FilterEnvelope=new EnvelopeParams(0,1); + GlobalPar.FilterEnvelope->ADSRinit_filter(64,40,64,70,60,64); + GlobalPar.FilterLfo=new LFOParams(80,0,64,0,0,0,0,2); + GlobalPar.Reson=new Resonance(); + + for (int nvoice=0;nvoicedefaults(); + GlobalPar.FreqLfo->defaults(); + GlobalPar.PBandwidth=64; + + /* Amplitude Global Parameters */ + GlobalPar.PVolume=90; + GlobalPar.PPanning=64;//center + GlobalPar.PAmpVelocityScaleFunction=64; + GlobalPar.AmpEnvelope->defaults(); + GlobalPar.AmpLfo->defaults(); + GlobalPar.PPunchStrength=0; + GlobalPar.PPunchTime=60; + GlobalPar.PPunchStretch=64; + GlobalPar.PPunchVelocitySensing=72; + GlobalPar.Hrandgrouping=0; + + /* Filter Global Parameters*/ + GlobalPar.PFilterVelocityScale=64; + GlobalPar.PFilterVelocityScaleFunction=64; + GlobalPar.GlobalFilter->defaults(); + GlobalPar.FilterEnvelope->defaults(); + GlobalPar.FilterLfo->defaults(); + GlobalPar.Reson->defaults(); + + + for (int nvoice=0;nvoicedefaults(); + VoicePar[nvoice].FMSmp->defaults(); + + VoicePar[nvoice].AmpEnvelope->defaults(); + VoicePar[nvoice].AmpLfo->defaults(); + + VoicePar[nvoice].FreqEnvelope->defaults(); + VoicePar[nvoice].FreqLfo->defaults(); + + VoicePar[nvoice].VoiceFilter->defaults(); + VoicePar[nvoice].FilterEnvelope->defaults(); + VoicePar[nvoice].FilterLfo->defaults(); + + VoicePar[nvoice].FMFreqEnvelope->defaults(); + VoicePar[nvoice].FMAmpEnvelope->defaults(); +}; + + + +/* + * Init the voice parameters + */ +void ADnoteParameters::EnableVoice(int nvoice){ + VoicePar[nvoice].OscilSmp=new OscilGen(fft,GlobalPar.Reson); + VoicePar[nvoice].FMSmp=new OscilGen(fft,NULL); + + VoicePar[nvoice].AmpEnvelope=new EnvelopeParams(64,1); + VoicePar[nvoice].AmpEnvelope->ADSRinit_dB(0,100,127,100); + VoicePar[nvoice].AmpLfo=new LFOParams(90,32,64,0,0,30,0,1); + + VoicePar[nvoice].FreqEnvelope=new EnvelopeParams(0,0); + VoicePar[nvoice].FreqEnvelope->ASRinit(30,40,64,60); + VoicePar[nvoice].FreqLfo=new LFOParams(50,40,0,0,0,0,0,0); + + VoicePar[nvoice].VoiceFilter=new FilterParams(2,50,60); + VoicePar[nvoice].FilterEnvelope=new EnvelopeParams(0,0); + VoicePar[nvoice].FilterEnvelope->ADSRinit_filter(90,70,40,70,10,40); + VoicePar[nvoice].FilterLfo=new LFOParams(50,20,64,0,0,0,0,2); + + VoicePar[nvoice].FMFreqEnvelope=new EnvelopeParams(0,0); + VoicePar[nvoice].FMFreqEnvelope->ASRinit(20,90,40,80); + VoicePar[nvoice].FMAmpEnvelope=new EnvelopeParams(64,1); + VoicePar[nvoice].FMAmpEnvelope->ADSRinit(80,90,127,100); +}; + +/* + * Get the Multiplier of the fine detunes of the voices + */ +REALTYPE ADnoteParameters::getBandwidthDetuneMultiplier(){ + REALTYPE bw=(GlobalPar.PBandwidth-64.0)/64.0; + bw=pow(2.0,bw*pow(fabs(bw),0.2)*5.0); + + return(bw); +}; + + +/* + * Kill the voice + */ +void ADnoteParameters::KillVoice(int nvoice){ + delete (VoicePar[nvoice].OscilSmp); + delete (VoicePar[nvoice].FMSmp); + + delete (VoicePar[nvoice].AmpEnvelope); + delete (VoicePar[nvoice].AmpLfo); + + delete (VoicePar[nvoice].FreqEnvelope); + delete (VoicePar[nvoice].FreqLfo); + + delete (VoicePar[nvoice].VoiceFilter); + delete (VoicePar[nvoice].FilterEnvelope); + delete (VoicePar[nvoice].FilterLfo); + + delete (VoicePar[nvoice].FMFreqEnvelope); + delete (VoicePar[nvoice].FMAmpEnvelope); +}; + +ADnoteParameters::~ADnoteParameters(){ + delete(GlobalPar.FreqEnvelope); + delete(GlobalPar.FreqLfo); + delete(GlobalPar.AmpEnvelope); + delete(GlobalPar.AmpLfo); + delete(GlobalPar.GlobalFilter); + delete(GlobalPar.FilterEnvelope); + delete(GlobalPar.FilterLfo); + delete(GlobalPar.Reson); + + for (int nvoice=0;nvoice=NUM_VOICES) return; + + int oscilused=0,fmoscilused=0;//if the oscil or fmoscil are used by another voice + + for (int i=0;iaddparbool("enabled",VoicePar[nvoice].Enabled); + if (((VoicePar[nvoice].Enabled==0)&&(oscilused==0)&&(fmoscilused==0))&&(xml->minimal)) return; + + xml->addpar("type",VoicePar[nvoice].Type); + xml->addpar("delay",VoicePar[nvoice].PDelay); + xml->addparbool("resonance",VoicePar[nvoice].Presonance); + + xml->addpar("ext_oscil",VoicePar[nvoice].Pextoscil); + xml->addpar("ext_fm_oscil",VoicePar[nvoice].PextFMoscil); + + xml->addpar("oscil_phase",VoicePar[nvoice].Poscilphase); + xml->addpar("oscil_fm_phase",VoicePar[nvoice].PFMoscilphase); + + xml->addparbool("filter_enabled",VoicePar[nvoice].PFilterEnabled); + xml->addparbool("filter_bypass",VoicePar[nvoice].Pfilterbypass); + + xml->addpar("fm_enabled",VoicePar[nvoice].PFMEnabled); + + xml->beginbranch("OSCIL"); + VoicePar[nvoice].OscilSmp->add2XML(xml); + xml->endbranch(); + + + xml->beginbranch("AMPLITUDE_PARAMETERS"); + xml->addpar("panning",VoicePar[nvoice].PPanning); + xml->addpar("volume",VoicePar[nvoice].PVolume); + xml->addparbool("volume_minus",VoicePar[nvoice].PVolumeminus); + xml->addpar("velocity_sensing",VoicePar[nvoice].PAmpVelocityScaleFunction); + + xml->addparbool("amp_envelope_enabled",VoicePar[nvoice].PAmpEnvelopeEnabled); + if ((VoicePar[nvoice].PAmpEnvelopeEnabled!=0)||(!xml->minimal)){ + xml->beginbranch("AMPLITUDE_ENVELOPE"); + VoicePar[nvoice].AmpEnvelope->add2XML(xml); + xml->endbranch(); + }; + xml->addparbool("amp_lfo_enabled",VoicePar[nvoice].PAmpLfoEnabled); + if ((VoicePar[nvoice].PAmpLfoEnabled!=0)||(!xml->minimal)){ + xml->beginbranch("AMPLITUDE_LFO"); + VoicePar[nvoice].AmpLfo->add2XML(xml); + xml->endbranch(); + }; + xml->endbranch(); + + xml->beginbranch("FREQUENCY_PARAMETERS"); + xml->addparbool("fixed_freq",VoicePar[nvoice].Pfixedfreq); + xml->addpar("fixed_freq_et",VoicePar[nvoice].PfixedfreqET); + xml->addpar("detune",VoicePar[nvoice].PDetune); + xml->addpar("coarse_detune",VoicePar[nvoice].PCoarseDetune); + xml->addpar("detune_type",VoicePar[nvoice].PDetuneType); + + xml->addparbool("freq_envelope_enabled",VoicePar[nvoice].PFreqEnvelopeEnabled); + if ((VoicePar[nvoice].PFreqEnvelopeEnabled!=0)||(!xml->minimal)){ + xml->beginbranch("FREQUENCY_ENVELOPE"); + VoicePar[nvoice].FreqEnvelope->add2XML(xml); + xml->endbranch(); + }; + xml->addparbool("freq_lfo_enabled",VoicePar[nvoice].PFreqLfoEnabled); + if ((VoicePar[nvoice].PFreqLfoEnabled!=0)||(!xml->minimal)){ + xml->beginbranch("FREQUENCY_LFO"); + VoicePar[nvoice].FreqLfo->add2XML(xml); + xml->endbranch(); + }; + xml->endbranch(); + + + if ((VoicePar[nvoice].PFilterEnabled!=0)||(!xml->minimal)){ + xml->beginbranch("FILTER_PARAMETERS"); + xml->beginbranch("FILTER"); + VoicePar[nvoice].VoiceFilter->add2XML(xml); + xml->endbranch(); + + xml->addparbool("filter_envelope_enabled",VoicePar[nvoice].PFilterEnvelopeEnabled); + if ((VoicePar[nvoice].PFilterEnvelopeEnabled!=0)||(!xml->minimal)){ + xml->beginbranch("FILTER_ENVELOPE"); + VoicePar[nvoice].FilterEnvelope->add2XML(xml); + xml->endbranch(); + }; + + xml->addparbool("filter_lfo_enabled",VoicePar[nvoice].PFilterLfoEnabled); + if ((VoicePar[nvoice].PFilterLfoEnabled!=0)||(!xml->minimal)){ + xml->beginbranch("FILTER_LFO"); + VoicePar[nvoice].FilterLfo->add2XML(xml); + xml->endbranch(); + }; + xml->endbranch(); + }; + + if ((VoicePar[nvoice].PFMEnabled!=0)||(fmoscilused!=0)||(!xml->minimal)){ + xml->beginbranch("FM_PARAMETERS"); + xml->addpar("input_voice",VoicePar[nvoice].PFMVoice); + + xml->addpar("volume",VoicePar[nvoice].PFMVolume); + xml->addpar("volume_damp",VoicePar[nvoice].PFMVolumeDamp); + xml->addpar("velocity_sensing",VoicePar[nvoice].PFMVelocityScaleFunction); + + xml->addparbool("amp_envelope_enabled",VoicePar[nvoice].PFMAmpEnvelopeEnabled); + if ((VoicePar[nvoice].PFMAmpEnvelopeEnabled!=0)||(!xml->minimal)){ + xml->beginbranch("AMPLITUDE_ENVELOPE"); + VoicePar[nvoice].FMAmpEnvelope->add2XML(xml); + xml->endbranch(); + }; + xml->beginbranch("MODULATOR"); + xml->addpar("detune",VoicePar[nvoice].PFMDetune); + xml->addpar("coarse_detune",VoicePar[nvoice].PFMCoarseDetune); + xml->addpar("detune_type",VoicePar[nvoice].PFMDetuneType); + + xml->addparbool("freq_envelope_enabled",VoicePar[nvoice].PFMFreqEnvelopeEnabled); + if ((VoicePar[nvoice].PFMFreqEnvelopeEnabled!=0)||(!xml->minimal)){ + xml->beginbranch("FREQUENCY_ENVELOPE"); + VoicePar[nvoice].FMFreqEnvelope->add2XML(xml); + xml->endbranch(); + }; + + xml->beginbranch("OSCIL"); + VoicePar[nvoice].FMSmp->add2XML(xml); + xml->endbranch(); + + xml->endbranch(); + xml->endbranch(); + }; +}; + + +void ADnoteParameters::add2XML(XMLwrapper *xml){ + xml->addparbool("stereo",GlobalPar.PStereo); + + xml->beginbranch("AMPLITUDE_PARAMETERS"); + xml->addpar("volume",GlobalPar.PVolume); + xml->addpar("panning",GlobalPar.PPanning); + xml->addpar("velocity_sensing",GlobalPar.PAmpVelocityScaleFunction); + xml->addpar("punch_strength",GlobalPar.PPunchStrength); + xml->addpar("punch_time",GlobalPar.PPunchTime); + xml->addpar("punch_stretch",GlobalPar.PPunchStretch); + xml->addpar("punch_velocity_sensing",GlobalPar.PPunchVelocitySensing); + xml->addpar("harmonic_randomness_grouping",GlobalPar.Hrandgrouping); + + xml->beginbranch("AMPLITUDE_ENVELOPE"); + GlobalPar.AmpEnvelope->add2XML(xml); + xml->endbranch(); + + xml->beginbranch("AMPLITUDE_LFO"); + GlobalPar.AmpLfo->add2XML(xml); + xml->endbranch(); + xml->endbranch(); + + xml->beginbranch("FREQUENCY_PARAMETERS"); + xml->addpar("detune",GlobalPar.PDetune); + + xml->addpar("coarse_detune",GlobalPar.PCoarseDetune); + xml->addpar("detune_type",GlobalPar.PDetuneType); + + xml->addpar("bandwidth",GlobalPar.PBandwidth); + + xml->beginbranch("FREQUENCY_ENVELOPE"); + GlobalPar.FreqEnvelope->add2XML(xml); + xml->endbranch(); + + xml->beginbranch("FREQUENCY_LFO"); + GlobalPar.FreqLfo->add2XML(xml); + xml->endbranch(); + xml->endbranch(); + + + xml->beginbranch("FILTER_PARAMETERS"); + xml->addpar("velocity_sensing_amplitude",GlobalPar.PFilterVelocityScale); + xml->addpar("velocity_sensing",GlobalPar.PFilterVelocityScaleFunction); + + xml->beginbranch("FILTER"); + GlobalPar.GlobalFilter->add2XML(xml); + xml->endbranch(); + + xml->beginbranch("FILTER_ENVELOPE"); + GlobalPar.FilterEnvelope->add2XML(xml); + xml->endbranch(); + + xml->beginbranch("FILTER_LFO"); + GlobalPar.FilterLfo->add2XML(xml); + xml->endbranch(); + xml->endbranch(); + + xml->beginbranch("RESONANCE"); + GlobalPar.Reson->add2XML(xml); + xml->endbranch(); + + for (int nvoice=0;nvoicebeginbranch("VOICE",nvoice); + add2XMLsection(xml,nvoice); + xml->endbranch(); + }; +}; + + +void ADnoteParameters::getfromXML(XMLwrapper *xml){ + GlobalPar.PStereo=xml->getparbool("stereo",GlobalPar.PStereo); + + if (xml->enterbranch("AMPLITUDE_PARAMETERS")){ + GlobalPar.PVolume=xml->getpar127("volume",GlobalPar.PVolume); + GlobalPar.PPanning=xml->getpar127("panning",GlobalPar.PPanning); + GlobalPar.PAmpVelocityScaleFunction=xml->getpar127("velocity_sensing",GlobalPar.PAmpVelocityScaleFunction); + + GlobalPar.PPunchStrength=xml->getpar127("punch_strength",GlobalPar.PPunchStrength); + GlobalPar.PPunchTime=xml->getpar127("punch_time",GlobalPar.PPunchTime); + GlobalPar.PPunchStretch=xml->getpar127("punch_stretch",GlobalPar.PPunchStretch); + GlobalPar.PPunchVelocitySensing=xml->getpar127("punch_velocity_sensing",GlobalPar.PPunchVelocitySensing); + GlobalPar.Hrandgrouping=xml->getpar127("harmonic_randomness_grouping",GlobalPar.Hrandgrouping); + + if (xml->enterbranch("AMPLITUDE_ENVELOPE")){ + GlobalPar.AmpEnvelope->getfromXML(xml); + xml->exitbranch(); + }; + + if (xml->enterbranch("AMPLITUDE_LFO")){ + GlobalPar.AmpLfo->getfromXML(xml); + xml->exitbranch(); + }; + + xml->exitbranch(); + }; + + if (xml->enterbranch("FREQUENCY_PARAMETERS")){ + GlobalPar.PDetune=xml->getpar("detune",GlobalPar.PDetune,0,16383); + GlobalPar.PCoarseDetune=xml->getpar("coarse_detune",GlobalPar.PCoarseDetune,0,16383); + GlobalPar.PDetuneType=xml->getpar127("detune_type",GlobalPar.PDetuneType); + + GlobalPar.PBandwidth=xml->getpar127("bandwidth",GlobalPar.PBandwidth); + + xml->enterbranch("FREQUENCY_ENVELOPE"); + GlobalPar.FreqEnvelope->getfromXML(xml); + xml->exitbranch(); + + xml->enterbranch("FREQUENCY_LFO"); + GlobalPar.FreqLfo->getfromXML(xml); + xml->exitbranch(); + + xml->exitbranch(); + }; + + + if (xml->enterbranch("FILTER_PARAMETERS")){ + GlobalPar.PFilterVelocityScale=xml->getpar127("velocity_sensing_amplitude",GlobalPar.PFilterVelocityScale); + GlobalPar.PFilterVelocityScaleFunction=xml->getpar127("velocity_sensing",GlobalPar.PFilterVelocityScaleFunction); + + xml->enterbranch("FILTER"); + GlobalPar.GlobalFilter->getfromXML(xml); + xml->exitbranch(); + + xml->enterbranch("FILTER_ENVELOPE"); + GlobalPar.FilterEnvelope->getfromXML(xml); + xml->exitbranch(); + + xml->enterbranch("FILTER_LFO"); + GlobalPar.FilterLfo->getfromXML(xml); + xml->exitbranch(); + xml->exitbranch(); + }; + + if (xml->enterbranch("RESONANCE")){ + GlobalPar.Reson->getfromXML(xml); + xml->exitbranch(); + }; + + for (int nvoice=0;nvoiceenterbranch("VOICE",nvoice)==0) continue; + getfromXMLsection(xml,nvoice); + xml->exitbranch(); + }; + + +}; + +void ADnoteParameters::getfromXMLsection(XMLwrapper *xml,int n){ + int nvoice=n; + if (nvoice>=NUM_VOICES) return; + + VoicePar[nvoice].Enabled=xml->getparbool("enabled",0); + + VoicePar[nvoice].Type=xml->getpar127("type",VoicePar[nvoice].Type); + VoicePar[nvoice].PDelay=xml->getpar127("delay",VoicePar[nvoice].PDelay); + VoicePar[nvoice].Presonance=xml->getparbool("resonance",VoicePar[nvoice].Presonance); + + VoicePar[nvoice].Pextoscil=xml->getpar("ext_oscil",-1,-1,nvoice-1); + VoicePar[nvoice].PextFMoscil=xml->getpar("ext_fm_oscil",-1,-1,nvoice-1); + + VoicePar[nvoice].Poscilphase=xml->getpar127("oscil_phase",VoicePar[nvoice].Poscilphase); + VoicePar[nvoice].PFMoscilphase=xml->getpar127("oscil_fm_phase",VoicePar[nvoice].PFMoscilphase); + + VoicePar[nvoice].PFilterEnabled=xml->getparbool("filter_enabled",VoicePar[nvoice].PFilterEnabled); + VoicePar[nvoice].Pfilterbypass=xml->getparbool("filter_bypass",VoicePar[nvoice].Pfilterbypass); + + VoicePar[nvoice].PFMEnabled=xml->getpar127("fm_enabled",VoicePar[nvoice].PFMEnabled); + + if (xml->enterbranch("OSCIL")){ + VoicePar[nvoice].OscilSmp->getfromXML(xml); + xml->exitbranch(); + }; + + + if (xml->enterbranch("AMPLITUDE_PARAMETERS")){ + VoicePar[nvoice].PPanning=xml->getpar127("panning",VoicePar[nvoice].PPanning); + VoicePar[nvoice].PVolume=xml->getpar127("volume",VoicePar[nvoice].PVolume); + VoicePar[nvoice].PVolumeminus=xml->getparbool("volume_minus",VoicePar[nvoice].PVolumeminus); + VoicePar[nvoice].PAmpVelocityScaleFunction=xml->getpar127("velocity_sensing",VoicePar[nvoice].PAmpVelocityScaleFunction); + + VoicePar[nvoice].PAmpEnvelopeEnabled=xml->getparbool("amp_envelope_enabled",VoicePar[nvoice].PAmpEnvelopeEnabled); + if (xml->enterbranch("AMPLITUDE_ENVELOPE")){ + VoicePar[nvoice].AmpEnvelope->getfromXML(xml); + xml->exitbranch(); + }; + + VoicePar[nvoice].PAmpLfoEnabled=xml->getparbool("amp_lfo_enabled",VoicePar[nvoice].PAmpLfoEnabled); + if (xml->enterbranch("AMPLITUDE_LFO")){ + VoicePar[nvoice].AmpLfo->getfromXML(xml); + xml->exitbranch(); + }; + xml->exitbranch(); + }; + + if (xml->enterbranch("FREQUENCY_PARAMETERS")){ + VoicePar[nvoice].Pfixedfreq=xml->getparbool("fixed_freq",VoicePar[nvoice].Pfixedfreq); + VoicePar[nvoice].PfixedfreqET=xml->getpar127("fixed_freq_et",VoicePar[nvoice].PfixedfreqET); + + + VoicePar[nvoice].PDetune=xml->getpar("detune",VoicePar[nvoice].PDetune,0,16383); + + VoicePar[nvoice].PCoarseDetune=xml->getpar("coarse_detune",VoicePar[nvoice].PCoarseDetune,0,16383); + VoicePar[nvoice].PDetuneType=xml->getpar127("detune_type",VoicePar[nvoice].PDetuneType); + + VoicePar[nvoice].PFreqEnvelopeEnabled=xml->getparbool("freq_envelope_enabled",VoicePar[nvoice].PFreqEnvelopeEnabled); + if (xml->enterbranch("FREQUENCY_ENVELOPE")){ + VoicePar[nvoice].FreqEnvelope->getfromXML(xml); + xml->exitbranch(); + }; + + VoicePar[nvoice].PFreqLfoEnabled=xml->getparbool("freq_lfo_enabled",VoicePar[nvoice].PFreqLfoEnabled); + if (xml->enterbranch("FREQUENCY_LFO")){ + VoicePar[nvoice].FreqLfo->getfromXML(xml); + xml->exitbranch(); + }; + xml->exitbranch(); + }; + + if (xml->enterbranch("FILTER_PARAMETERS")){ + if (xml->enterbranch("FILTER")){ + VoicePar[nvoice].VoiceFilter->getfromXML(xml); + xml->exitbranch(); + }; + + VoicePar[nvoice].PFilterEnvelopeEnabled=xml->getparbool("filter_envelope_enabled",VoicePar[nvoice].PFilterEnvelopeEnabled); + if (xml->enterbranch("FILTER_ENVELOPE")){ + VoicePar[nvoice].FilterEnvelope->getfromXML(xml); + xml->exitbranch(); + }; + + VoicePar[nvoice].PFilterLfoEnabled=xml->getparbool("filter_lfo_enabled",VoicePar[nvoice].PFilterLfoEnabled); + if (xml->enterbranch("FILTER_LFO")){ + VoicePar[nvoice].FilterLfo->getfromXML(xml); + xml->exitbranch(); + }; + xml->exitbranch(); + }; + + if (xml->enterbranch("FM_PARAMETERS")){ + VoicePar[nvoice].PFMVoice=xml->getpar("input_voice",VoicePar[nvoice].PFMVoice,-1,nvoice-1); + + VoicePar[nvoice].PFMVolume=xml->getpar127("volume",VoicePar[nvoice].PFMVolume); + VoicePar[nvoice].PFMVolumeDamp=xml->getpar127("volume_damp",VoicePar[nvoice].PFMVolumeDamp); + VoicePar[nvoice].PFMVelocityScaleFunction=xml->getpar127("velocity_sensing",VoicePar[nvoice].PFMVelocityScaleFunction); + + VoicePar[nvoice].PFMAmpEnvelopeEnabled=xml->getparbool("amp_envelope_enabled",VoicePar[nvoice].PFMAmpEnvelopeEnabled); + if (xml->enterbranch("AMPLITUDE_ENVELOPE")){ + VoicePar[nvoice].FMAmpEnvelope->getfromXML(xml); + xml->exitbranch(); + }; + + if (xml->enterbranch("MODULATOR")){ + VoicePar[nvoice].PFMDetune=xml->getpar("detune",VoicePar[nvoice].PFMDetune,0,16383); + VoicePar[nvoice].PFMCoarseDetune=xml->getpar("coarse_detune",VoicePar[nvoice].PFMCoarseDetune,0,16383); + VoicePar[nvoice].PFMDetuneType=xml->getpar127("detune_type",VoicePar[nvoice].PFMDetuneType); + + VoicePar[nvoice].PFMFreqEnvelopeEnabled=xml->getparbool("freq_envelope_enabled",VoicePar[nvoice].PFMFreqEnvelopeEnabled); + if (xml->enterbranch("FREQUENCY_ENVELOPE")){ + VoicePar[nvoice].FMFreqEnvelope->getfromXML(xml); + xml->exitbranch(); + }; + + if (xml->enterbranch("OSCIL")){ + VoicePar[nvoice].FMSmp->getfromXML(xml); + xml->exitbranch(); + }; + + xml->exitbranch(); + }; + xml->exitbranch(); + }; +}; + + diff --git a/plugins/zynaddsubfx/src/Params/ADnoteParameters.h b/plugins/zynaddsubfx/src/Params/ADnoteParameters.h new file mode 100644 index 000000000..c1c765a07 --- /dev/null +++ b/plugins/zynaddsubfx/src/Params/ADnoteParameters.h @@ -0,0 +1,282 @@ +/* + ZynAddSubFX - a software synthesizer + + ADnoteParameters.h - Parameters for ADnote (ADsynth) + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef AD_NOTE_PARAMETERS_H +#define AD_NOTE_PARAMETERS_H + + +#include "../globals.h" +#include "EnvelopeParams.h" +#include "LFOParams.h" +#include "FilterParams.h" +#include "../Synth/OscilGen.h" +#include "../Synth/Resonance.h" +#include "../Misc/Util.h" +#include "../Misc/XMLwrapper.h" +#include "../DSP/FFTwrapper.h" +#include "Presets.h" + + enum FMTYPE{NONE,MORPH,RING_MOD,PHASE_MOD,FREQ_MOD,PITCH_MOD}; + + /*****************************************************************/ + /* GLOBAL PARAMETERS */ + /*****************************************************************/ + + struct ADnoteGlobalParam{ + + /* The instrument type - MONO/STEREO + If the mode is MONO, the panning of voices are not used + Stereo=1, Mono=0. */ + + unsigned char PStereo; + + + /****************************************** + * FREQUENCY GLOBAL PARAMETERS * + ******************************************/ + unsigned short int PDetune;//fine detune + unsigned short int PCoarseDetune;//coarse detune+octave + unsigned char PDetuneType;//detune type + + unsigned char PBandwidth;//how much the relative fine detunes of the voices are changed + + EnvelopeParams *FreqEnvelope; //Frequency Envelope + + LFOParams *FreqLfo;//Frequency LFO + + /******************************************** + * AMPLITUDE GLOBAL PARAMETERS * + ********************************************/ + + /* Panning - 0 - random + 1 - left + 64 - center + 127 - right */ + unsigned char PPanning; + + unsigned char PVolume; + + unsigned char PAmpVelocityScaleFunction; + + EnvelopeParams *AmpEnvelope; + + LFOParams *AmpLfo; + + unsigned char PPunchStrength,PPunchTime,PPunchStretch,PPunchVelocitySensing; + + /****************************************** + * FILTER GLOBAL PARAMETERS * + ******************************************/ + FilterParams *GlobalFilter; + + // filter velocity sensing + unsigned char PFilterVelocityScale; + + // filter velocity sensing + unsigned char PFilterVelocityScaleFunction; + + EnvelopeParams *FilterEnvelope; + + LFOParams *FilterLfo; + + // RESONANCE + Resonance *Reson; + + //how the randomness is applied to the harmonics on more voices using the same oscillator + unsigned char Hrandgrouping; + }; + + + + /***********************************************************/ + /* VOICE PARAMETERS */ + /***********************************************************/ + struct ADnoteVoiceParam{ + + /* If the voice is enabled */ + unsigned char Enabled; + + /* Type of the voice (0=Sound,1=Noise)*/ + unsigned char Type; + + /* Voice Delay */ + unsigned char PDelay; + + /* If the resonance is enabled for this voice */ + unsigned char Presonance; + + // What external oscil should I use, -1 for internal OscilSmp&FMSmp + short int Pextoscil,PextFMoscil; + // it is not allowed that the externoscil,externFMoscil => current voice + + // oscillator phases + unsigned char Poscilphase,PFMoscilphase; + + // filter bypass + unsigned char Pfilterbypass; + + /* Voice oscillator */ + OscilGen *OscilSmp; + + /********************************** + * FREQUENCY PARAMETERS * + **********************************/ + + /* If the base frequency is fixed to 440 Hz*/ + unsigned char Pfixedfreq; + + /* Equal temperate (this is used only if the Pfixedfreq is enabled) + If this parameter is 0, the frequency is fixed (to 440 Hz); + if this parameter is 64, 1 MIDI halftone -> 1 frequency halftone */ + unsigned char PfixedfreqET; + + /* Fine detune */ + unsigned short int PDetune; + + /* Coarse detune + octave */ + unsigned short int PCoarseDetune; + + /* Detune type */ + unsigned char PDetuneType; + + /* Frequency Envelope */ + unsigned char PFreqEnvelopeEnabled; + EnvelopeParams *FreqEnvelope; + + /* Frequency LFO */ + unsigned char PFreqLfoEnabled; + LFOParams *FreqLfo; + + + /*************************** + * AMPLITUDE PARAMETERS * + ***************************/ + + /* Panning 0 - random + 1 - left + 64 - center + 127 - right + The Panning is ignored if the instrument is mono */ + unsigned char PPanning; + + /* Voice Volume */ + unsigned char PVolume; + + /* If the Volume negative */ + unsigned char PVolumeminus; + + /* Velocity sensing */ + unsigned char PAmpVelocityScaleFunction; + + /* Amplitude Envelope */ + unsigned char PAmpEnvelopeEnabled; + EnvelopeParams *AmpEnvelope; + + /* Amplitude LFO */ + unsigned char PAmpLfoEnabled; + LFOParams *AmpLfo; + + + + /************************* + * FILTER PARAMETERS * + *************************/ + + /* Voice Filter */ + unsigned char PFilterEnabled; + FilterParams *VoiceFilter; + + /* Filter Envelope */ + unsigned char PFilterEnvelopeEnabled; + EnvelopeParams *FilterEnvelope; + + /* LFO Envelope */ + unsigned char PFilterLfoEnabled; + LFOParams *FilterLfo; + + /**************************** + * MODULLATOR PARAMETERS * + ****************************/ + + /* Modullator Parameters (0=off,1=Morph,2=RM,3=PM,4=FM.. */ + unsigned char PFMEnabled; + + /* Voice that I use as modullator instead of FMSmp. + It is -1 if I use FMSmp(default). + It maynot be equal or bigger than current voice */ + short int PFMVoice; + + /* Modullator oscillator */ + OscilGen *FMSmp; + + /* Modullator Volume */ + unsigned char PFMVolume; + + /* Modullator damping at higher frequencies */ + unsigned char PFMVolumeDamp; + + /* Modullator Velocity Sensing */ + unsigned char PFMVelocityScaleFunction; + + /* Fine Detune of the Modullator*/ + unsigned short int PFMDetune; + + /* Coarse Detune of the Modullator */ + unsigned short int PFMCoarseDetune; + + /* The detune type */ + unsigned char PFMDetuneType; + + /* Frequency Envelope of the Modullator */ + unsigned char PFMFreqEnvelopeEnabled; + EnvelopeParams *FMFreqEnvelope; + + /* Frequency Envelope of the Modullator */ + unsigned char PFMAmpEnvelopeEnabled; + EnvelopeParams *FMAmpEnvelope; + }; + +class ADnoteParameters:public Presets{ + public: + ADnoteParameters(FFTwrapper *fft_); + ~ADnoteParameters(); + + ADnoteGlobalParam GlobalPar; + ADnoteVoiceParam VoicePar[NUM_VOICES]; + + void defaults(); + void add2XML(XMLwrapper *xml); + void getfromXML(XMLwrapper *xml); + + REALTYPE getBandwidthDetuneMultiplier(); + private: + void defaults(int n);//n is the nvoice + + void EnableVoice(int nvoice); + void KillVoice(int nvoice); + FFTwrapper *fft; + + void add2XMLsection(XMLwrapper *xml,int n); + void getfromXMLsection(XMLwrapper *xml,int n); +}; + +#endif diff --git a/plugins/zynaddsubfx/src/Params/Controller.C b/plugins/zynaddsubfx/src/Params/Controller.C new file mode 100644 index 000000000..754541510 --- /dev/null +++ b/plugins/zynaddsubfx/src/Params/Controller.C @@ -0,0 +1,308 @@ +/* + ZynAddSubFX - a software synthesizer + + Controller.C - (Midi) Controllers implementation + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include "Controller.h" +#include +#include + +Controller::Controller(){ + defaults(); + resetall(); +}; + +Controller::~Controller(){ +}; + +void Controller::defaults(){ + setpitchwheelbendrange(200);//2 halftones + expression.receive=1; + panning.depth=64; + filtercutoff.depth=64; + filterq.depth=64; + bandwidth.depth=64; + bandwidth.exponential=0; + modwheel.depth=80; + modwheel.exponential=0; + fmamp.receive=1; + volume.receive=0; + sustain.receive=1; + NRPN.receive=1; + + portamento.portamento=0; + portamento.used=0; + portamento.receive=1; + portamento.time=64; + portamento.updowntimestretch=64; + portamento.pitchthresh=3; + portamento.pitchthreshtype=1; + portamento.noteusing=-1; + resonancecenter.depth=64; + resonancebandwidth.depth=64; + + initportamento(440.0,440.0,false); // Now has a third argument + setportamento(0); + +}; + +void Controller::resetall(){ + setpitchwheel(0);//center + setexpression(127); + setpanning(64); + setfiltercutoff(64); + setfilterq(64); + setbandwidth(64); + setmodwheel(64); + setfmamp(127); + setvolume(127); + setsustain(0); + setresonancecenter(64); + setresonancebw(64); + + //reset the NRPN + NRPN.parhi=-1; + NRPN.parlo=-1; + NRPN.valhi=-1; + NRPN.vallo=-1; +}; + +void Controller::setpitchwheel(int value){ + pitchwheel.data=value; + REALTYPE cents=value/8192.0; + cents*=pitchwheel.bendrange; + pitchwheel.relfreq=pow(2,cents/1200.0); + //fprintf(stderr,"%ld %ld -> %.3f\n",pitchwheel.bendrange,pitchwheel.data,pitchwheel.relfreq);fflush(stderr); +}; + +void Controller::setpitchwheelbendrange(unsigned short int value){ + pitchwheel.bendrange=value; +}; + +void Controller::setexpression(int value){ + expression.data=value; + if (expression.receive!=0) expression.relvolume=value/127.0; + else expression.relvolume=1.0; +}; + +void Controller::setpanning(int value){ + panning.data=value; + panning.pan=(value/128.0-0.5)*(panning.depth/64.0); +}; + +void Controller::setfiltercutoff(int value){ + filtercutoff.data=value; + filtercutoff.relfreq=(value-64.0)*filtercutoff.depth/4096.0*3.321928;//3.3219..=ln2(10) +}; + +void Controller::setfilterq(int value){ + filterq.data=value; + filterq.relq=pow(30.0,(value-64.0)/64.0*(filterq.depth/64.0)); +}; + +void Controller::setbandwidth(int value){ + bandwidth.data=value; + if (bandwidth.exponential==0) { + REALTYPE tmp=pow(25.0,pow(bandwidth.depth/127.0,1.5))-1.0; + if ((value<64)&&(bandwidth.depth>=64)) tmp=1.0; + bandwidth.relbw=(value/64.0-1.0)*tmp+1.0; + if (bandwidth.relbw<0.01) bandwidth.relbw=0.01; + } else { + bandwidth.relbw=pow(25.0,(value-64.0)/64.0*(bandwidth.depth/64.0)); + }; +}; + +void Controller::setmodwheel(int value){ + modwheel.data=value; + if (modwheel.exponential==0) { + REALTYPE tmp=pow(25.0,pow(modwheel.depth/127.0,1.5)*2.0)/25.0; + if ((value<64)&&(modwheel.depth>=64)) tmp=1.0; + modwheel.relmod=(value/64.0-1.0)*tmp+1.0; + if (modwheel.relmod<0.0) modwheel.relmod=0.0; + } else modwheel.relmod=pow(25.0,(value-64.0)/64.0*(modwheel.depth/80.0)); +}; + +void Controller::setfmamp(int value){ + fmamp.data=value; + fmamp.relamp=value/127.0; + if (fmamp.receive!=0) fmamp.relamp=value/127.0; + else fmamp.relamp=1.0; +}; + +void Controller::setvolume(int value){ + volume.data=value; + if (volume.receive!=0) volume.volume=pow(0.1,(127-value)/127.0*2.0); + else volume.volume=1.0; +}; + +void Controller::setsustain(int value){ + sustain.data=value; + if (sustain.receive!=0) sustain.sustain=((value<64) ? 0 : 1 ); + else sustain.sustain=0; +}; + +void Controller::setportamento(int value){ + portamento.data=value; + if (portamento.receive!=0) portamento.portamento=((value<64) ? 0 : 1 ); +}; + +// I added a third argument to pass legato status, +// when legatoflag is true it means "there's a legato in progress". +int Controller::initportamento(REALTYPE oldfreq,REALTYPE newfreq,bool legatoflag){ + portamento.x=0.0; + + if (legatoflag){ // Legato in progress + if (portamento.portamento==0) return(0); + } else { // No legato, do the original if...return + if ((portamento.used!=0) || (portamento.portamento==0)) return(0); + }; + + REALTYPE portamentotime=pow(100.0,portamento.time/127.0)/50.0;//portamento time in seconds + + if ((portamento.updowntimestretch>=64)&&(newfreqoldfreq)){ + if (portamento.updowntimestretch==0) return(0); + portamentotime*=pow(0.1,(64.0-portamento.updowntimestretch)/64.0); + }; + + portamento.dx=SOUND_BUFFER_SIZE/(portamentotime*SAMPLE_RATE); + portamento.origfreqrap=oldfreq/newfreq; + + REALTYPE tmprap=( (portamento.origfreqrap>1.0) ? + (portamento.origfreqrap) : + (1.0/portamento.origfreqrap) ); + + REALTYPE thresholdrap=pow(2.0,portamento.pitchthresh/12.0); + if ((portamento.pitchthreshtype==0) && (tmprap-0.00001>thresholdrap) ) return(0); + if ((portamento.pitchthreshtype==1) && (tmprap+0.000011.0) { + portamento.x=1.0; + portamento.used=0; + }; + portamento.freqrap=(1.0-portamento.x)*portamento.origfreqrap+portamento.x; +}; + + +void Controller::setresonancecenter(int value){ + resonancecenter.data=value; + resonancecenter.relcenter=pow(3.0,(value-64.0)/64.0*(resonancecenter.depth/64.0)); +}; +void Controller::setresonancebw(int value){ + resonancebandwidth.data=value; + resonancebandwidth.relbw=pow(1.5,(value-64.0)/64.0*(resonancebandwidth.depth/127.0)); +}; + + +//Returns 0 if there is NRPN or 1 if there is not +int Controller::getnrpn(int *parhi, int *parlo, int *valhi, int *vallo){ + if (NRPN.receive==0) return(1); + if ((NRPN.parhi<0)||(NRPN.parlo<0)||(NRPN.valhi<0)||(NRPN.vallo<0)) + return(1); + + *parhi=NRPN.parhi; + *parlo=NRPN.parlo; + *valhi=NRPN.valhi; + *vallo=NRPN.vallo; + return(0); +}; + + +void Controller::setparameternumber(unsigned int type,int value){ + switch(type){ + case C_nrpnhi:NRPN.parhi=value; + NRPN.valhi=-1;NRPN.vallo=-1;//clear the values + break; + case C_nrpnlo:NRPN.parlo=value; + NRPN.valhi=-1;NRPN.vallo=-1;//clear the values + break; + case C_dataentryhi:if ((NRPN.parhi>=0)&&(NRPN.parlo>=0)) NRPN.valhi=value; + break; + case C_dataentrylo:if ((NRPN.parhi>=0)&&(NRPN.parlo>=0)) NRPN.vallo=value; + break; + }; +}; + + + +void Controller::add2XML(XMLwrapper *xml){ + xml->addpar("pitchwheel_bendrange",pitchwheel.bendrange); + + xml->addparbool("expression_receive",expression.receive); + xml->addpar("panning_depth",panning.depth); + xml->addpar("filter_cutoff_depth",filtercutoff.depth); + xml->addpar("filter_q_depth",filterq.depth); + xml->addpar("bandwidth_depth",bandwidth.depth); + xml->addpar("mod_wheel_depth",modwheel.depth); + xml->addparbool("mod_wheel_exponential",modwheel.exponential); + xml->addparbool("fm_amp_receive",fmamp.receive); + xml->addparbool("volume_receive",volume.receive); + xml->addparbool("sustain_receive",sustain.receive); + + xml->addparbool("portamento_receive",portamento.receive); + xml->addpar("portamento_time",portamento.time); + xml->addpar("portamento_pitchthresh",portamento.pitchthresh); + xml->addpar("portamento_pitchthreshtype",portamento.pitchthreshtype); + xml->addpar("portamento_portamento",portamento.portamento); + xml->addpar("portamento_updowntimestretch",portamento.updowntimestretch); + + xml->addpar("resonance_center_depth",resonancecenter.depth); + xml->addpar("resonance_bandwidth_depth",resonancebandwidth.depth); +}; + +void Controller::getfromXML(XMLwrapper *xml){ + pitchwheel.bendrange=xml->getpar("pitchwheel_bendrange",pitchwheel.bendrange,-6400,6400); + + expression.receive=xml->getparbool("expression_receive",expression.receive); + panning.depth=xml->getpar127("panning_depth",panning.depth); + filtercutoff.depth=xml->getpar127("filter_cutoff_depth",filtercutoff.depth); + filterq.depth=xml->getpar127("filter_q_depth",filterq.depth); + bandwidth.depth=xml->getpar127("bandwidth_depth",bandwidth.depth); + modwheel.depth=xml->getpar127("mod_wheel_depth",modwheel.depth); + modwheel.exponential=xml->getparbool("mod_wheel_exponential",modwheel.exponential); + fmamp.receive=xml->getparbool("fm_amp_receive",fmamp.receive); + volume.receive=xml->getparbool("volume_receive",volume.receive); + sustain.receive=xml->getparbool("sustain_receive",sustain.receive); + + portamento.receive=xml->getparbool("portamento_receive",portamento.receive); + portamento.time=xml->getpar127("portamento_time",portamento.time); + portamento.pitchthresh=xml->getpar127("portamento_pitchthresh",portamento.pitchthresh); + portamento.pitchthreshtype=xml->getpar127("portamento_pitchthreshtype",portamento.pitchthreshtype); + portamento.portamento=xml->getpar127("portamento_portamento",portamento.portamento); + portamento.updowntimestretch=xml->getpar127("portamento_updowntimestretch",portamento.updowntimestretch); + + resonancecenter.depth=xml->getpar127("resonance_center_depth",resonancecenter.depth); + resonancebandwidth.depth=xml->getpar127("resonance_bandwidth_depth",resonancebandwidth.depth); +}; + + + diff --git a/plugins/zynaddsubfx/src/Params/Controller.h b/plugins/zynaddsubfx/src/Params/Controller.h new file mode 100644 index 000000000..cdf629781 --- /dev/null +++ b/plugins/zynaddsubfx/src/Params/Controller.h @@ -0,0 +1,179 @@ +/* + ZynAddSubFX - a software synthesizer + + Controller.h - (Midi) Controllers implementation + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + + +#ifndef CONTROLLER_H +#define CONTROLLER_H + +#include "../globals.h" +#include "../Misc/XMLwrapper.h" + +class Controller{ + public: + Controller(); + ~Controller(); + void resetall(); + + void add2XML(XMLwrapper *xml); + void defaults(); + void getfromXML(XMLwrapper *xml); + + //Controllers functions + void setpitchwheel(int value); + void setpitchwheelbendrange(unsigned short int value); + void setexpression(int value); + void setpanning(int value); + void setfiltercutoff(int value); + void setfilterq(int value); + void setbandwidth(int value); + void setmodwheel(int value); + void setfmamp(int value); + void setvolume(int value); + void setsustain(int value); + void setportamento(int value); + void setresonancecenter(int value); + void setresonancebw(int value); + + + void setparameternumber(unsigned int type,int value);//used for RPN and NRPN's + int getnrpn(int *parhi, int *parlo, int *valhi, int *vallo); + + int initportamento(REALTYPE oldfreq,REALTYPE newfreq,bool legatoflag);//returns 1 if the portamento's conditions are true, else return 0 + void updateportamento(); //update portamento values + + // Controllers values + struct {//Pitch Wheel + int data; + short int bendrange;//bendrange is in cents + REALTYPE relfreq;//the relative frequency (default is 1.0) + } pitchwheel; + + struct{//Expression + int data; + REALTYPE relvolume; + unsigned char receive; + } expression; + + struct{//Panning + int data; + REALTYPE pan; + unsigned char depth; + } panning; + + + struct{//Filter cutoff + int data; + REALTYPE relfreq; + unsigned char depth; + } filtercutoff; + + struct{//Filter Q + int data; + REALTYPE relq; + unsigned char depth; + } filterq; + + struct{//Bandwidth + int data; + REALTYPE relbw; + unsigned char depth; + unsigned char exponential; + } bandwidth; + + struct {//Modulation Wheel + int data; + REALTYPE relmod; + unsigned char depth; + unsigned char exponential; + } modwheel; + + struct{//FM amplitude + int data; + REALTYPE relamp; + unsigned char receive; + } fmamp; + + struct{//Volume + int data; + REALTYPE volume; + unsigned char receive; + } volume; + + struct{//Sustain + int data,sustain; + unsigned char receive; + } sustain; + + struct{//Portamento + //parameters + int data; + unsigned char portamento; + + //pitchthresh is the threshold of enabling protamento + //pitchthreshtype -> enable the portamento only below(0)/above(1) the threshold + unsigned char receive,time,pitchthresh,pitchthreshtype; + + //'up portanemto' means when the frequency is rising (eg: the portamento is from 200Hz to 300 Hz) + //'down portanemto' means when the frequency is lowering (eg: the portamento is from 300Hz to 200 Hz) + unsigned char updowntimestretch;//this value represent how the portamento time is reduced + //0 - for down portamento, 1..63 - the up portamento's time is smaller than the down portamento + //64 - the portamento time is always the same + //64-126 - the down portamento's time is smaller than the up portamento + //127 - for upper portamento + + REALTYPE freqrap;//this value is used to compute the actual portamento + int noteusing;//this is used by the Part:: for knowing which note uses the portamento + int used;//if a the portamento is used by a note + //internal data + REALTYPE x,dx;//x is from 0.0 (start portamento) to 1.0 (finished portamento), dx is x increment + REALTYPE origfreqrap;// this is used for computing oldfreq value from x + } portamento; + + struct{//Resonance Center Frequency + int data; + REALTYPE relcenter; + unsigned char depth; + } resonancecenter; + + struct{//Resonance Bandwidth + int data; + REALTYPE relbw; + unsigned char depth; + } resonancebandwidth; + + + /* RPN and NPRPN */ + struct{//nrpn + int parhi,parlo; + int valhi,vallo; + unsigned char receive;//this is saved to disk by Master + } NRPN; + + private: +}; + + + + + +#endif + diff --git a/plugins/zynaddsubfx/src/Params/EnvelopeParams.C b/plugins/zynaddsubfx/src/Params/EnvelopeParams.C new file mode 100644 index 000000000..54cb3d95a --- /dev/null +++ b/plugins/zynaddsubfx/src/Params/EnvelopeParams.C @@ -0,0 +1,227 @@ +/* + ZynAddSubFX - a software synthesizer + + EnvelopeParams.C - Parameters for Envelope + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include + +#include +#include +#include "EnvelopeParams.h" + +EnvelopeParams::EnvelopeParams(unsigned char Penvstretch_,unsigned char Pforcedrelease_):Presets(){ + int i; + + PA_dt=10;PD_dt=10;PR_dt=10;PA_val=64;PD_val=64;PS_val=64;PR_val=64; + + for (i=0;iaddparbool("free_mode",Pfreemode); + xml->addpar("env_points",Penvpoints); + xml->addpar("env_sustain",Penvsustain); + xml->addpar("env_stretch",Penvstretch); + xml->addparbool("forced_release",Pforcedrelease); + xml->addparbool("linear_envelope",Plinearenvelope); + xml->addpar("A_dt",PA_dt); + xml->addpar("D_dt",PD_dt); + xml->addpar("R_dt",PR_dt); + xml->addpar("A_val",PA_val); + xml->addpar("D_val",PD_val); + xml->addpar("S_val",PS_val); + xml->addpar("R_val",PR_val); + + if ((Pfreemode!=0)||(!xml->minimal)){ + for (int i=0;ibeginbranch("POINT",i); + if (i!=0) xml->addpar("dt",Penvdt[i]); + xml->addpar("val",Penvval[i]); + xml->endbranch(); + }; + }; +}; + + + +void EnvelopeParams::getfromXML(XMLwrapper *xml){ + Pfreemode=xml->getparbool("free_mode",Pfreemode); + Penvpoints=xml->getpar127("env_points",Penvpoints); + Penvsustain=xml->getpar127("env_sustain",Penvsustain); + Penvstretch=xml->getpar127("env_stretch",Penvstretch); + Pforcedrelease=xml->getparbool("forced_release",Pforcedrelease); + Plinearenvelope=xml->getparbool("linear_envelope",Plinearenvelope); + + PA_dt=xml->getpar127("A_dt",PA_dt); + PD_dt=xml->getpar127("D_dt",PD_dt); + PR_dt=xml->getpar127("R_dt",PR_dt); + PA_val=xml->getpar127("A_val",PA_val); + PD_val=xml->getpar127("D_val",PD_val); + PS_val=xml->getpar127("S_val",PS_val); + PR_val=xml->getpar127("R_val",PR_val); + + for (int i=0;ienterbranch("POINT",i)==0) continue; + if (i!=0) Penvdt[i]=xml->getpar127("dt",Penvdt[i]); + Penvval[i]=xml->getpar127("val",Penvval[i]); + xml->exitbranch(); + }; + + if (!Pfreemode) converttofree(); +}; + + +void EnvelopeParams::defaults(){ + Penvstretch=Denvstretch; + Pforcedrelease=Dforcedrelease; + Plinearenvelope=Dlinearenvelope; + PA_dt=DA_dt; + PD_dt=DD_dt; + PR_dt=DR_dt; + PA_val=DA_val; + PD_val=DD_val; + PS_val=DS_val; + PR_val=DR_val; + Pfreemode=0; + converttofree(); +}; + +void EnvelopeParams::store2defaults(){ + Denvstretch=Penvstretch; + Dforcedrelease=Pforcedrelease; + Dlinearenvelope=Plinearenvelope; + DA_dt=PA_dt; + DD_dt=PD_dt; + DR_dt=PR_dt; + DA_val=PA_val; + DD_val=PD_val; + DS_val=PS_val; + DR_val=PR_val; +}; + + + diff --git a/plugins/zynaddsubfx/src/Params/EnvelopeParams.h b/plugins/zynaddsubfx/src/Params/EnvelopeParams.h new file mode 100644 index 000000000..5267356b1 --- /dev/null +++ b/plugins/zynaddsubfx/src/Params/EnvelopeParams.h @@ -0,0 +1,86 @@ +/* + ZynAddSubFX - a software synthesizer + + EnvelopeParams.h - Parameters for Envelope + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef ENVELOPE_PARAMS_H +#define ENVELOPE_PARAMS_H + +#include "../globals.h" +#include "../Misc/XMLwrapper.h" +#include "Presets.h" + +#define MAX_ENVELOPE_POINTS 40 +#define MIN_ENVELOPE_DB -40 + +class EnvelopeParams:public Presets{ + public: + EnvelopeParams(unsigned char Penvstretch_,unsigned char Pforcedrelease_); + ~EnvelopeParams(); + void ADSRinit(char A_dt,char D_dt,char S_val,char R_dt); + void ADSRinit_dB(char A_dt,char D_dt,char S_val,char R_dt); + void ASRinit(char A_val,char A_dt,char R_val,char R_dt); + void ADSRinit_filter(char A_val,char A_dt,char D_val,char D_dt,char R_dt,char R_val); + void ASRinit_bw(char A_val,char A_dt,char R_val,char R_dt); + void converttofree(); + + void add2XML(XMLwrapper *xml); + void defaults(); + void getfromXML(XMLwrapper *xml); + + REALTYPE getdt(char i); + + /* Parametrii MIDI */ + unsigned char Pfreemode;//1 daca este in modul free sau 0 daca este in mod ADSR,ASR,... + unsigned char Penvpoints; + unsigned char Penvsustain;//127 pentru dezactivat + unsigned char Penvdt[MAX_ENVELOPE_POINTS]; + unsigned char Penvval[MAX_ENVELOPE_POINTS]; + unsigned char Penvstretch;//64=normal stretch (piano-like), 0=no stretch + unsigned char Pforcedrelease;//0 - OFF, 1 - ON + unsigned char Plinearenvelope;//if the amplitude envelope is linear + + unsigned char PA_dt,PD_dt,PR_dt, + PA_val,PD_val,PS_val,PR_val; + + + + int Envmode;// 1 for ADSR parameters (linear amplitude) + // 2 for ADSR_dB parameters (dB amplitude) + // 3 for ASR parameters (frequency LFO) + // 4 for ADSR_filter parameters (filter parameters) + // 5 for ASR_bw parameters (bandwidth parameters) + + private: + void store2defaults(); + + /* Default parameters */ + unsigned char Denvstretch; + unsigned char Dforcedrelease; + unsigned char Dlinearenvelope; + unsigned char DA_dt,DD_dt,DR_dt, + DA_val,DD_val,DS_val,DR_val; + + +}; + + +#endif + diff --git a/plugins/zynaddsubfx/src/Params/FilterParams.C b/plugins/zynaddsubfx/src/Params/FilterParams.C new file mode 100644 index 000000000..f1402939b --- /dev/null +++ b/plugins/zynaddsubfx/src/Params/FilterParams.C @@ -0,0 +1,344 @@ +/* + ZynAddSubFX - a software synthesizer + + FilterParams.C - Parameters for filter + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include +#include +#include +#include "FilterParams.h" + +FilterParams::FilterParams(unsigned char Ptype_,unsigned char Pfreq_,unsigned char Pq_):Presets(){ + setpresettype("Pfilter"); + Dtype=Ptype_; + Dfreq=Pfreq_; + Dq=Pq_; + + changed=false; + defaults(); +}; + +FilterParams::~FilterParams(){ +}; + + +void FilterParams::defaults(){ + Ptype=Dtype; + Pfreq=Dfreq; + Pq=Dq; + + Pstages=0; + Pfreqtrack=64; + Pgain=64; + Pcategory=0; + + Pnumformants=3; + Pformantslowness=64; + for (int j=0;jPtype; + Pfreq=pars->Pfreq; + Pq=pars->Pq; + + Pstages=pars->Pstages; + Pfreqtrack=pars->Pfreqtrack; + Pgain=pars->Pgain; + Pcategory=pars->Pcategory; + + Pnumformants=pars->Pnumformants; + Pformantslowness=pars->Pformantslowness; + for (int j=0;jPvowels[j].formants[i].freq; + Pvowels[j].formants[i].q=pars->Pvowels[j].formants[i].q; + Pvowels[j].formants[i].amp=pars->Pvowels[j].formants[i].amp; + }; + }; + + Psequencesize=pars->Psequencesize; + for (int i=0;iPsequence[i].nvowel; + + Psequencestretch=pars->Psequencestretch; + Psequencereversed=pars->Psequencereversed; + Pcenterfreq=pars->Pcenterfreq; + Poctavesfreq=pars->Poctavesfreq; + Pvowelclearness=pars->Pvowelclearness; +}; + + +/* + * Parameter control + */ +REALTYPE FilterParams::getfreq(){ + return((Pfreq/64.0-1.0)*5.0); +}; + +REALTYPE FilterParams::getq(){ + return(exp(pow((REALTYPE) Pq/127.0,2)*log(1000.0))-0.9); +}; +REALTYPE FilterParams::getfreqtracking(REALTYPE notefreq){ + return(log(notefreq/440.0)*(Pfreqtrack-64.0)/(64.0*LOG_2)); +}; + +REALTYPE FilterParams::getgain(){ + return((Pgain/64.0-1.0)*30.0);//-30..30dB +}; + +/* + * Get the center frequency of the formant's graph + */ +REALTYPE FilterParams::getcenterfreq(){ + return(10000.0*pow(10,-(1.0-Pcenterfreq/127.0)*2.0)); +}; + +/* + * Get the number of octave that the formant functions applies to + */ +REALTYPE FilterParams::getoctavesfreq(){ + return(0.25+10.0*Poctavesfreq/127.0); +}; + +/* + * Get the frequency from x, where x is [0..1] + */ +REALTYPE FilterParams::getfreqx(REALTYPE x){ + if (x>1.0) x=1.0; + REALTYPE octf=pow(2.0,getoctavesfreq()); + return(getcenterfreq()/sqrt(octf)*pow(octf,x)); +}; + +/* + * Get the x coordinate from frequency (used by the UI) + */ +REALTYPE FilterParams::getfreqpos(REALTYPE freq){ + return((log(freq)-log(getfreqx(0.0)))/log(2.0)/getoctavesfreq()); +}; + + +/* + * Get the freq. response of the formant filter + */ +void FilterParams::formantfilterH(int nvowel,int nfreqs,REALTYPE *freqs){ + REALTYPE c[3],d[3]; + REALTYPE filter_freq,filter_q,filter_amp; + REALTYPE omega,sn,cs,alpha; + + for (int i=0;i0) filter_q=(filter_q>1.0 ? pow(filter_q,1.0/(Pstages+1)) : filter_q); + + filter_amp=getformantamp(Pvowels[nvowel].formants[nformant].amp); + + + if (filter_freq<=(SAMPLE_RATE/2-100.0)){ + omega=2*PI*filter_freq/SAMPLE_RATE; + sn=sin(omega); + cs=cos(omega); + alpha=sn/(2*filter_q); + REALTYPE tmp=1+alpha; + c[0]=alpha/tmp*sqrt(filter_q+1); + c[1]=0; + c[2]=-alpha/tmp*sqrt(filter_q+1); + d[1]=-2*cs/tmp*(-1); + d[2]=(1-alpha)/tmp*(-1); + } else continue; + + + for (int i=0;iSAMPLE_RATE/2) { + for (int tmp=i;tmp0.000000001) freqs[i]=rap2dB(freqs[i])+getgain(); + else freqs[i]=-90.0; + }; + +}; + +/* + * Transforms a parameter to the real value + */ +REALTYPE FilterParams::getformantfreq(unsigned char freq){ + REALTYPE result=getfreqx(freq/127.0); + return(result); +}; + +REALTYPE FilterParams::getformantamp(unsigned char amp){ + REALTYPE result=pow(0.1,(1.0-amp/127.0)*4.0); + return(result); +}; + +REALTYPE FilterParams::getformantq(unsigned char q){ + //temp + REALTYPE result=pow(25.0,(q-32.0)/64.0); + return(result); +}; + + + +void FilterParams::add2XMLsection(XMLwrapper *xml,int n){ + int nvowel=n; + for (int nformant=0;nformantbeginbranch("FORMANT",nformant); + xml->addpar("freq",Pvowels[nvowel].formants[nformant].freq); + xml->addpar("amp",Pvowels[nvowel].formants[nformant].amp); + xml->addpar("q",Pvowels[nvowel].formants[nformant].q); + xml->endbranch(); + }; +}; + +void FilterParams::add2XML(XMLwrapper *xml){ + //filter parameters + xml->addpar("category",Pcategory); + xml->addpar("type",Ptype); + xml->addpar("freq",Pfreq); + xml->addpar("q",Pq); + xml->addpar("stages",Pstages); + xml->addpar("freq_track",Pfreqtrack); + xml->addpar("gain",Pgain); + + //formant filter parameters + if ((Pcategory==1)||(!xml->minimal)){ + xml->beginbranch("FORMANT_FILTER"); + xml->addpar("num_formants",Pnumformants); + xml->addpar("formant_slowness",Pformantslowness); + xml->addpar("vowel_clearness",Pvowelclearness); + xml->addpar("center_freq",Pcenterfreq); + xml->addpar("octaves_freq",Poctavesfreq); + for (int nvowel=0;nvowelbeginbranch("VOWEL",nvowel); + add2XMLsection(xml,nvowel); + xml->endbranch(); + }; + xml->addpar("sequence_size",Psequencesize); + xml->addpar("sequence_stretch",Psequencestretch); + xml->addparbool("sequence_reversed",Psequencereversed); + for (int nseq=0;nseqbeginbranch("SEQUENCE_POS",nseq); + xml->addpar("vowel_id",Psequence[nseq].nvowel); + xml->endbranch(); + }; + xml->endbranch(); + }; +}; + + +void FilterParams::getfromXMLsection(XMLwrapper *xml,int n){ + int nvowel=n; + for (int nformant=0;nformantenterbranch("FORMANT",nformant)==0) continue; + Pvowels[nvowel].formants[nformant].freq=xml->getpar127("freq",Pvowels[nvowel].formants[nformant].freq); + Pvowels[nvowel].formants[nformant].amp=xml->getpar127("amp",Pvowels[nvowel].formants[nformant].amp); + Pvowels[nvowel].formants[nformant].q=xml->getpar127("q",Pvowels[nvowel].formants[nformant].q); + xml->exitbranch(); + }; +}; + +void FilterParams::getfromXML(XMLwrapper *xml){ + //filter parameters + Pcategory=xml->getpar127("category",Pcategory); + Ptype=xml->getpar127("type",Ptype); + Pfreq=xml->getpar127("freq",Pfreq); + Pq=xml->getpar127("q",Pq); + Pstages=xml->getpar127("stages",Pstages); + Pfreqtrack=xml->getpar127("freq_track",Pfreqtrack); + Pgain=xml->getpar127("gain",Pgain); + + //formant filter parameters + if(xml->enterbranch("FORMANT_FILTER")){ + Pnumformants=xml->getpar127("num_formants",Pnumformants); + Pformantslowness=xml->getpar127("formant_slowness",Pformantslowness); + Pvowelclearness=xml->getpar127("vowel_clearness",Pvowelclearness); + Pcenterfreq=xml->getpar127("center_freq",Pcenterfreq); + Poctavesfreq=xml->getpar127("octaves_freq",Poctavesfreq); + + for (int nvowel=0;nvowelenterbranch("VOWEL",nvowel)==0) continue; + getfromXMLsection(xml,nvowel); + xml->exitbranch(); + }; + Psequencesize=xml->getpar127("sequence_size",Psequencesize); + Psequencestretch=xml->getpar127("sequence_stretch",Psequencestretch); + Psequencereversed=xml->getparbool("sequence_reversed",Psequencereversed); + for (int nseq=0;nseqenterbranch("SEQUENCE_POS",nseq)==0) continue; + Psequence[nseq].nvowel=xml->getpar("vowel_id",Psequence[nseq].nvowel,0,FF_MAX_VOWELS-1); + xml->exitbranch(); + }; + xml->exitbranch(); + }; + +}; + diff --git a/plugins/zynaddsubfx/src/Params/FilterParams.h b/plugins/zynaddsubfx/src/Params/FilterParams.h new file mode 100644 index 000000000..bf3e06804 --- /dev/null +++ b/plugins/zynaddsubfx/src/Params/FilterParams.h @@ -0,0 +1,100 @@ +/* + ZynAddSubFX - a software synthesizer + + FilterParams.h - Parameters for filter + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef FILTER_PARAMS_H +#define FILTER_PARAMS_H + +#include "../globals.h" +#include "../Misc/XMLwrapper.h" +#include "Presets.h" + +class FilterParams:public Presets{ + public: + FilterParams(unsigned char Ptype_,unsigned char Pfreq,unsigned char Pq_); + ~FilterParams(); + + void add2XML(XMLwrapper *xml); + void add2XMLsection(XMLwrapper *xml,int n); + void defaults(); + void getfromXML(XMLwrapper *xml); + void getfromXMLsection(XMLwrapper *xml,int n); + + + void getfromFilterParams(FilterParams *pars); + + REALTYPE getfreq(); + REALTYPE getq(); + REALTYPE getfreqtracking(REALTYPE notefreq); + REALTYPE getgain(); + + unsigned char Pcategory;//Filter category (Analog/Formant/StVar) + unsigned char Ptype;// Filter type (for analog lpf,hpf,bpf..) + unsigned char Pfreq;// Frequency (64-central frequency) + unsigned char Pq; // Q parameters (resonance or bandwidth) + unsigned char Pstages; //filter stages+1 + unsigned char Pfreqtrack;//how the filter frequency is changing according the note frequency + unsigned char Pgain;//filter's output gain + + //Formant filter parameters + unsigned char Pnumformants;//how many formants are used + unsigned char Pformantslowness;//how slow varies the formants + unsigned char Pvowelclearness;//how vowels are kept clean (how much try to avoid "mixed" vowels) + unsigned char Pcenterfreq,Poctavesfreq;//the center frequency of the res. func., and the number of octaves + + struct { + struct { + unsigned char freq,amp,q;//frequency,amplitude,Q + }formants[FF_MAX_FORMANTS]; + }Pvowels[FF_MAX_VOWELS]; + + + unsigned char Psequencesize;//how many vowels are in the sequence + unsigned char Psequencestretch;//how the sequence is stretched (how the input from filter envelopes/LFOs/etc. is "stretched") + unsigned char Psequencereversed;//if the input from filter envelopes/LFOs/etc. is reversed(negated) + struct { + unsigned char nvowel;//the vowel from the position + } Psequence[FF_MAX_SEQUENCE]; + + REALTYPE getcenterfreq(); + REALTYPE getoctavesfreq(); + REALTYPE getfreqpos(REALTYPE freq); + REALTYPE getfreqx(REALTYPE x); + + void formantfilterH(int nvowel,int nfreqs,REALTYPE *freqs);//used by UI + + REALTYPE getformantfreq(unsigned char freq); + REALTYPE getformantamp(unsigned char amp); + REALTYPE getformantq(unsigned char q); + + bool changed; + + private: + void defaults(int n); + + //stored default parameters + unsigned char Dtype; + unsigned char Dfreq; + unsigned char Dq; +}; + +#endif + diff --git a/plugins/zynaddsubfx/src/Params/LFOParams.C b/plugins/zynaddsubfx/src/Params/LFOParams.C new file mode 100644 index 000000000..a074c2835 --- /dev/null +++ b/plugins/zynaddsubfx/src/Params/LFOParams.C @@ -0,0 +1,91 @@ +/* + ZynAddSubFX - a software synthesizer + + LFOParams.C - Parameters for LFO + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include +#include +#include "../globals.h" +#include "LFOParams.h" + +int LFOParams::time; + +LFOParams::LFOParams(char Pfreq_,char Pintensity_,char Pstartphase_, char PLFOtype_,char Prandomness_, char Pdelay_,char Pcontinous_,char fel_):Presets(){ + switch(fel_) { + case 0:setpresettype("Plfofrequency"); + break; + case 1:setpresettype("Plfoamplitude"); + break; + case 2:setpresettype("Plfofilter"); + break; + }; + Dfreq=Pfreq_; + Dintensity=Pintensity_; + Dstartphase=Pstartphase_; + DLFOtype=PLFOtype_; + Drandomness=Prandomness_; + Ddelay=Pdelay_; + Dcontinous=Pcontinous_; + fel=fel_; + time=0; + + defaults(); +}; + +LFOParams::~LFOParams(){ +}; + +void LFOParams::defaults(){ + Pfreq=Dfreq/127.0; + Pintensity=Dintensity; + Pstartphase=Dstartphase; + PLFOtype=DLFOtype; + Prandomness=Drandomness; + Pdelay=Ddelay; + Pcontinous=Dcontinous; + Pfreqrand=0; + Pstretch=64; +}; + + +void LFOParams::add2XML(XMLwrapper *xml){ + xml->addparreal("freq",Pfreq); + xml->addpar("intensity",Pintensity); + xml->addpar("start_phase",Pstartphase); + xml->addpar("lfo_type",PLFOtype); + xml->addpar("randomness_amplitude",Prandomness); + xml->addpar("randomness_frequency",Pfreqrand); + xml->addpar("delay",Pdelay); + xml->addpar("stretch",Pstretch); + xml->addparbool("continous",Pcontinous); +}; + +void LFOParams::getfromXML(XMLwrapper *xml){ + Pfreq=xml->getparreal("freq",Pfreq,0.0,1.0); + Pintensity=xml->getpar127("intensity",Pintensity); + Pstartphase=xml->getpar127("start_phase",Pstartphase); + PLFOtype=xml->getpar127("lfo_type",PLFOtype); + Prandomness=xml->getpar127("randomness_amplitude",Prandomness); + Pfreqrand=xml->getpar127("randomness_frequency",Pfreqrand); + Pdelay=xml->getpar127("delay",Pdelay); + Pstretch=xml->getpar127("stretch",Pstretch); + Pcontinous=xml->getparbool("continous",Pcontinous); +}; + diff --git a/plugins/zynaddsubfx/src/Params/LFOParams.h b/plugins/zynaddsubfx/src/Params/LFOParams.h new file mode 100644 index 000000000..35d74f135 --- /dev/null +++ b/plugins/zynaddsubfx/src/Params/LFOParams.h @@ -0,0 +1,64 @@ +/* + ZynAddSubFX - a software synthesizer + + LFOParams.h - Parameters for LFO + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef LFO_PARAMS_H +#define LFO_PARAMS_H + +#include "../Misc/XMLwrapper.h" +#include "Presets.h" + +class LFOParams:public Presets{ + public: + LFOParams(char Pfreq_,char Pintensity_,char Pstartphase_, char PLFOtype_,char Prandomness_, char Pdelay_,char Pcontinous,char fel_); + ~LFOParams(); + + void add2XML(XMLwrapper *xml); + void defaults(); + void getfromXML(XMLwrapper *xml); + + /* Parametrii MIDI */ + REALTYPE Pfreq; // frequency + unsigned char Pintensity; // intensity + unsigned char Pstartphase;// start phase (0=random) + unsigned char PLFOtype; // LFO type (sin,triangle,square,ramp,...) + unsigned char Prandomness;// randomness (0=off) + unsigned char Pfreqrand; // frequency randomness (0=off) + unsigned char Pdelay; // delay (0=off) + unsigned char Pcontinous; // 1 if LFO is continous + unsigned char Pstretch; // how the LFO is "stretched" according the note frequency (64=no stretch) + + int fel;//what kind is the LFO (0 - frequency, 1 - amplitude, 2 - filter) + static int time;//is used by Pcontinous parameter + private: + /* Default parameters */ + unsigned char Dfreq; + unsigned char Dintensity; + unsigned char Dstartphase; + unsigned char DLFOtype; + unsigned char Drandomness; + unsigned char Ddelay; + unsigned char Dcontinous; + +}; + + +#endif diff --git a/plugins/zynaddsubfx/src/Params/PADnoteParameters.C b/plugins/zynaddsubfx/src/Params/PADnoteParameters.C new file mode 100644 index 000000000..46a07448d --- /dev/null +++ b/plugins/zynaddsubfx/src/Params/PADnoteParameters.C @@ -0,0 +1,762 @@ +/* + ZynAddSubFX - a software synthesizer + + PADnoteParameters.C - Parameters for PADnote (PADsynth) + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ +#include +#include "PADnoteParameters.h" +#include "../Output/WAVaudiooutput.h" +using namespace std; + +PADnoteParameters::PADnoteParameters(FFTwrapper *fft_,pthread_mutex_t *mutex_):Presets(){ + setpresettype("Ppadsyth"); + + fft=fft_; + mutex=mutex_; + + resonance=new Resonance(); + oscilgen=new OscilGen(fft_,resonance); + oscilgen->ADvsPAD=true; + + FreqEnvelope=new EnvelopeParams(0,0); + FreqEnvelope->ASRinit(64,50,64,60); + FreqLfo=new LFOParams(70,0,64,0,0,0,0,0); + + AmpEnvelope=new EnvelopeParams(64,1); + AmpEnvelope->ADSRinit_dB(0,40,127,25); + AmpLfo=new LFOParams(80,0,64,0,0,0,0,1); + + GlobalFilter=new FilterParams(2,94,40); + FilterEnvelope=new EnvelopeParams(0,1); + FilterEnvelope->ADSRinit_filter(64,40,64,70,60,64); + FilterLfo=new LFOParams(80,0,64,0,0,0,0,2); + + for (int i=0;idefaults(); + oscilgen->defaults(); + + Phrpos.type=0; + Phrpos.par1=64; + Phrpos.par2=64; + Phrpos.par3=0; + + Pquality.samplesize=3; + Pquality.basenote=4; + Pquality.oct=3; + Pquality.smpoct=2; + + PStereo=1;//stereo + /* Frequency Global Parameters */ + Pfixedfreq=0; + PfixedfreqET=0; + PDetune=8192;//zero + PCoarseDetune=0; + PDetuneType=1; + FreqEnvelope->defaults(); + FreqLfo->defaults(); + + /* Amplitude Global Parameters */ + PVolume=90; + PPanning=64;//center + PAmpVelocityScaleFunction=64; + AmpEnvelope->defaults(); + AmpLfo->defaults(); + PPunchStrength=0; + PPunchTime=60; + PPunchStretch=64; + PPunchVelocitySensing=72; + + /* Filter Global Parameters*/ + PFilterVelocityScale=64; + PFilterVelocityScaleFunction=64; + GlobalFilter->defaults(); + FilterEnvelope->defaults(); + FilterLfo->defaults(); + + deletesamples(); +}; + +void PADnoteParameters::deletesample(int n){ + if ((n<0)||(n>=PAD_MAX_SAMPLES)) return; + if (sample[n].smp!=NULL){ + delete[]sample[n].smp; + sample[n].smp=NULL; + }; + sample[n].size=0; + sample[n].basefreq=440.0; +}; + +void PADnoteParameters::deletesamples(){ + for (int i=0;i1.0) { + x=1.0; + makezero=true; + }; + }; + + //compute the full profile or one half + switch(Php.onehalf){ + case 1:x=x*0.5+0.5; + break; + case 2:x=x*0.5; + break; + }; + + REALTYPE x_before_freq_mult=x; + + //do the frequency multiplier + x*=freqmult; + + //do the modulation of the profile + x+=sin(x_before_freq_mult*3.1415926*modfreq)*modpar1; + x=fmod(x+1000.0,1.0)*2.0-1.0; + + + //this is the base function of the profile + REALTYPE f; + switch (Php.base.type){ + case 1:f=exp(-(x*x)*basepar);if (f<0.4) f=0.0; else f=1.0; + break; + case 2:f=exp(-(fabs(x))*sqrt(basepar)); + break; + default:f=exp(-(x*x)*basepar); + break; + }; + if (makezero) f=0.0; + + REALTYPE amp=1.0; + origx=origx*2.0-1.0; + + //compute the amplitude multiplier + switch(Php.amp.type){ + case 1:amp=exp(-(origx*origx)*10.0*amppar1); + break; + case 2:amp=0.5*(1.0+cos(3.1415926*origx*sqrt(amppar1*4.0+1.0))); + break; + case 3:amp=1.0/(pow(origx*(amppar1*2.0+0.8),14.0)+1.0); + break; + }; + + //apply the amplitude multiplier + REALTYPE finalsmp=f; + if (Php.amp.type!=0){ + switch(Php.amp.mode){ + case 0:finalsmp=amp*(1.0-amppar2)+finalsmp*amppar2; + break; + case 1:finalsmp*=amp*(1.0-amppar2)+amppar2; + break; + case 2:finalsmp=finalsmp/(amp+pow(amppar2,4.0)*20.0+0.0001); + break; + case 3:finalsmp=amp/(finalsmp+pow(amppar2,4.0)*20.0+0.0001); + break; + }; + }; + + smp[i/supersample]+=finalsmp/supersample; + }; + + //normalize the profile (make the max. to be equal to 1.0) + REALTYPE max=0.0; + for (int i=0;imax) max=smp[i]; + }; + if (max<0.00001) max=1.0; + for (int i=0;i=4.0) break; + }; + + REALTYPE result=1.0-2.0*i/(REALTYPE) size; + return(result); +}; + +/* + * Compute the real bandwidth in cents and returns it + * Also, sets the bandwidth parameter + */ +REALTYPE PADnoteParameters::setPbandwidth(int Pbandwidth){ + this->Pbandwidth=Pbandwidth; + REALTYPE result=pow(Pbandwidth/1000.0,1.1); + result=pow(10.0,result*4.0)*0.25; + return(result); +}; + +/* + * Get the harmonic(overtone) position + */ +REALTYPE PADnoteParameters::getNhr(int n){ + REALTYPE result=1.0; + REALTYPE par1=pow(10.0,-(1.0-Phrpos.par1/255.0)*3.0); + REALTYPE par2=Phrpos.par2/255.0; + + REALTYPE n0=n-1.0; + REALTYPE tmp=0.0; + int thresh=0; + switch(Phrpos.type){ + case 1: + thresh=(int)(par2*par2*100.0)+1; + if (nget(harmonics,basefreq,false); + + //normalize + REALTYPE max=0.0; + for (int i=0;imax) max=harmonics[i]; + if (max<0.000001) max=1; + for (int i=0;iSAMPLE_RATE*0.49999) break; + if (realfreq<20.0) break; + if (harmonics[nh-1]<1e-4) continue; + + //compute the bandwidth of each harmonic + REALTYPE bandwidthcents=setPbandwidth(Pbandwidth); + REALTYPE bw=(pow(2.0,bandwidthcents/1200.0)-1.0)*basefreq/bwadjust; + REALTYPE power=1.0; + switch (Pbwscale){ + case 0: power=1.0;break; + case 1: power=0.0;break; + case 2: power=0.25;break; + case 3: power=0.5;break; + case 4: power=0.75;break; + case 5: power=1.5;break; + case 6: power=2.0;break; + case 7: power=-0.5;break; + }; + bw=bw*pow(realfreq/basefreq,power); + int ibw=(int)((bw/(SAMPLE_RATE*0.5)*size))+1; + + REALTYPE amp=harmonics[nh-1]; + if (resonance->Penabled) amp*=resonance->getfreqresponse(realfreq); + + if (ibw>profilesize){//if the bandwidth is larger than the profilesize + REALTYPE rap=sqrt((REALTYPE)profilesize/(REALTYPE)ibw); + int cfreq=(int) (realfreq/(SAMPLE_RATE*0.5)*size)-ibw/2; + for (int i=0;i=size) break; + spectrum[spfreq]+=amp*profile[src]*rap; + }; + }else{//if the bandwidth is smaller than the profilesize + REALTYPE rap=sqrt((REALTYPE)ibw/(REALTYPE)profilesize); + REALTYPE ibasefreq=realfreq/(SAMPLE_RATE*0.5)*size; + for (int i=0;i=size-1) break; + spectrum[spfreq]+=amp*profile[i]*rap*(1.0-fspfreq); + spectrum[spfreq+1]+=amp*profile[i]*rap*fspfreq; + }; + }; + }; +}; + +/* + * Generates the long spectrum for non-Bandwidth modes (only amplitudes are generated; phases will be random) + */ +void PADnoteParameters::generatespectrum_otherModes(REALTYPE *spectrum, int size,REALTYPE basefreq,REALTYPE *profile,int profilesize,REALTYPE bwadjust){ + for (int i=0;iget(harmonics,basefreq,false); + + //normalize + REALTYPE max=0.0; + for (int i=0;imax) max=harmonics[i]; + if (max<0.000001) max=1; + for (int i=0;iSAMPLE_RATE*0.49999) break; + if (realfreq<20.0) break; +// if (harmonics[nh-1]<1e-4) continue; + + + REALTYPE amp=harmonics[nh-1]; + if (resonance->Penabled) amp*=resonance->getfreqresponse(realfreq); + int cfreq=(int) (realfreq/(SAMPLE_RATE*0.5)*size); + + spectrum[cfreq]=amp+1e-9; + }; + + if (Pmode!=1){ + int old=0; + for (int k=1;k1e-10) || (k==(size-1)) ){ + int delta=k-old; + REALTYPE val1=spectrum[old]; + REALTYPE val2=spectrum[k]; + REALTYPE idelta=1.0/delta; + for (int i=0;ifreqs2smps(fftfreqs,newsample.smp);//that's all; here is the only ifft for the whole sample; no windows are used ;-) + + + //normalize(rms) + REALTYPE rms=0.0; + for (int i=0;iinformation.PADsynth_used=true; + + xml->addparbool("stereo",PStereo); + xml->addpar("mode",Pmode); + xml->addpar("bandwidth",Pbandwidth); + xml->addpar("bandwidth_scale",Pbwscale); + + xml->beginbranch("HARMONIC_PROFILE"); + xml->addpar("base_type",Php.base.type); + xml->addpar("base_par1",Php.base.par1); + xml->addpar("frequency_multiplier",Php.freqmult); + xml->addpar("modulator_par1",Php.modulator.par1); + xml->addpar("modulator_frequency",Php.modulator.freq); + xml->addpar("width",Php.width); + xml->addpar("amplitude_multiplier_type",Php.amp.type); + xml->addpar("amplitude_multiplier_mode",Php.amp.mode); + xml->addpar("amplitude_multiplier_par1",Php.amp.par1); + xml->addpar("amplitude_multiplier_par2",Php.amp.par2); + xml->addparbool("autoscale",Php.autoscale); + xml->addpar("one_half",Php.onehalf); + xml->endbranch(); + + xml->beginbranch("OSCIL"); + oscilgen->add2XML(xml); + xml->endbranch(); + + xml->beginbranch("RESONANCE"); + resonance->add2XML(xml); + xml->endbranch(); + + xml->beginbranch("HARMONIC_POSITION"); + xml->addpar("type",Phrpos.type); + xml->addpar("parameter1",Phrpos.par1); + xml->addpar("parameter2",Phrpos.par2); + xml->addpar("parameter3",Phrpos.par3); + xml->endbranch(); + + xml->beginbranch("SAMPLE_QUALITY"); + xml->addpar("samplesize",Pquality.samplesize); + xml->addpar("basenote",Pquality.basenote); + xml->addpar("octaves",Pquality.oct); + xml->addpar("samples_per_octave",Pquality.smpoct); + xml->endbranch(); + + xml->beginbranch("AMPLITUDE_PARAMETERS"); + xml->addpar("volume",PVolume); + xml->addpar("panning",PPanning); + xml->addpar("velocity_sensing",PAmpVelocityScaleFunction); + xml->addpar("punch_strength",PPunchStrength); + xml->addpar("punch_time",PPunchTime); + xml->addpar("punch_stretch",PPunchStretch); + xml->addpar("punch_velocity_sensing",PPunchVelocitySensing); + + xml->beginbranch("AMPLITUDE_ENVELOPE"); + AmpEnvelope->add2XML(xml); + xml->endbranch(); + + xml->beginbranch("AMPLITUDE_LFO"); + AmpLfo->add2XML(xml); + xml->endbranch(); + + xml->endbranch(); + + xml->beginbranch("FREQUENCY_PARAMETERS"); + xml->addpar("fixed_freq",Pfixedfreq); + xml->addpar("fixed_freq_et",PfixedfreqET); + xml->addpar("detune",PDetune); + xml->addpar("coarse_detune",PCoarseDetune); + xml->addpar("detune_type",PDetuneType); + + xml->beginbranch("FREQUENCY_ENVELOPE"); + FreqEnvelope->add2XML(xml); + xml->endbranch(); + + xml->beginbranch("FREQUENCY_LFO"); + FreqLfo->add2XML(xml); + xml->endbranch(); + xml->endbranch(); + + xml->beginbranch("FILTER_PARAMETERS"); + xml->addpar("velocity_sensing_amplitude",PFilterVelocityScale); + xml->addpar("velocity_sensing",PFilterVelocityScaleFunction); + + xml->beginbranch("FILTER"); + GlobalFilter->add2XML(xml); + xml->endbranch(); + + xml->beginbranch("FILTER_ENVELOPE"); + FilterEnvelope->add2XML(xml); + xml->endbranch(); + + xml->beginbranch("FILTER_LFO"); + FilterLfo->add2XML(xml); + xml->endbranch(); + xml->endbranch(); +}; + +void PADnoteParameters::getfromXML(XMLwrapper *xml){ + PStereo=xml->getparbool("stereo",PStereo); + Pmode=xml->getpar127("mode",0); + Pbandwidth=xml->getpar("bandwidth",Pbandwidth,0,1000); + Pbwscale=xml->getpar127("bandwidth_scale",Pbwscale); + + if (xml->enterbranch("HARMONIC_PROFILE")){ + Php.base.type=xml->getpar127("base_type",Php.base.type); + Php.base.par1=xml->getpar127("base_par1",Php.base.par1); + Php.freqmult=xml->getpar127("frequency_multiplier",Php.freqmult); + Php.modulator.par1=xml->getpar127("modulator_par1",Php.modulator.par1); + Php.modulator.freq=xml->getpar127("modulator_frequency",Php.modulator.freq); + Php.width=xml->getpar127("width",Php.width); + Php.amp.type=xml->getpar127("amplitude_multiplier_type",Php.amp.type); + Php.amp.mode=xml->getpar127("amplitude_multiplier_mode",Php.amp.mode); + Php.amp.par1=xml->getpar127("amplitude_multiplier_par1",Php.amp.par1); + Php.amp.par2=xml->getpar127("amplitude_multiplier_par2",Php.amp.par2); + Php.autoscale=xml->getparbool("autoscale",Php.autoscale); + Php.onehalf=xml->getpar127("one_half",Php.onehalf); + xml->exitbranch(); + }; + + if (xml->enterbranch("OSCIL")){ + oscilgen->getfromXML(xml); + xml->exitbranch(); + }; + + if (xml->enterbranch("RESONANCE")){ + resonance->getfromXML(xml); + xml->exitbranch(); + }; + + if (xml->enterbranch("HARMONIC_POSITION")){ + Phrpos.type=xml->getpar127("type",Phrpos.type); + Phrpos.par1=xml->getpar("parameter1",Phrpos.par1,0,255); + Phrpos.par2=xml->getpar("parameter2",Phrpos.par2,0,255); + Phrpos.par3=xml->getpar("parameter3",Phrpos.par3,0,255); + xml->exitbranch(); + }; + + if (xml->enterbranch("SAMPLE_QUALITY")){ + Pquality.samplesize=xml->getpar127("samplesize",Pquality.samplesize); + Pquality.basenote=xml->getpar127("basenote",Pquality.basenote); + Pquality.oct=xml->getpar127("octaves",Pquality.oct); + Pquality.smpoct=xml->getpar127("samples_per_octave",Pquality.smpoct); + xml->exitbranch(); + }; + + if (xml->enterbranch("AMPLITUDE_PARAMETERS")){ + PVolume=xml->getpar127("volume",PVolume); + PPanning=xml->getpar127("panning",PPanning); + PAmpVelocityScaleFunction=xml->getpar127("velocity_sensing",PAmpVelocityScaleFunction); + PPunchStrength=xml->getpar127("punch_strength",PPunchStrength); + PPunchTime=xml->getpar127("punch_time",PPunchTime); + PPunchStretch=xml->getpar127("punch_stretch",PPunchStretch); + PPunchVelocitySensing=xml->getpar127("punch_velocity_sensing",PPunchVelocitySensing); + + xml->enterbranch("AMPLITUDE_ENVELOPE"); + AmpEnvelope->getfromXML(xml); + xml->exitbranch(); + + xml->enterbranch("AMPLITUDE_LFO"); + AmpLfo->getfromXML(xml); + xml->exitbranch(); + + xml->exitbranch(); + }; + + if (xml->enterbranch("FREQUENCY_PARAMETERS")){ + Pfixedfreq=xml->getpar127("fixed_freq",Pfixedfreq); + PfixedfreqET=xml->getpar127("fixed_freq_et",PfixedfreqET); + PDetune=xml->getpar("detune",PDetune,0,16383); + PCoarseDetune=xml->getpar("coarse_detune",PCoarseDetune,0,16383); + PDetuneType=xml->getpar127("detune_type",PDetuneType); + + xml->enterbranch("FREQUENCY_ENVELOPE"); + FreqEnvelope->getfromXML(xml); + xml->exitbranch(); + + xml->enterbranch("FREQUENCY_LFO"); + FreqLfo->getfromXML(xml); + xml->exitbranch(); + xml->exitbranch(); + }; + + if (xml->enterbranch("FILTER_PARAMETERS")){ + PFilterVelocityScale=xml->getpar127("velocity_sensing_amplitude",PFilterVelocityScale); + PFilterVelocityScaleFunction=xml->getpar127("velocity_sensing",PFilterVelocityScaleFunction); + + xml->enterbranch("FILTER"); + GlobalFilter->getfromXML(xml); + xml->exitbranch(); + + xml->enterbranch("FILTER_ENVELOPE"); + FilterEnvelope->getfromXML(xml); + xml->exitbranch(); + + xml->enterbranch("FILTER_LFO"); + FilterLfo->getfromXML(xml); + xml->exitbranch(); + xml->exitbranch(); + }; +}; + + diff --git a/plugins/zynaddsubfx/src/Params/PADnoteParameters.h b/plugins/zynaddsubfx/src/Params/PADnoteParameters.h new file mode 100644 index 000000000..4bfa4c4eb --- /dev/null +++ b/plugins/zynaddsubfx/src/Params/PADnoteParameters.h @@ -0,0 +1,169 @@ +/* + ZynAddSubFX - a software synthesizer + + PADnoteParameters.h - Parameters for PADnote (PADsynth) + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef PAD_NOTE_PARAMETERS_H +#define PAD_NOTE_PARAMETERS_H + +#include "../Misc/XMLwrapper.h" +#include "../DSP/FFTwrapper.h" +#include "../globals.h" +#include "../Synth/OscilGen.h" +#include "../Synth/Resonance.h" +#include "../Misc/Util.h" + +#include "EnvelopeParams.h" +#include "LFOParams.h" +#include "FilterParams.h" +#include "Presets.h" +#include + +class PADnoteParameters:public Presets{ + public: + PADnoteParameters(FFTwrapper *fft_,pthread_mutex_t *mutex_); + ~PADnoteParameters(); + + void defaults(); + void add2XML(XMLwrapper *xml); + void getfromXML(XMLwrapper *xml); + + //returns a value between 0.0-1.0 that represents the estimation perceived bandwidth + REALTYPE getprofile(REALTYPE *smp,int size); + + //parameters + + //the mode: 0 - bandwidth, 1 - discrete (bandwidth=0), 2 - continous + //the harmonic profile is used only on mode 0 + unsigned char Pmode; + + //Harmonic profile (the frequency distribution of a single harmonic) + struct { + struct{//base function + unsigned char type; + unsigned char par1; + }base; + unsigned char freqmult;//frequency multiplier of the distribution + struct{//the modulator of the distribution + unsigned char par1; + unsigned char freq; + }modulator; + + unsigned char width;//the width of the resulting function after the modulation + struct{//the amplitude multiplier of the harmonic profile + unsigned char mode; + unsigned char type; + unsigned char par1; + unsigned char par2; + }amp; + bool autoscale;//if the scale of the harmonic profile is computed automaticaly + unsigned char onehalf;//what part of the base function is used to make the distribution + }Php; + + + unsigned int Pbandwidth;//the values are from 0 to 1000 + unsigned char Pbwscale;//how the bandwidth is increased according to the harmonic's frequency + + struct{//where are positioned the harmonics (on integer multimplier or different places) + unsigned char type; + unsigned char par1,par2,par3;//0..255 + }Phrpos; + + struct {//quality of the samples (how many samples, the length of them,etc.) + unsigned char samplesize; + unsigned char basenote,oct,smpoct; + } Pquality; + + //frequency parameters + //If the base frequency is fixed to 440 Hz + unsigned char Pfixedfreq; + + /* Equal temperate (this is used only if the Pfixedfreq is enabled) + If this parameter is 0, the frequency is fixed (to 440 Hz); + if this parameter is 64, 1 MIDI halftone -> 1 frequency halftone */ + unsigned char PfixedfreqET; + unsigned short int PDetune;//fine detune + unsigned short int PCoarseDetune;//coarse detune+octave + unsigned char PDetuneType;//detune type + + EnvelopeParams *FreqEnvelope; //Frequency Envelope + LFOParams *FreqLfo;//Frequency LFO + + //Amplitude parameters + unsigned char PStereo; + /* Panning - 0 - random + 1 - left + 64 - center + 127 - right */ + unsigned char PPanning; + + unsigned char PVolume; + + unsigned char PAmpVelocityScaleFunction; + + EnvelopeParams *AmpEnvelope; + + LFOParams *AmpLfo; + + unsigned char PPunchStrength,PPunchTime,PPunchStretch,PPunchVelocitySensing; + + //Filter Parameters + FilterParams *GlobalFilter; + + // filter velocity sensing + unsigned char PFilterVelocityScale; + + // filter velocity sensing + unsigned char PFilterVelocityScaleFunction; + + EnvelopeParams *FilterEnvelope; + LFOParams *FilterLfo; + + + + + REALTYPE setPbandwidth(int Pbandwidth);//returns the BandWidth in cents + REALTYPE getNhr(int n);//gets the n-th overtone position relatively to N harmonic + + void applyparameters(bool lockmutex); + void export2wav(std::string basefilename); + + OscilGen *oscilgen; + Resonance *resonance; + + struct{ + int size; + REALTYPE basefreq; + REALTYPE *smp; + }sample[PAD_MAX_SAMPLES],newsample; + + private: + void generatespectrum_bandwidthMode(REALTYPE *spectrum, int size,REALTYPE basefreq,REALTYPE *profile,int profilesize,REALTYPE bwadjust); + void generatespectrum_otherModes(REALTYPE *spectrum, int size,REALTYPE basefreq,REALTYPE *profile,int profilesize,REALTYPE bwadjust); + void deletesamples(); + void deletesample(int n); + + FFTwrapper *fft; + pthread_mutex_t *mutex; +}; + + + +#endif diff --git a/plugins/zynaddsubfx/src/Params/Presets.C b/plugins/zynaddsubfx/src/Params/Presets.C new file mode 100644 index 000000000..8f45a93bf --- /dev/null +++ b/plugins/zynaddsubfx/src/Params/Presets.C @@ -0,0 +1,129 @@ +/* + ZynAddSubFX - a software synthesizer + + Presets.C - Presets and Clipboard management + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include "Presets.h" +#include + + +Presets::Presets(){ + type[0]=0; + nelement=-1; +}; + +Presets::~Presets(){ +}; + +void Presets::setpresettype(const char *type){ + strcpy(this->type,type); +}; + +void Presets::copy(const char *name){ + XMLwrapper *xml=new XMLwrapper(); + + //used only for the clipboard + if (name==NULL) xml->minimal=false; + + char type[MAX_PRESETTYPE_SIZE]; + strcpy(type,this->type); + if (nelement!=-1) strcat(type,"n"); + if (name==NULL) { + if (strstr(type,"Plfo")!=NULL) strcpy(type,"Plfo"); + }; + + xml->beginbranch(type); + if (nelement==-1) add2XML(xml); + else add2XMLsection(xml,nelement); + xml->endbranch(); + + if (name==NULL) presetsstore.copyclipboard(xml,type); + else presetsstore.copypreset(xml,type,name); + + delete(xml); + nelement=-1; +}; + +void Presets::paste(int npreset){ + char type[MAX_PRESETTYPE_SIZE]; + strcpy(type,this->type); + if (nelement!=-1) strcat(type,"n"); + if (npreset==0){ + if (strstr(type,"Plfo")!=NULL) strcpy(type,"Plfo"); + }; + + XMLwrapper *xml=new XMLwrapper(); + if (npreset==0){ + if (!checkclipboardtype()) { + nelement=-1; + delete(xml); + return; + }; + if (!presetsstore.pasteclipboard(xml)) { + delete(xml); + nelement=-1; + return; + }; + } else { + if (!presetsstore.pastepreset(xml,npreset)) { + delete(xml); + nelement=-1; + return; + }; + }; + + if (xml->enterbranch(type)==0) { + nelement=-1; + return; + }; + if (nelement==-1) { + defaults(); + getfromXML(xml); + } else { + defaults(nelement); + getfromXMLsection(xml,nelement); + }; + xml->exitbranch(); + + delete(xml); + nelement=-1; +}; + +bool Presets::checkclipboardtype(){ + char type[MAX_PRESETTYPE_SIZE]; + strcpy(type,this->type); + if (nelement!=-1) strcat(type,"n"); + + return(presetsstore.checkclipboardtype(type)); +}; + +void Presets::setelement(int n){ + nelement=n; +}; + +void Presets::rescanforpresets(){ + presetsstore.rescanforpresets(type); +}; + + +void Presets::deletepreset(int npreset){ + presetsstore.deletepreset(npreset); +}; + diff --git a/plugins/zynaddsubfx/src/Params/Presets.h b/plugins/zynaddsubfx/src/Params/Presets.h new file mode 100644 index 000000000..41211ccc2 --- /dev/null +++ b/plugins/zynaddsubfx/src/Params/Presets.h @@ -0,0 +1,58 @@ +/* + ZynAddSubFX - a software synthesizer + + Presets.h - Presets and Clipboard management + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef PRESETS_H +#define PRESETS_H + +#include "../Misc/XMLwrapper.h" + +#include "PresetsStore.h" + +class Presets{ + public: + Presets(); + virtual ~Presets(); + + void copy(const char *name);//if name==NULL, the clipboard is used + void paste(int npreset);//npreset==0 for clipboard + bool checkclipboardtype(); + void deletepreset(int npreset); + + char type[MAX_PRESETTYPE_SIZE]; + void setelement(int n); + + void rescanforpresets(); + + protected: + void setpresettype(const char *type); + private: + virtual void add2XML(XMLwrapper *xml)=0; + virtual void getfromXML(XMLwrapper *xml)=0; + virtual void defaults()=0; + virtual void add2XMLsection(XMLwrapper *xml,int n){}; + virtual void getfromXMLsection(XMLwrapper *xml,int n){}; + virtual void defaults(int n){}; + int nelement; +}; + +#endif + diff --git a/plugins/zynaddsubfx/src/Params/PresetsStore.C b/plugins/zynaddsubfx/src/Params/PresetsStore.C new file mode 100644 index 000000000..8ad87755a --- /dev/null +++ b/plugins/zynaddsubfx/src/Params/PresetsStore.C @@ -0,0 +1,183 @@ +/* + ZynAddSubFX - a software synthesizer + + PresetsStore.C - Presets and Clipboard store + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ +#include +#include +#include +#include + +#include "PresetsStore.h" +#include "../Misc/Util.h" + +PresetsStore presetsstore; + +PresetsStore::PresetsStore(){ + clipboard.data=NULL; + clipboard.type[0]=0; + + for (int i=0;igetXMLdata(); +}; + +bool PresetsStore::pasteclipboard(XMLwrapper *xml){ + if (clipboard.data!=NULL) xml->putXMLdata(clipboard.data); + else return(false); + return(true); +}; + +bool PresetsStore::checkclipboardtype(char *type){ + //makes LFO's compatible + if ((strstr(type,"Plfo")!=NULL)&&(strstr(clipboard.type,"Plfo")!=NULL)) return(true); + return(strcmp(type,clipboard.type)==0); +}; + +//Presets management +void PresetsStore::clearpresets(){ + for (int i=0;iname)==NULL)||((p2->name)==NULL)) return(0); + + return(strcasecmp(p1->name,p2->name)<0); +}; + + +void PresetsStore::rescanforpresets(char *type){ + clearpresets(); + int presetk=0; + char ftype[MAX_STRING_SIZE]; + snprintf(ftype,MAX_STRING_SIZE,".%s.xpz",type); + + for (int i=0;id_name; + if (strstr(filename,ftype)==NULL) continue; + + + presets[presetk].file=new char [MAX_STRING_SIZE]; + presets[presetk].name=new char [MAX_STRING_SIZE]; + char tmpc=dirname[strlen(dirname)-1]; + const char *tmps; + if ((tmpc=='/')||(tmpc=='\\')) tmps=""; + else tmps="/"; + snprintf(presets[presetk].file,MAX_STRING_SIZE,"%s%s%s",dirname,tmps,filename); + snprintf(presets[presetk].name,MAX_STRING_SIZE,"%s",filename); + + char *tmp=strstr(presets[presetk].name,ftype); + if (tmp!=NULL) tmp[0]='\0'; + presetk++; if (presetk>=MAX_PRESETS) return; + }; + + closedir(dir); + }; + + //sort the presets + for (int j=0;j='0')&&(c<='9')) continue; + if ((c>='A')&&(c<='Z')) continue; + if ((c>='a')&&(c<='z')) continue; + if ((c=='-')||(c==' ')) continue; + tmpfilename[i]='_'; + }; + + const char *dirname=config.cfg.presetsDirList[0]; + char tmpc=dirname[strlen(dirname)-1]; + const char *tmps; + if ((tmpc=='/')||(tmpc=='\\')) tmps=""; + else tmps="/"; + + snprintf(filename,MAX_STRING_SIZE,"%s%s%s.%s.xpz",dirname,tmps,name,type); + + xml->saveXMLfile(filename); +}; + +bool PresetsStore::pastepreset(XMLwrapper *xml, int npreset){ + npreset--; + if (npreset>=MAX_PRESETS) return(false); + char *filename=presets[npreset].file; + if (filename==NULL) return(false); + bool result=(xml->loadXMLfile(filename)>=0); + return(result); +}; + +void PresetsStore::deletepreset(int npreset){ + npreset--; + if (npreset>=MAX_PRESETS) return; + char *filename=presets[npreset].file; + if (filename==NULL) return; + remove(filename); +}; + diff --git a/plugins/zynaddsubfx/src/Params/PresetsStore.h b/plugins/zynaddsubfx/src/Params/PresetsStore.h new file mode 100644 index 000000000..bbbecccc3 --- /dev/null +++ b/plugins/zynaddsubfx/src/Params/PresetsStore.h @@ -0,0 +1,63 @@ +/* + ZynAddSubFX - a software synthesizer + + PresetsStore.C - Presets and Clipboard store + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include "../Misc/XMLwrapper.h" +#include "../Misc/Config.h" + +#define MAX_PRESETTYPE_SIZE 30 +#define MAX_PRESETS 1000 + +class PresetsStore{ + public: + PresetsStore(); + ~PresetsStore(); + + //Clipboard stuff + void copyclipboard(XMLwrapper *xml,char *type); + bool pasteclipboard(XMLwrapper *xml); + bool checkclipboardtype(char *type); + + //presets stuff + void copypreset(XMLwrapper *xml,char *type, const char *name); + bool pastepreset(XMLwrapper *xml, int npreset); + void deletepreset(int npreset); + + struct presetstruct{ + char *file; + char *name; + }; + presetstruct presets[MAX_PRESETS]; + + void rescanforpresets(char *type); + + private: + struct { + char *data; + char type[MAX_PRESETTYPE_SIZE]; + } clipboard; + + void clearpresets(); + +}; + +extern PresetsStore presetsstore; + diff --git a/plugins/zynaddsubfx/src/Params/SUBnoteParameters.C b/plugins/zynaddsubfx/src/Params/SUBnoteParameters.C new file mode 100644 index 000000000..2d387de46 --- /dev/null +++ b/plugins/zynaddsubfx/src/Params/SUBnoteParameters.C @@ -0,0 +1,238 @@ +/* + ZynAddSubFX - a software synthesizer + + SUBnoteParameters.C - Parameters for SUBnote (SUBsynth) + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include "../globals.h" +#include "SUBnoteParameters.h" +#include + +SUBnoteParameters::SUBnoteParameters():Presets(){ + setpresettype("Psubsyth"); + AmpEnvelope=new EnvelopeParams(64,1); + AmpEnvelope->ADSRinit_dB(0,40,127,25); + FreqEnvelope=new EnvelopeParams(64,0); + FreqEnvelope->ASRinit(30,50,64,60); + BandWidthEnvelope=new EnvelopeParams(64,0); + BandWidthEnvelope->ASRinit_bw(100,70,64,60); + + GlobalFilter=new FilterParams(2,80,40); + GlobalFilterEnvelope=new EnvelopeParams(0,1); + GlobalFilterEnvelope->ADSRinit_filter(64,40,64,70,60,64); + + defaults(); +}; + + +void SUBnoteParameters::defaults(){ + PVolume=96; + PPanning=64; + PAmpVelocityScaleFunction=90; + + Pfixedfreq=0; + PfixedfreqET=0; + Pnumstages=2; + Pbandwidth=40; + Phmagtype=0; + Pbwscale=64; + Pstereo=1; + Pstart=1; + + PDetune=8192; + PCoarseDetune=0; + PDetuneType=1; + PFreqEnvelopeEnabled=0; + PBandWidthEnvelopeEnabled=0; + + for (int n=0;ndefaults(); + FreqEnvelope->defaults(); + BandWidthEnvelope->defaults(); + GlobalFilter->defaults(); + GlobalFilterEnvelope->defaults(); + +}; + + + +SUBnoteParameters::~SUBnoteParameters(){ + delete (AmpEnvelope); + delete (FreqEnvelope); + delete (BandWidthEnvelope); + delete (GlobalFilter); + delete (GlobalFilterEnvelope); +}; + + + + +void SUBnoteParameters::add2XML(XMLwrapper *xml){ + xml->addpar("num_stages",Pnumstages); + xml->addpar("harmonic_mag_type",Phmagtype); + xml->addpar("start",Pstart); + + xml->beginbranch("HARMONICS"); + for (int i=0;iminimal)) continue; + xml->beginbranch("HARMONIC",i); + xml->addpar("mag",Phmag[i]); + xml->addpar("relbw",Phrelbw[i]); + xml->endbranch(); + }; + xml->endbranch(); + + xml->beginbranch("AMPLITUDE_PARAMETERS"); + xml->addparbool("stereo",Pstereo); + xml->addpar("volume",PVolume); + xml->addpar("panning",PPanning); + xml->addpar("velocity_sensing",PAmpVelocityScaleFunction); + xml->beginbranch("AMPLITUDE_ENVELOPE"); + AmpEnvelope->add2XML(xml); + xml->endbranch(); + xml->endbranch(); + + xml->beginbranch("FREQUENCY_PARAMETERS"); + xml->addparbool("fixed_freq",Pfixedfreq); + xml->addpar("fixed_freq_et",PfixedfreqET); + + xml->addpar("detune",PDetune); + xml->addpar("coarse_detune",PCoarseDetune); + xml->addpar("detune_type",PDetuneType); + + xml->addpar("bandwidth",Pbandwidth); + xml->addpar("bandwidth_scale",Pbwscale); + + xml->addparbool("freq_envelope_enabled",PFreqEnvelopeEnabled); + if ((PFreqEnvelopeEnabled!=0)||(!xml->minimal)){ + xml->beginbranch("FREQUENCY_ENVELOPE"); + FreqEnvelope->add2XML(xml); + xml->endbranch(); + }; + + xml->addparbool("band_width_envelope_enabled",PBandWidthEnvelopeEnabled); + if ((PBandWidthEnvelopeEnabled!=0)||(!xml->minimal)){ + xml->beginbranch("BANDWIDTH_ENVELOPE"); + BandWidthEnvelope->add2XML(xml); + xml->endbranch(); + }; + xml->endbranch(); + + xml->beginbranch("FILTER_PARAMETERS"); + xml->addparbool("enabled",PGlobalFilterEnabled); + if ((PGlobalFilterEnabled!=0)||(!xml->minimal)){ + xml->beginbranch("FILTER"); + GlobalFilter->add2XML(xml); + xml->endbranch(); + + xml->addpar("filter_velocity_sensing",PGlobalFilterVelocityScaleFunction); + xml->addpar("filter_velocity_sensing_amplitude",PGlobalFilterVelocityScale); + + xml->beginbranch("FILTER_ENVELOPE"); + GlobalFilterEnvelope->add2XML(xml); + xml->endbranch(); + }; + xml->endbranch(); +}; + +void SUBnoteParameters::getfromXML(XMLwrapper *xml){ + Pnumstages=xml->getpar127("num_stages",Pnumstages); + Phmagtype=xml->getpar127("harmonic_mag_type",Phmagtype); + Pstart=xml->getpar127("start",Pstart); + + if (xml->enterbranch("HARMONICS")){ + Phmag[0]=0; + for (int i=0;ienterbranch("HARMONIC",i)==0) continue; + Phmag[i]=xml->getpar127("mag",Phmag[i]); + Phrelbw[i]=xml->getpar127("relbw",Phrelbw[i]); + xml->exitbranch(); + }; + xml->exitbranch(); + }; + + if (xml->enterbranch("AMPLITUDE_PARAMETERS")){ + Pstereo=xml->getparbool("stereo",Pstereo); + PVolume=xml->getpar127("volume",PVolume); + PPanning=xml->getpar127("panning",PPanning); + PAmpVelocityScaleFunction=xml->getpar127("velocity_sensing",PAmpVelocityScaleFunction); + if (xml->enterbranch("AMPLITUDE_ENVELOPE")){ + AmpEnvelope->getfromXML(xml); + xml->exitbranch(); + }; + xml->exitbranch(); + }; + + if (xml->enterbranch("FREQUENCY_PARAMETERS")){ + Pfixedfreq=xml->getparbool("fixed_freq",Pfixedfreq); + PfixedfreqET=xml->getpar127("fixed_freq_et",PfixedfreqET); + + PDetune=xml->getpar("detune",PDetune,0,16383); + PCoarseDetune=xml->getpar("coarse_detune",PCoarseDetune,0,16383); + PDetuneType=xml->getpar127("detune_type",PDetuneType); + + Pbandwidth=xml->getpar127("bandwidth",Pbandwidth); + Pbwscale=xml->getpar127("bandwidth_scale",Pbwscale); + + PFreqEnvelopeEnabled=xml->getparbool("freq_envelope_enabled",PFreqEnvelopeEnabled); + if (xml->enterbranch("FREQUENCY_ENVELOPE")){ + FreqEnvelope->getfromXML(xml); + xml->exitbranch(); + }; + + PBandWidthEnvelopeEnabled=xml->getparbool("band_width_envelope_enabled",PBandWidthEnvelopeEnabled); + if (xml->enterbranch("BANDWIDTH_ENVELOPE")){ + BandWidthEnvelope->getfromXML(xml); + xml->exitbranch(); + }; + + xml->exitbranch(); + }; + + if (xml->enterbranch("FILTER_PARAMETERS")){ + PGlobalFilterEnabled=xml->getparbool("enabled",PGlobalFilterEnabled); + if (xml->enterbranch("FILTER")){ + GlobalFilter->getfromXML(xml); + xml->exitbranch(); + }; + + PGlobalFilterVelocityScaleFunction=xml->getpar127("filter_velocity_sensing",PGlobalFilterVelocityScaleFunction); + PGlobalFilterVelocityScale=xml->getpar127("filter_velocity_sensing_amplitude",PGlobalFilterVelocityScale); + + if (xml->enterbranch("FILTER_ENVELOPE")){ + GlobalFilterEnvelope->getfromXML(xml); + xml->exitbranch(); + }; + + xml->exitbranch(); + }; +}; + + + + diff --git a/plugins/zynaddsubfx/src/Params/SUBnoteParameters.h b/plugins/zynaddsubfx/src/Params/SUBnoteParameters.h new file mode 100644 index 000000000..419fc25d6 --- /dev/null +++ b/plugins/zynaddsubfx/src/Params/SUBnoteParameters.h @@ -0,0 +1,105 @@ +/* + ZynAddSubFX - a software synthesizer + + SUBnoteParameters.h - Parameters for SUBnote (SUBsynth) + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef SUB_NOTE_PARAMETERS_H +#define SUB_NOTE_PARAMETERS_H + +#include "../globals.h" +#include "../Misc/XMLwrapper.h" +#include "EnvelopeParams.h" +#include "FilterParams.h" +#include "Presets.h" + +class SUBnoteParameters:public Presets{ + public: + SUBnoteParameters(); + ~SUBnoteParameters(); + + void add2XML(XMLwrapper *xml); + void defaults(); + void getfromXML(XMLwrapper *xml); + + //Parameters + //AMPLITUDE PARAMETRERS + unsigned char Pstereo;//0 for mono,1 for stereo + unsigned char PVolume; + unsigned char PPanning; + unsigned char PAmpVelocityScaleFunction; + EnvelopeParams *AmpEnvelope; + + //Frequency Parameters + unsigned short int PDetune; + unsigned short int PCoarseDetune; + unsigned char PDetuneType; + unsigned char PFreqEnvelopeEnabled; + EnvelopeParams *FreqEnvelope; + unsigned char PBandWidthEnvelopeEnabled; + EnvelopeParams *BandWidthEnvelope; + + //Filter Parameters (Global) + unsigned char PGlobalFilterEnabled; + FilterParams *GlobalFilter; + unsigned char PGlobalFilterVelocityScale; + unsigned char PGlobalFilterVelocityScaleFunction; + EnvelopeParams *GlobalFilterEnvelope; + + + //Other Parameters + + //If the base frequency is fixed to 440 Hz + unsigned char Pfixedfreq; + + /* Equal temperate (this is used only if the Pfixedfreq is enabled) + If this parameter is 0, the frequency is fixed (to 440 Hz); + if this parameter is 64, 1 MIDI halftone -> 1 frequency halftone */ + unsigned char PfixedfreqET; + + + //how many times the filters are applied + unsigned char Pnumstages; + + //bandwidth + unsigned char Pbandwidth; + + //How the magnitudes are computed (0=linear,1=-60dB,2=-60dB) + unsigned char Phmagtype; + + //Magnitudes + unsigned char Phmag[MAX_SUB_HARMONICS]; + + //Relative BandWidth ("64"=1.0) + unsigned char Phrelbw[MAX_SUB_HARMONICS]; + + //how much the bandwidth is increased according to lower/higher frequency; 64-default + unsigned char Pbwscale; + + //how the harmonics start("0"=0,"1"=random,"2"=1) + unsigned char Pstart; + + + private: +}; + +#endif + + + diff --git a/plugins/zynaddsubfx/src/README.txt b/plugins/zynaddsubfx/src/README.txt new file mode 100644 index 000000000..daadfc9fd --- /dev/null +++ b/plugins/zynaddsubfx/src/README.txt @@ -0,0 +1,95 @@ +ZynAddSubFX +----------- +It is a realtime software synthesizer for Linux and Windows with many features. Please see the docs for details. +Copyright (c) 2002-2006 Nasca Octavian Paul and others contribuitors +e-mail: zynaddsubfx AT yahoo D0T com +ZynAddSubFX is free program and is distribuited WITH NO WARRANTY. It is licensed under GNU General Public License version 2 (and only version 2) - see the file COPYING. + + --==## PLEASE SHARE YOUR INSTRUMENTS/MASTER SETTINGS ##==-- + --==## MADE WITH ZynAddSubFX ##==-- + Here is the mailing list where you can share your patches with others: + http://lists.sourceforge.net/mailman/listinfo/zynaddsubfx-user + + +The project page is + http://sourceforge.net/projects/zynaddsubfx + or + http://zynaddsubfx.sourceforge.net + +ZynAddSubFX is also available on many Internet sites like: + http://www-ccrma.stanford.edu/planetccrma/software/soundapps.html (Planet CCRMA) + http://www.hitsquad.com/smm/programs/ZynAddSubFX/ + http://freshmeat.net/projects/zynaddsubfx/ + http://ibiblio.org/pub/Linux/apps/sound/midi/ + or search "ZynAddSubFX" on a search engine (like www.google.com). + + +Requirements: +------------- + - a fast computer + - Linux (tested with RedHat 7.2,7.3,etc.) or Windows + - FFTW 2.x.x (tested with fftw 2.0.5, 2.1.3) - necesary for + Fast Fourier computations + - MXML-2.2 library from http://www.easysw.com/~mike/mxml/ + - zlib library from http://www.zlib.org - this exists in most linux distributions + - (for Linux) OpenSoundSystem (OSS) (if you don't have ALSA, only) + - (for Windows) pthreads, portaudio + +Not requred, but recomanded: +--------------------------- + + - FLTK 1.x.x (tested with fltk 1.1.0, 1.1.1, 1.1.2,etc.) + - ALSA 0.9.x or later (with OSS emulation, if you don't use JACK) + - JACKit - if you want to use it you must enable compilation for JACK in Makefile.inc + - a VST host for the VST version + +Compilation: +------------ + If you want to compile on Windows, please read compile.win32 file. + If you don't know how to compile, you may download binaries from Planet CCRMA (see above, on sites). + First set what should sound input/ouput should use in Makefile.inc in src/ directory. + Then "make" from the "src/" directory. Hope all goes right. If the compiler complains something about FFTwrapper.h and FFTW library headers(rfftw.h or fftw.h) please read the docs from DSP/FFTwrapper.h . + To compile the Spliter, run "compile.sh" from the "Spliter" directory. + To compile the Controller, run "compile.sh" from the "Controller" directory. + +Running on LINUX +---------------- + *AUDIO OUTPUT + A) OSS (Open Sound System) + B) JACK (JACK Audio Connection Kit) + + *MIDI INPUT* + There are 2 possibilites of midi inputs (depends on what you have chosen in Makefile.inc to use - OSS or ALSA). + A) ALSA (Advenced Linux Sound Architecture) + 1) Launch zynaddsubfx + 2) ZynAddSubFX will make a virtual MIDI port. + You can connect other midi devices (like a real MIDI keyboard, midi sequencers which supports ALSA or virtual keyboard - like vkeybd). + To connect, use "aconnect" or "alsa-patch-bay"; usualy the port of ZynAddSubFX is 128:0 or 129:0. + 3) You are ready to play + + It is possible to use midi sequencer/other software that doesn't supports ALSA with ZynAddSubFX, but this is a bit more complicated. + Search on Internet for "HOWTO Use MIDI Sequencers With Softsynths" by Frank Barknecht, if you want to do this. + + + B) OSS (Open Sound System) + 1) Launch zynaddsubfx + 2) Connect the midi keyboard + + As you have seen the OSS option needs a real midi keyboard. If you don't have it, you can download/install ALSA from www.alsa-project.org + +Running on WINDOWS +------------------ + If you launch zynaddsubfx.exe and nothing happens, you need pthreadGC.dll in the same directory (or windows directory). The dll files are distribuited with zynaddsubfx windows binaries. + It might be possible that the latency will be very high. If this happens, you have to set the environment variable PA_MIN_LATENCY_MSEC to a value that represents the latency in miliseconds. + Eg: (in autoexec.bat or launched before running zynaddsubfx) "set PA_MIN_LATENCY_MSEC=50" + Warning: if the value is too low, you might ecounter severe dropouts on zynaddsubfx. You'll have to set to a higher value and turn off automated background tasks (like virus scanners, email clients, etc.). + If you have more cards, you can select the desired card where you can play audio with the evironment variable "PA_RECOMMENDED_OUTPUT_DEVICE" + Eg: "set PA_RECOMMENDED_OUTPUT_DEVICE=1" + A better way to set all of this, I will put on next versions. + +Please send me instruments,banks,master settings,songs(midi+...xmz files) done with ZynAddSubFX. I'll apreciate this. + + +Have fun! :-) + + diff --git a/plugins/zynaddsubfx/src/Seq/MIDIEvents.C b/plugins/zynaddsubfx/src/Seq/MIDIEvents.C new file mode 100644 index 000000000..cc44b5711 --- /dev/null +++ b/plugins/zynaddsubfx/src/Seq/MIDIEvents.C @@ -0,0 +1,85 @@ +/* + ZynAddSubFX - a software synthesizer + + MIDIEvents.C - It stores the midi events from midi file or sequencer + Copyright (C) 2003-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include "MIDIEvents.h" +#include +#include + +MIDIEvents::MIDIEvents(){ +}; + +MIDIEvents::~MIDIEvents(){ +}; + + +/************** Track stuff ***************/ +void MIDIEvents::writeevent(list *l,event *ev){ + listpos *tmp=new listpos; + tmp->next=NULL; + tmp->ev=*ev; + if (l->current!=NULL) l->current->next=tmp; + else l->first=tmp; + l->current=tmp; +// printf("Wx%x ",(int) l->current); +// printf("-> %d \n",l->current->ev.deltatime); + l->size++; +}; + +void MIDIEvents::readevent(list *l,event *ev){ + if (l->current==NULL) { + ev->type=-1; + return; + }; + *ev=l->current->ev; + l->current=l->current->next; + + //test + if (l->current!=NULL) { +// ev->deltatime=10000; +// printf("Rx%d\n",l->current->ev.deltatime); +// printf("Rx%x ",(int) l->current); +// printf("-> %d (next=%x) \n",(int)l->current->ev.deltatime,(int)l->current->next); + }; + +}; + + +void MIDIEvents::rewindlist(list *l){ + l->current=l->first; +}; + +void MIDIEvents::deletelist(list *l){ + l->current=l->first; + if (l->current==NULL) return; + while (l->current->next!=NULL){ + listpos *tmp=l->current; + l->current=l->current->next; + delete(tmp); + }; + deletelistreference(l); +}; + +void MIDIEvents::deletelistreference(list *l){ + l->current=l->first=NULL; + l->size=0; + l->length=0.0; +}; diff --git a/plugins/zynaddsubfx/src/Seq/MIDIEvents.h b/plugins/zynaddsubfx/src/Seq/MIDIEvents.h new file mode 100644 index 000000000..3c4b91bda --- /dev/null +++ b/plugins/zynaddsubfx/src/Seq/MIDIEvents.h @@ -0,0 +1,66 @@ +/* + ZynAddSubFX - a software synthesizer + + MIDIEvents.h - It stores the midi events from midi file or sequencer + Copyright (C) 2003-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ +#ifndef MIDI_EVENTS_H +#define MIDI_EVENTS_H + +#include "../globals.h" +#define NUM_MIDI_TRACKS NUM_MIDI_CHANNELS + +class MIDIEvents{ + friend class MIDIFile; + public: + MIDIEvents(); + ~MIDIEvents(); + + protected: + + /* Events */ + struct event{ + int deltatime; + int channel;//on what midi channel is + int type,par1,par2;//type=1 for note, type=2 for controller, type=255 for time messages + } tmpevent; + struct listpos{ + event ev; + struct listpos *next; + }; + struct list{ + listpos *first,*current; + int size;//how many events are + double length;//in seconds + }; + struct { + list track;//the stored track + list record;//the track being "recorded" from midi + } miditrack[NUM_MIDI_TRACKS]; + + void writeevent(list *l,event *ev); + void readevent(list *l,event *ev); + + void rewindlist(list *l); + void deletelist(list *l); + void deletelistreference(list *l); + +}; + + +#endif diff --git a/plugins/zynaddsubfx/src/Seq/MIDIFile.C b/plugins/zynaddsubfx/src/Seq/MIDIFile.C new file mode 100644 index 000000000..c9d1f9c08 --- /dev/null +++ b/plugins/zynaddsubfx/src/Seq/MIDIFile.C @@ -0,0 +1,389 @@ +/* + ZynAddSubFX - a software synthesizer + + MIDIFile.C - MIDI file loader + Copyright (C) 2003-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include +#include +#include "MIDIFile.h" + + +MIDIFile::MIDIFile(){ + midifile=NULL; + midifilesize=0; + midifilek=0; + midieof=false; + me=NULL; +}; + +MIDIFile::~MIDIFile(){ + clearmidifile(); +}; + +int MIDIFile::loadfile(char *filename){ + clearmidifile(); + + FILE *file=fopen(filename,"r"); + if (file==NULL) return(-1); + + char header[4]; + ZERO(header,4); + fread(header,4,1,file); + + //test to see if this a midi file + if ((header[0]!='M')||(header[1]!='T')||(header[2]!='h')||(header[3]!='d')){ + fclose(file); + return(-1); + }; + + //get the filesize + fseek(file,0,SEEK_END); + midifilesize=ftell(file); + rewind(file); + + midifile=new unsigned char[midifilesize]; + ZERO(midifile,midifilesize); + fread(midifile,midifilesize,1,file); + fclose(file); + +// for (int i=0;ime=me_; + + //read the header + int chunk=getint32();//MThd + if (chunk!=0x4d546864) return(-1); + int size=getint32(); + if (size!=6) return(-1);//header is always 6 bytes long + + + int format=getint16(); + printf("format %d\n",format); + + int ntracks=getint16();//this is always 1 if the format is "0" + printf("ntracks %d\n",ntracks); + + int division=getint16(); + printf("division %d\n",division); + if (division>=0){//delta time units in each a quater note +// tick=???; + } else {//SMPTE (frames/second and ticks/frame) + printf("ERROR:in MIDIFile.C::parsemidifile() - SMPTE not implemented yet."); + }; + + if (ntracks>=NUM_MIDI_TRACKS) ntracks=NUM_MIDI_TRACKS-1; + + for (int n=0;nme=NULL; + return(0); +}; + +//private members + + +int MIDIFile::parsetrack(int ntrack){ + printf("\n--==*Reading track %d **==--\n",ntrack); + + int chunk=getint32();//MTrk + if (chunk!=0x4d54726b) return(-1); + + int size=getint32(); + printf("size = %d\n",size); + + int oldmidifilek=midifilek; + + unsigned char lastmsg=0; + unsigned int dt=0; + + while(!midieof){ + unsigned int msgdeltatime=getvarint32(); + +/// printf("MSGDELTATIME = %d\n",msgdeltatime); + +// dt+=msgdeltatime; + + int msg=peekbyte(); +/// printf("raw msg=0x%x ",msg); + if (msg<0x80) { + msg=lastmsg; + } else { + lastmsg=msg; + getbyte(); + }; +/// printf("msg=0x%x\n",msg); + +// dt+=msgdeltatime; + add_dt(ntrack, msgdeltatime); + + unsigned int mtype,mlength; + + switch(msg){ + case 0x80 ... 0x8f://note on off + parsenoteoff(ntrack,msg & 0x0f,dt); + dt=0; + break; + case 0x90 ... 0x9f://note on (or note off) + parsenoteon(ntrack,msg & 0x0f,dt); + dt=0; + break; + case 0xa0 ... 0xaf://aftertouch - ignored + skipnbytes(2); + break; + case 0xb0 ... 0xbf://control change + parsecontrolchange(ntrack,msg & 0x0f,dt); + dt=0; + break; + case 0xc0 ... 0xcf://program change - ignored + skipnbytes(1); + break; + case 0xd0 ... 0xdf://channel pressure - ignored + skipnbytes(1); + break; + case 0xe0 ... 0xef://channel mode messages + skipnbytes(2); + break; + case 0xf0://sysex - ignored + while (getbyte()!=0xf7){ + if (midieof) break; + }; + break; + case 0xf7://sysex (another type) - ignored + skipnbytes(getvarint32()); + break; + + case 0xff://meta-event + mtype=getbyte(); + mlength=getbyte(); + parsemetaevent(mtype,mlength); + break; + + default: + getbyte(); + printf("UNKNOWN message! 0x%x\n",msg); + return(-1); + break; + }; + + + + if (midieof) return(-1); + + if ((midifilek-oldmidifilek)==size) break; + else if((midifilek-oldmidifilek)>size) return(-1); +// if (size!=6) return(-1);//header is always 6 bytes long + }; + + printf("End Track\n\n"); + + return(0); +}; + + +void MIDIFile::parsenoteoff(char ntrack,char chan,unsigned int dt){ + unsigned char note; + note=getbyte(); + + unsigned char noteoff_velocity=getbyte();//unused by zynaddsubfx + noteoff_velocity=0; + if (chan>=NUM_MIDI_CHANNELS) return; + + me->tmpevent.deltatime=convertdt(dt); + me->tmpevent.type=1; + me->tmpevent.par1=note; + me->tmpevent.par2=0; + me->tmpevent.channel=chan; + + printf("Note off:%d \n",note); + + ///test +// ntrack=0; + + me->writeevent(&me->miditrack[(int)ntrack].record,&me->tmpevent); + +}; + + +void MIDIFile::parsenoteon(char ntrack,char chan,unsigned int dt){ + unsigned char note,vel; + note=getbyte(); + vel=getbyte(); + +// printf("ntrack=%d\n",ntrack); + printf("[dt %d ] Note on:%d %d\n",dt,note,vel); + + if (chan>=NUM_MIDI_CHANNELS) return; + + me->tmpevent.deltatime=convertdt(dt); + me->tmpevent.type=1; + me->tmpevent.par1=note; + me->tmpevent.par2=vel; + me->tmpevent.channel=chan; + me->writeevent(&me->miditrack[(int)ntrack].record,&me->tmpevent); + + + +}; + +void MIDIFile::parsecontrolchange(char ntrack,char chan,unsigned int dt){ + unsigned char control,value; + control=getbyte(); + value=getbyte(); + + if (chan>=NUM_MIDI_CHANNELS) return; + + printf("[dt %d] Control change:%d %d\n",dt,control,value); + + me->tmpevent.deltatime=convertdt(dt); + me->tmpevent.type=2; + me->tmpevent.par1=control;//???????????? ma uit la Sequencer::recordnote() din varianele vechi de zyn + me->tmpevent.par2=value; + me->tmpevent.channel=chan; + me->writeevent(&me->miditrack[(int)ntrack].record,&me->tmpevent); + +}; + +void MIDIFile::parsepitchwheel(char ntrack,char chan, unsigned int dt){ + unsigned char valhi,vallo; + vallo=getbyte(); + valhi=getbyte(); + + if (chan>=NUM_MIDI_CHANNELS) return; + + int value=(int)valhi*128+vallo; + + printf("[dt %d] Pitch wheel:%d\n",dt,value); + +}; + +void MIDIFile::parsemetaevent(unsigned char mtype,unsigned char mlength){ + int oldmidifilek=midifilek; + printf("meta-event type=0x%x length=%d\n",mtype,mlength); + + + + midifilek=oldmidifilek+mlength; + +}; + +void MIDIFile::add_dt(char ntrack, unsigned int dt){ + me->tmpevent.deltatime=convertdt(dt); + me->tmpevent.type=255; + me->tmpevent.par1=0; + me->tmpevent.par2=0; + me->tmpevent.channel=0; + me->writeevent(&me->miditrack[(int)ntrack].record,&me->tmpevent); +}; + + +unsigned int MIDIFile::convertdt(unsigned int dt){ + double result=dt; + printf("DT=%d\n",dt); + + return((int) (result*15.0)); +}; + + +void MIDIFile::clearmidifile(){ + if (midifile!=NULL) delete(midifile); + midifile=NULL; + midifilesize=0; + midifilek=0; + midieof=false; + data.tick=0.05; +}; + +unsigned char MIDIFile::getbyte(){ + if (midifilek>=midifilesize) { + midieof=true; + return(0); + }; + +/// printf("(%d) ",midifile[midifilek]); + return(midifile[midifilek++]); +}; + +unsigned char MIDIFile::peekbyte(){ + if (midifilek>=midifilesize) { + midieof=true; + return(0); + }; + return(midifile[midifilek]); +}; + +unsigned int MIDIFile::getint32(){ + unsigned int result=0; + for (int i=0;i<4;i++) { + result=result*256+getbyte(); + }; + if (midieof) result=0; + return(result); +}; + +unsigned short int MIDIFile::getint16(){ + unsigned short int result=0; + for (int i=0;i<2;i++) { + result=result*256+getbyte(); + }; + if (midieof) result=0; + return(result); +}; + +unsigned int MIDIFile::getvarint32(){ + unsigned long result=0; + unsigned char b; + +/// printf("\n[start]"); + + if ((result = getbyte()) & 0x80) { + result &= 0x7f; + do { + b=getbyte(); + result = (result << 7) + (b & 0x7f); + }while (b & 0x80); + } +/// printf("[end - result= %d]\n",result); + return result; +}; + + +void MIDIFile::skipnbytes(int n){ + midifilek+=n; + if (midifilek>=midifilesize){ + midifilek=midifilesize-1; + midieof=true; + }; +}; + diff --git a/plugins/zynaddsubfx/src/Seq/MIDIFile.h b/plugins/zynaddsubfx/src/Seq/MIDIFile.h new file mode 100644 index 000000000..8b300c13b --- /dev/null +++ b/plugins/zynaddsubfx/src/Seq/MIDIFile.h @@ -0,0 +1,90 @@ +/* + ZynAddSubFX - a software synthesizer + + MIDIFile.h - MIDI file loader + Copyright (C) 2003-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef MIDIFILE_H +#define MIDIFILE_H + +#include "../globals.h" +#include "MIDIEvents.h" + +class MIDIFile{ + public: + MIDIFile(); + ~MIDIFile(); + + //returns -1 if there is an error, otherwise 0 + int loadfile(char *filename); + + //returns -1 if there is an error, otherwise 0 + int parsemidifile(MIDIEvents *me_); + + private: + MIDIEvents *me; + + unsigned char *midifile; + int midifilesize,midifilek; + bool midieof; + + //returns -1 if there is an error, otherwise 0 + int parsetrack(int ntrack); + + void parsenoteoff(char ntrack,char chan,unsigned int dt); + void parsenoteon(char ntrack,char chan,unsigned int dt); + void parsecontrolchange(char ntrack,char chan,unsigned int dt); + void parsepitchwheel(char ntrack,char chan, unsigned int dt); + void parsemetaevent(unsigned char mtype,unsigned char mlength); + + void add_dt(char ntrack, unsigned int dt); + + void clearmidifile(); + + //convert the delta-time to internal format + unsigned int convertdt(unsigned int dt); + + /* Low Level MIDIfile functions */ + + //get a byte from the midifile + unsigned char getbyte(); + + //peek the current byte from the midifile + unsigned char peekbyte(); + + //get a set of 4 bytes from the midifile + unsigned int getint32(); + + //get a word of 2 bytes from the midifile + unsigned short int getint16(); + + //read a variable length quantity + unsigned int getvarint32(); + + //skip some bytes + void skipnbytes(int n); + + struct { + double tick;//how many seconds one tick has + + }data; + +}; + +#endif diff --git a/plugins/zynaddsubfx/src/Seq/Sequencer.C b/plugins/zynaddsubfx/src/Seq/Sequencer.C new file mode 100644 index 000000000..94d98b20b --- /dev/null +++ b/plugins/zynaddsubfx/src/Seq/Sequencer.C @@ -0,0 +1,165 @@ +/* + ZynAddSubFX - a software synthesizer + + Sequencer.C - The Sequencer + Copyright (C) 2003-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include +#include +#include + +#include +#include + +#include "Sequencer.h" + + + +Sequencer::Sequencer(){ + play=0; + for (int i=0;i1sec) sa elimin nota + + if (ntrack==1) printf("_ %f %.2f (%d)\n",nextevent[(int)ntrack].time,playtime[(int)ntrack].abs,nextevent[(int)ntrack].ev.par2); + + *type=nextevent[(int)ntrack].ev.type; + *par1=nextevent[(int)ntrack].ev.par1; + *par2=nextevent[(int)ntrack].ev.par2; + *midich=nextevent[(int)ntrack].ev.channel; + + + double dt=nextevent[(int)ntrack].ev.deltatime*0.0001*realplayspeed; + printf("zzzzzzzzzzzzzz[%d] %d\n",ntrack,nextevent[(int)ntrack].ev.deltatime); + nextevent[(int)ntrack].time+=dt; + +// printf("%f - %d %d \n",nextevent[ntrack].time,par1,par2); + return(0);//?? sau 1 +}; + +/************** Timer stuff ***************/ + +void Sequencer::resettime(timestruct *t){ + t->abs=0.0; + t->rel=0.0; + + timeval tval; + + t->last=0.0; + #ifndef OS_WINDOWS + if (gettimeofday(&tval,NULL)==0) + t->last=tval.tv_sec+tval.tv_usec*0.000001; + #endif + +}; + +void Sequencer::updatecounter(timestruct *t){ + timeval tval; + double current=0.0; + #ifndef OS_WINDOWS + if (gettimeofday(&tval,NULL)==0) + current=tval.tv_sec+tval.tv_usec*0.000001; + #endif + + t->rel=current - t->last; + t->abs+=t->rel; + t->last=current; + +// printf("%f %f %f\n",t->last,t->abs,t->rel); +}; + +void Sequencer::setplayspeed(int speed){ + playspeed=speed; + realplayspeed=pow(10.0,speed/128.0); +}; diff --git a/plugins/zynaddsubfx/src/Seq/Sequencer.h b/plugins/zynaddsubfx/src/Seq/Sequencer.h new file mode 100644 index 000000000..3236741a4 --- /dev/null +++ b/plugins/zynaddsubfx/src/Seq/Sequencer.h @@ -0,0 +1,84 @@ +/* + ZynAddSubFX - a software synthesizer + + Sequencer.h - The Sequencer + Copyright (C) 2003-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef SEQUENCER_H +#define SEQUENCER_H + +#include "../globals.h" +#include "MIDIEvents.h" +#include "MIDIFile.h" + +class Sequencer:public MIDIEvents{ + public: + Sequencer(); + ~Sequencer(); + + //theese functions are called by the master and are ignored if the recorder/player are stopped + void recordnote(char chan, char note, char vel); + void recordcontroller(char chan,unsigned int type,int par); + + //this is only for player + //it returns 1 if this must be called at least once more + //it returns 0 if there are no more notes for the current time + //or -1 if there is no note + int getevent(char ntrack, int *midich,int *type,int *par1, int *par2); + + //returns 0 if ok or -1 if there is a error loading file + int importmidifile(char *filename); + + void startplay(); + void stopplay(); + + + int play; + int playspeed;//viteza de rulare (0.1x-10x), 0=1.0x, 128=10x + void setplayspeed(int speed); + + private: + + MIDIFile midifile; + + /* Timer */ + struct timestruct{ + double abs;//the time from the begining of the track + double rel;//the time difference between the last and the current event + double last;//the time of the last event (absolute, since 1 Jan 1970) + //theese must be double, because the float's precision is too low + //and all theese represents the time in seconds + } playtime[NUM_MIDI_TRACKS]; + + void resettime(timestruct *t); + void updatecounter(timestruct *t);//this updates the timer values + + /* Player only*/ + + struct { + event ev; + double time; + } nextevent[NUM_MIDI_TRACKS]; + + double realplayspeed; + +}; + + +#endif + diff --git a/plugins/zynaddsubfx/src/Synth/ADnote.C b/plugins/zynaddsubfx/src/Synth/ADnote.C new file mode 100644 index 000000000..de569539d --- /dev/null +++ b/plugins/zynaddsubfx/src/Synth/ADnote.C @@ -0,0 +1,1271 @@ +/* + ZynAddSubFX - a software synthesizer + + ADnote.C - The "additive" synthesizer + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include + + +#include "../globals.h" +#include "../Misc/Util.h" +#include "ADnote.h" + + +ADnote::ADnote(ADnoteParameters *pars,Controller *ctl_,REALTYPE freq,REALTYPE velocity,int portamento_,int midinote_,bool besilent){ + ready=0; + + tmpwave=new REALTYPE [SOUND_BUFFER_SIZE]; + bypassl=new REALTYPE [SOUND_BUFFER_SIZE]; + bypassr=new REALTYPE [SOUND_BUFFER_SIZE]; + + // Initialise some legato-specific vars + Legato.msg=LM_Norm; + Legato.fade.length=(int)(SAMPLE_RATE*0.005);// 0.005 seems ok. + if (Legato.fade.length<1) Legato.fade.length=1;// (if something's fishy) + Legato.fade.step=(1.0/Legato.fade.length); + Legato.decounter=-10; + Legato.param.freq=freq; + Legato.param.vel=velocity; + Legato.param.portamento=portamento_; + Legato.param.midinote=midinote_; + Legato.silent=besilent; + + partparams=pars; + ctl=ctl_; + portamento=portamento_; + midinote=midinote_; + NoteEnabled=ON; + basefreq=freq; + if (velocity>1.0) velocity=1.0; + this->velocity=velocity; + time=0.0; + stereo=pars->GlobalPar.PStereo; + + NoteGlobalPar.Detune=getdetune(pars->GlobalPar.PDetuneType + ,pars->GlobalPar.PCoarseDetune,pars->GlobalPar.PDetune); + bandwidthDetuneMultiplier=pars->getBandwidthDetuneMultiplier(); + + if (pars->GlobalPar.PPanning==0) NoteGlobalPar.Panning=RND; + else NoteGlobalPar.Panning=pars->GlobalPar.PPanning/128.0; + + + NoteGlobalPar.FilterCenterPitch=pars->GlobalPar.GlobalFilter->getfreq()+//center freq + pars->GlobalPar.PFilterVelocityScale/127.0*6.0* //velocity sensing + (VelF(velocity,pars->GlobalPar.PFilterVelocityScaleFunction)-1); + + if (pars->GlobalPar.PPunchStrength!=0) { + NoteGlobalPar.Punch.Enabled=1; + NoteGlobalPar.Punch.t=1.0;//start from 1.0 and to 0.0 + NoteGlobalPar.Punch.initialvalue=( (pow(10,1.5*pars->GlobalPar.PPunchStrength/127.0)-1.0) + *VelF(velocity,pars->GlobalPar.PPunchVelocitySensing) ); + REALTYPE time=pow(10,3.0*pars->GlobalPar.PPunchTime/127.0)/10000.0;//0.1 .. 100 ms + REALTYPE stretch=pow(440.0/freq,pars->GlobalPar.PPunchStretch/64.0); + NoteGlobalPar.Punch.dt=1.0/(time*SAMPLE_RATE*stretch); + } else NoteGlobalPar.Punch.Enabled=0; + + for (int nvoice=0;nvoiceVoicePar[nvoice].OscilSmp->newrandseed(rand()); + NoteVoicePar[nvoice].OscilSmp=NULL; + NoteVoicePar[nvoice].FMSmp=NULL; + NoteVoicePar[nvoice].VoiceOut=NULL; + + NoteVoicePar[nvoice].FMVoice=-1; + + if (pars->VoicePar[nvoice].Enabled==0) { + NoteVoicePar[nvoice].Enabled=OFF; + continue; //the voice is disabled + }; + + NoteVoicePar[nvoice].Enabled=ON; + NoteVoicePar[nvoice].fixedfreq=pars->VoicePar[nvoice].Pfixedfreq; + NoteVoicePar[nvoice].fixedfreqET=pars->VoicePar[nvoice].PfixedfreqET; + + //use the Globalpars.detunetype if the detunetype is 0 + if (pars->VoicePar[nvoice].PDetuneType!=0){ + NoteVoicePar[nvoice].Detune=getdetune(pars->VoicePar[nvoice].PDetuneType + ,pars->VoicePar[nvoice].PCoarseDetune,8192);//coarse detune + NoteVoicePar[nvoice].FineDetune=getdetune(pars->VoicePar[nvoice].PDetuneType + ,0,pars->VoicePar[nvoice].PDetune);//fine detune + } else { + NoteVoicePar[nvoice].Detune=getdetune(pars->GlobalPar.PDetuneType + ,pars->VoicePar[nvoice].PCoarseDetune,8192);//coarse detune + NoteVoicePar[nvoice].FineDetune=getdetune(pars->GlobalPar.PDetuneType + ,0,pars->VoicePar[nvoice].PDetune);//fine detune + }; + if (pars->VoicePar[nvoice].PFMDetuneType!=0){ + NoteVoicePar[nvoice].FMDetune=getdetune(pars->VoicePar[nvoice].PFMDetuneType + ,pars->VoicePar[nvoice].PFMCoarseDetune,pars->VoicePar[nvoice].PFMDetune); + } else { + NoteVoicePar[nvoice].FMDetune=getdetune(pars->GlobalPar.PDetuneType + ,pars->VoicePar[nvoice].PFMCoarseDetune,pars->VoicePar[nvoice].PFMDetune); + }; + + oscposhi[nvoice]=0;oscposlo[nvoice]=0.0; + oscposhiFM[nvoice]=0;oscposloFM[nvoice]=0.0; + + NoteVoicePar[nvoice].OscilSmp=new REALTYPE[OSCIL_SIZE+OSCIL_SMP_EXTRA_SAMPLES];//the extra points contains the first point + + //Get the voice's oscil or external's voice oscil + int vc=nvoice; + if (pars->VoicePar[nvoice].Pextoscil!=-1) vc=pars->VoicePar[nvoice].Pextoscil; + if (!pars->GlobalPar.Hrandgrouping) pars->VoicePar[vc].OscilSmp->newrandseed(rand()); + oscposhi[nvoice]=pars->VoicePar[vc].OscilSmp->get(NoteVoicePar[nvoice].OscilSmp,getvoicebasefreq(nvoice), + pars->VoicePar[nvoice].Presonance); + + //I store the first elments to the last position for speedups + for (int i=0;iVoicePar[nvoice].Poscilphase-64.0)/128.0*OSCIL_SIZE+OSCIL_SIZE*4); + oscposhi[nvoice]%=OSCIL_SIZE; + + + NoteVoicePar[nvoice].FreqLfo=NULL; + NoteVoicePar[nvoice].FreqEnvelope=NULL; + + NoteVoicePar[nvoice].AmpLfo=NULL; + NoteVoicePar[nvoice].AmpEnvelope=NULL; + + NoteVoicePar[nvoice].VoiceFilter=NULL; + NoteVoicePar[nvoice].FilterEnvelope=NULL; + NoteVoicePar[nvoice].FilterLfo=NULL; + + NoteVoicePar[nvoice].FilterCenterPitch=pars->VoicePar[nvoice].VoiceFilter->getfreq(); + NoteVoicePar[nvoice].filterbypass=pars->VoicePar[nvoice].Pfilterbypass; + + switch(pars->VoicePar[nvoice].PFMEnabled){ + case 1:NoteVoicePar[nvoice].FMEnabled=MORPH;break; + case 2:NoteVoicePar[nvoice].FMEnabled=RING_MOD;break; + case 3:NoteVoicePar[nvoice].FMEnabled=PHASE_MOD;break; + case 4:NoteVoicePar[nvoice].FMEnabled=FREQ_MOD;break; + case 5:NoteVoicePar[nvoice].FMEnabled=PITCH_MOD;break; + default:NoteVoicePar[nvoice].FMEnabled=NONE; + }; + + NoteVoicePar[nvoice].FMVoice=pars->VoicePar[nvoice].PFMVoice; + NoteVoicePar[nvoice].FMFreqEnvelope=NULL; + NoteVoicePar[nvoice].FMAmpEnvelope=NULL; + + //Compute the Voice's modulator volume (incl. damping) + REALTYPE fmvoldamp=pow(440.0/getvoicebasefreq(nvoice),pars->VoicePar[nvoice].PFMVolumeDamp/64.0-1.0); + switch (NoteVoicePar[nvoice].FMEnabled){ + case PHASE_MOD:fmvoldamp=pow(440.0/getvoicebasefreq(nvoice),pars->VoicePar[nvoice].PFMVolumeDamp/64.0); + NoteVoicePar[nvoice].FMVolume=(exp(pars->VoicePar[nvoice].PFMVolume/127.0*FM_AMP_MULTIPLIER)-1.0)*fmvoldamp*4.0; + break; + case FREQ_MOD:NoteVoicePar[nvoice].FMVolume=(exp(pars->VoicePar[nvoice].PFMVolume/127.0*FM_AMP_MULTIPLIER)-1.0)*fmvoldamp*4.0; + break; + // case PITCH_MOD:NoteVoicePar[nvoice].FMVolume=(pars->VoicePar[nvoice].PFMVolume/127.0*8.0)*fmvoldamp;//??????????? + // break; + default:if (fmvoldamp>1.0) fmvoldamp=1.0; + NoteVoicePar[nvoice].FMVolume=pars->VoicePar[nvoice].PFMVolume/127.0*fmvoldamp; + }; + + //Voice's modulator velocity sensing + NoteVoicePar[nvoice].FMVolume*=VelF(velocity,partparams->VoicePar[nvoice].PFMVelocityScaleFunction); + + FMoldsmp[nvoice]=0.0;//this is for FM (integration) + + firsttick[nvoice]=1; + NoteVoicePar[nvoice].DelayTicks=(int)((exp(pars->VoicePar[nvoice].PDelay/127.0*log(50.0))-1.0)/SOUND_BUFFER_SIZE/10.0*SAMPLE_RATE); + }; + + initparameters(); + ready=1; +}; + + +// ADlegatonote: This function is (mostly) a copy of ADnote(...) and +// initparameters() stuck together with some lines removed so that it +// only alter the already playing note (to perform legato). It is +// possible I left stuff that is not required for this. +void ADnote::ADlegatonote(REALTYPE freq, REALTYPE velocity, int portamento_, int midinote_, bool externcall){ + ADnoteParameters *pars=partparams; + //Controller *ctl_=ctl; + + // Manage legato stuff + if (externcall) Legato.msg=LM_Norm; + if (Legato.msg!=LM_CatchUp){ + Legato.lastfreq=Legato.param.freq; + Legato.param.freq=freq; + Legato.param.vel=velocity; + Legato.param.portamento=portamento_; + Legato.param.midinote=midinote_; + if (Legato.msg==LM_Norm){ + if (Legato.silent){ + Legato.fade.m=0.0; + Legato.msg=LM_FadeIn; + } else { + Legato.fade.m=1.0; + Legato.msg=LM_FadeOut; + return; + } + } + if (Legato.msg==LM_ToNorm) Legato.msg=LM_Norm; + } + + portamento=portamento_; + midinote=midinote_; + basefreq=freq; + + if (velocity>1.0) velocity=1.0; + this->velocity=velocity; + + NoteGlobalPar.Detune=getdetune(pars->GlobalPar.PDetuneType + ,pars->GlobalPar.PCoarseDetune,pars->GlobalPar.PDetune); + bandwidthDetuneMultiplier=pars->getBandwidthDetuneMultiplier(); + + if (pars->GlobalPar.PPanning==0) NoteGlobalPar.Panning=RND; + else NoteGlobalPar.Panning=pars->GlobalPar.PPanning/128.0; + + + NoteGlobalPar.FilterCenterPitch=pars->GlobalPar.GlobalFilter->getfreq()+//center freq + pars->GlobalPar.PFilterVelocityScale/127.0*6.0* //velocity sensing + (VelF(velocity,pars->GlobalPar.PFilterVelocityScaleFunction)-1); + + + for (int nvoice=0;nvoiceVoicePar[nvoice].Pfixedfreq; + NoteVoicePar[nvoice].fixedfreqET=pars->VoicePar[nvoice].PfixedfreqET; + + //use the Globalpars.detunetype if the detunetype is 0 + if (pars->VoicePar[nvoice].PDetuneType!=0){ + NoteVoicePar[nvoice].Detune=getdetune(pars->VoicePar[nvoice].PDetuneType + ,pars->VoicePar[nvoice].PCoarseDetune,8192);//coarse detune + NoteVoicePar[nvoice].FineDetune=getdetune(pars->VoicePar[nvoice].PDetuneType + ,0,pars->VoicePar[nvoice].PDetune);//fine detune + } else { + NoteVoicePar[nvoice].Detune=getdetune(pars->GlobalPar.PDetuneType + ,pars->VoicePar[nvoice].PCoarseDetune,8192);//coarse detune + NoteVoicePar[nvoice].FineDetune=getdetune(pars->GlobalPar.PDetuneType + ,0,pars->VoicePar[nvoice].PDetune);//fine detune + }; + if (pars->VoicePar[nvoice].PFMDetuneType!=0){ + NoteVoicePar[nvoice].FMDetune=getdetune(pars->VoicePar[nvoice].PFMDetuneType + ,pars->VoicePar[nvoice].PFMCoarseDetune,pars->VoicePar[nvoice].PFMDetune); + } else { + NoteVoicePar[nvoice].FMDetune=getdetune(pars->GlobalPar.PDetuneType + ,pars->VoicePar[nvoice].PFMCoarseDetune,pars->VoicePar[nvoice].PFMDetune); + }; + + //Get the voice's oscil or external's voice oscil + int vc=nvoice; + if (pars->VoicePar[nvoice].Pextoscil!=-1) vc=pars->VoicePar[nvoice].Pextoscil; + if (!pars->GlobalPar.Hrandgrouping) pars->VoicePar[vc].OscilSmp->newrandseed(rand()); + + ///oscposhi[nvoice]=pars->VoicePar[vc].OscilSmp->get(NoteVoicePar[nvoice].OscilSmp,getvoicebasefreq(nvoice),pars->VoicePar[nvoice].Presonance); + pars->VoicePar[vc].OscilSmp->get(NoteVoicePar[nvoice].OscilSmp,getvoicebasefreq(nvoice),pars->VoicePar[nvoice].Presonance);//(gf)Modif of the above line. + + //I store the first elments to the last position for speedups + for (int i=0;iVoicePar[nvoice].VoiceFilter->getfreq(); + NoteVoicePar[nvoice].filterbypass=pars->VoicePar[nvoice].Pfilterbypass; + + + NoteVoicePar[nvoice].FMVoice=pars->VoicePar[nvoice].PFMVoice; + + //Compute the Voice's modulator volume (incl. damping) + REALTYPE fmvoldamp=pow(440.0/getvoicebasefreq(nvoice),pars->VoicePar[nvoice].PFMVolumeDamp/64.0-1.0); + + switch (NoteVoicePar[nvoice].FMEnabled){ + case PHASE_MOD:fmvoldamp=pow(440.0/getvoicebasefreq(nvoice),pars->VoicePar[nvoice].PFMVolumeDamp/64.0); + NoteVoicePar[nvoice].FMVolume=(exp(pars->VoicePar[nvoice].PFMVolume/127.0*FM_AMP_MULTIPLIER)-1.0)*fmvoldamp*4.0; + break; + case FREQ_MOD:NoteVoicePar[nvoice].FMVolume=(exp(pars->VoicePar[nvoice].PFMVolume/127.0*FM_AMP_MULTIPLIER)-1.0)*fmvoldamp*4.0; + break; + // case PITCH_MOD:NoteVoicePar[nvoice].FMVolume=(pars->VoicePar[nvoice].PFMVolume/127.0*8.0)*fmvoldamp;//??????????? + // break; + default:if (fmvoldamp>1.0) fmvoldamp=1.0; + NoteVoicePar[nvoice].FMVolume=pars->VoicePar[nvoice].PFMVolume/127.0*fmvoldamp; + }; + + //Voice's modulator velocity sensing + NoteVoicePar[nvoice].FMVolume*=VelF(velocity,partparams->VoicePar[nvoice].PFMVelocityScaleFunction); + + NoteVoicePar[nvoice].DelayTicks=(int)((exp(pars->VoicePar[nvoice].PDelay/127.0*log(50.0))-1.0)/SOUND_BUFFER_SIZE/10.0*SAMPLE_RATE); + }; + + /// initparameters(); + + /////////////// + // Altered content of initparameters(): + + int nvoice,i,tmp[NUM_VOICES]; + + NoteGlobalPar.Volume=4.0*pow(0.1,3.0*(1.0-partparams->GlobalPar.PVolume/96.0))//-60 dB .. 0 dB + *VelF(velocity,partparams->GlobalPar.PAmpVelocityScaleFunction);//velocity sensing + + globalnewamplitude=NoteGlobalPar.Volume*NoteGlobalPar.AmpEnvelope->envout_dB()*NoteGlobalPar.AmpLfo->amplfoout(); + + NoteGlobalPar.FilterQ=partparams->GlobalPar.GlobalFilter->getq(); + NoteGlobalPar.FilterFreqTracking=partparams->GlobalPar.GlobalFilter->getfreqtracking(basefreq); + + // Forbids the Modulation Voice to be greater or equal than voice + for (i=0;i=i) NoteVoicePar[i].FMVoice=-1; + + // Voice Parameter init + for (nvoice=0;nvoiceVoicePar[nvoice].Type; + /* Voice Amplitude Parameters Init */ + NoteVoicePar[nvoice].Volume=pow(0.1,3.0*(1.0-partparams->VoicePar[nvoice].PVolume/127.0)) // -60 dB .. 0 dB + *VelF(velocity,partparams->VoicePar[nvoice].PAmpVelocityScaleFunction);//velocity + + if (partparams->VoicePar[nvoice].PVolumeminus!=0) NoteVoicePar[nvoice].Volume=-NoteVoicePar[nvoice].Volume; + + if (partparams->VoicePar[nvoice].PPanning==0) + NoteVoicePar[nvoice].Panning=RND;// random panning + else NoteVoicePar[nvoice].Panning=partparams->VoicePar[nvoice].PPanning/128.0; + + newamplitude[nvoice]=1.0; + if ((partparams->VoicePar[nvoice].PAmpEnvelopeEnabled!=0) + && (NoteVoicePar[nvoice].AmpEnvelope!=NULL)){ + newamplitude[nvoice]*=NoteVoicePar[nvoice].AmpEnvelope->envout_dB(); + }; + + if ((partparams->VoicePar[nvoice].PAmpLfoEnabled!=0) + && (NoteVoicePar[nvoice].AmpLfo!=NULL)){ + newamplitude[nvoice]*=NoteVoicePar[nvoice].AmpLfo->amplfoout(); + }; + + + NoteVoicePar[nvoice].FilterFreqTracking=partparams->VoicePar[nvoice].VoiceFilter->getfreqtracking(basefreq); + + /* Voice Modulation Parameters Init */ + if ((NoteVoicePar[nvoice].FMEnabled!=NONE)&&(NoteVoicePar[nvoice].FMVoice<0)){ + partparams->VoicePar[nvoice].FMSmp->newrandseed(rand()); + + //Perform Anti-aliasing only on MORPH or RING MODULATION + + int vc=nvoice; + if (partparams->VoicePar[nvoice].PextFMoscil!=-1) vc=partparams->VoicePar[nvoice].PextFMoscil; + + REALTYPE tmp=1.0; + if ((partparams->VoicePar[vc].FMSmp->Padaptiveharmonics!=0)|| + (NoteVoicePar[nvoice].FMEnabled==MORPH)|| + (NoteVoicePar[nvoice].FMEnabled==RING_MOD)){ + tmp=getFMvoicebasefreq(nvoice); + }; + if (!partparams->GlobalPar.Hrandgrouping) partparams->VoicePar[vc].FMSmp->newrandseed(rand()); + + ///oscposhiFM[nvoice]=(oscposhi[nvoice]+partparams->VoicePar[vc].FMSmp->get(NoteVoicePar[nvoice].FMSmp,tmp)) % OSCIL_SIZE; + // / oscposhi[nvoice]+partparams->VoicePar[vc].FMSmp->get(NoteVoicePar[nvoice].FMSmp,tmp); //(gf) Modif of the above line. + for (int i=0;iVoicePar[nvoice].PFMoscilphase-64.0)/128.0*OSCIL_SIZE+OSCIL_SIZE*4); + ///oscposhiFM[nvoice]%=OSCIL_SIZE; + }; + + FMnewamplitude[nvoice]=NoteVoicePar[nvoice].FMVolume*ctl->fmamp.relamp; + + if ((partparams->VoicePar[nvoice].PFMAmpEnvelopeEnabled!=0) + && (NoteVoicePar[nvoice].FMAmpEnvelope!=NULL)){ + FMnewamplitude[nvoice]*=NoteVoicePar[nvoice].FMAmpEnvelope->envout_dB(); + }; + }; + + for (nvoice=0;nvoiceGlobalPar.FreqEnvelope,basefreq); + NoteGlobalPar.FreqLfo=new LFO(partparams->GlobalPar.FreqLfo,basefreq); + + NoteGlobalPar.AmpEnvelope=new Envelope(partparams->GlobalPar.AmpEnvelope,basefreq); + NoteGlobalPar.AmpLfo=new LFO(partparams->GlobalPar.AmpLfo,basefreq); + + NoteGlobalPar.Volume=4.0*pow(0.1,3.0*(1.0-partparams->GlobalPar.PVolume/96.0))//-60 dB .. 0 dB + *VelF(velocity,partparams->GlobalPar.PAmpVelocityScaleFunction);//velocity sensing + + NoteGlobalPar.AmpEnvelope->envout_dB();//discard the first envelope output + globalnewamplitude=NoteGlobalPar.Volume*NoteGlobalPar.AmpEnvelope->envout_dB()*NoteGlobalPar.AmpLfo->amplfoout(); + + NoteGlobalPar.GlobalFilterL=new Filter(partparams->GlobalPar.GlobalFilter); + if (stereo!=0) NoteGlobalPar.GlobalFilterR=new Filter(partparams->GlobalPar.GlobalFilter); + + NoteGlobalPar.FilterEnvelope=new Envelope(partparams->GlobalPar.FilterEnvelope,basefreq); + NoteGlobalPar.FilterLfo=new LFO(partparams->GlobalPar.FilterLfo,basefreq); + NoteGlobalPar.FilterQ=partparams->GlobalPar.GlobalFilter->getq(); + NoteGlobalPar.FilterFreqTracking=partparams->GlobalPar.GlobalFilter->getfreqtracking(basefreq); + + // Forbids the Modulation Voice to be greater or equal than voice + for (i=0;i=i) NoteVoicePar[i].FMVoice=-1; + + // Voice Parameter init + for (nvoice=0;nvoiceVoicePar[nvoice].Type; + /* Voice Amplitude Parameters Init */ + NoteVoicePar[nvoice].Volume=pow(0.1,3.0*(1.0-partparams->VoicePar[nvoice].PVolume/127.0)) // -60 dB .. 0 dB + *VelF(velocity,partparams->VoicePar[nvoice].PAmpVelocityScaleFunction);//velocity + + if (partparams->VoicePar[nvoice].PVolumeminus!=0) NoteVoicePar[nvoice].Volume=-NoteVoicePar[nvoice].Volume; + + if (partparams->VoicePar[nvoice].PPanning==0) + NoteVoicePar[nvoice].Panning=RND;// random panning + else NoteVoicePar[nvoice].Panning=partparams->VoicePar[nvoice].PPanning/128.0; + + newamplitude[nvoice]=1.0; + if (partparams->VoicePar[nvoice].PAmpEnvelopeEnabled!=0) { + NoteVoicePar[nvoice].AmpEnvelope=new Envelope(partparams->VoicePar[nvoice].AmpEnvelope,basefreq); + NoteVoicePar[nvoice].AmpEnvelope->envout_dB();//discard the first envelope sample + newamplitude[nvoice]*=NoteVoicePar[nvoice].AmpEnvelope->envout_dB(); + }; + + if (partparams->VoicePar[nvoice].PAmpLfoEnabled!=0){ + NoteVoicePar[nvoice].AmpLfo=new LFO(partparams->VoicePar[nvoice].AmpLfo,basefreq); + newamplitude[nvoice]*=NoteVoicePar[nvoice].AmpLfo->amplfoout(); + }; + + /* Voice Frequency Parameters Init */ + if (partparams->VoicePar[nvoice].PFreqEnvelopeEnabled!=0) + NoteVoicePar[nvoice].FreqEnvelope=new Envelope(partparams->VoicePar[nvoice].FreqEnvelope,basefreq); + + if (partparams->VoicePar[nvoice].PFreqLfoEnabled!=0) NoteVoicePar[nvoice].FreqLfo=new LFO(partparams->VoicePar[nvoice].FreqLfo,basefreq); + + /* Voice Filter Parameters Init */ + if (partparams->VoicePar[nvoice].PFilterEnabled!=0){ + NoteVoicePar[nvoice].VoiceFilter=new Filter(partparams->VoicePar[nvoice].VoiceFilter); + }; + + if (partparams->VoicePar[nvoice].PFilterEnvelopeEnabled!=0) + NoteVoicePar[nvoice].FilterEnvelope=new Envelope(partparams->VoicePar[nvoice].FilterEnvelope,basefreq); + + if (partparams->VoicePar[nvoice].PFilterLfoEnabled!=0) + NoteVoicePar[nvoice].FilterLfo=new LFO(partparams->VoicePar[nvoice].FilterLfo,basefreq); + + NoteVoicePar[nvoice].FilterFreqTracking=partparams->VoicePar[nvoice].VoiceFilter->getfreqtracking(basefreq); + + /* Voice Modulation Parameters Init */ + if ((NoteVoicePar[nvoice].FMEnabled!=NONE)&&(NoteVoicePar[nvoice].FMVoice<0)){ + partparams->VoicePar[nvoice].FMSmp->newrandseed(rand()); + NoteVoicePar[nvoice].FMSmp=new REALTYPE[OSCIL_SIZE+OSCIL_SMP_EXTRA_SAMPLES]; + + //Perform Anti-aliasing only on MORPH or RING MODULATION + + int vc=nvoice; + if (partparams->VoicePar[nvoice].PextFMoscil!=-1) vc=partparams->VoicePar[nvoice].PextFMoscil; + + REALTYPE tmp=1.0; + if ((partparams->VoicePar[vc].FMSmp->Padaptiveharmonics!=0)|| + (NoteVoicePar[nvoice].FMEnabled==MORPH)|| + (NoteVoicePar[nvoice].FMEnabled==RING_MOD)){ + tmp=getFMvoicebasefreq(nvoice); + }; + if (!partparams->GlobalPar.Hrandgrouping) partparams->VoicePar[vc].FMSmp->newrandseed(rand()); + + oscposhiFM[nvoice]=(oscposhi[nvoice]+partparams->VoicePar[vc].FMSmp->get(NoteVoicePar[nvoice].FMSmp,tmp)) % OSCIL_SIZE; + for (int i=0;iVoicePar[nvoice].PFMoscilphase-64.0)/128.0*OSCIL_SIZE+OSCIL_SIZE*4); + oscposhiFM[nvoice]%=OSCIL_SIZE; + }; + + if (partparams->VoicePar[nvoice].PFMFreqEnvelopeEnabled!=0) + NoteVoicePar[nvoice].FMFreqEnvelope=new Envelope(partparams->VoicePar[nvoice].FMFreqEnvelope,basefreq); + + FMnewamplitude[nvoice]=NoteVoicePar[nvoice].FMVolume*ctl->fmamp.relamp; + + if (partparams->VoicePar[nvoice].PFMAmpEnvelopeEnabled!=0){ + NoteVoicePar[nvoice].FMAmpEnvelope=new Envelope(partparams->VoicePar[nvoice].FMAmpEnvelope,basefreq); + FMnewamplitude[nvoice]*=NoteVoicePar[nvoice].FMAmpEnvelope->envout_dB(); + }; + }; + + for (nvoice=0;nvoiceOSCIL_SIZE) speed=OSCIL_SIZE; + + F2I(speed,oscfreqhi[nvoice]); + oscfreqlo[nvoice]=speed-floor(speed); +}; + +/* + * Computes the frequency of an modullator oscillator + */ +void ADnote::setfreqFM(int nvoice,REALTYPE freq){ + REALTYPE speed; + freq=fabs(freq); + speed=freq*REALTYPE(OSCIL_SIZE)/(REALTYPE) SAMPLE_RATE; + if (speed>OSCIL_SIZE) speed=OSCIL_SIZE; + + F2I(speed,oscfreqhiFM[nvoice]); + oscfreqloFM[nvoice]=speed-floor(speed); +}; + +/* + * Get Voice base frequency + */ +REALTYPE ADnote::getvoicebasefreq(int nvoice){ + REALTYPE detune=NoteVoicePar[nvoice].Detune/100.0+ + NoteVoicePar[nvoice].FineDetune/100.0*ctl->bandwidth.relbw*bandwidthDetuneMultiplier+ + NoteGlobalPar.Detune/100.0; + + if (NoteVoicePar[nvoice].fixedfreq==0) return(this->basefreq*pow(2,detune/12.0)); + else {//the fixed freq is enabled + REALTYPE fixedfreq=440.0; + int fixedfreqET=NoteVoicePar[nvoice].fixedfreqET; + if (fixedfreqET!=0) {//if the frequency varies according the keyboard note + REALTYPE tmp=(midinote-69.0)/12.0*(pow(2.0,(fixedfreqET-1)/63.0)-1.0); + if (fixedfreqET<=64) fixedfreq*=pow(2.0,tmp); + else fixedfreq*=pow(3.0,tmp); + }; + return(fixedfreq*pow(2.0,detune/12.0)); + }; +}; + +/* + * Get Voice's Modullator base frequency + */ +REALTYPE ADnote::getFMvoicebasefreq(int nvoice){ + REALTYPE detune=NoteVoicePar[nvoice].FMDetune/100.0; + return(getvoicebasefreq(nvoice)*pow(2,detune/12.0)); +}; + +/* + * Computes all the parameters for each tick + */ +void ADnote::computecurrentparameters(){ + int nvoice; + REALTYPE voicefreq,voicepitch,filterpitch,filterfreq,FMfreq,FMrelativepitch,globalpitch,globalfilterpitch; + globalpitch=0.01*(NoteGlobalPar.FreqEnvelope->envout()+ + NoteGlobalPar.FreqLfo->lfoout()*ctl->modwheel.relmod); + globaloldamplitude=globalnewamplitude; + globalnewamplitude=NoteGlobalPar.Volume*NoteGlobalPar.AmpEnvelope->envout_dB()*NoteGlobalPar.AmpLfo->amplfoout(); + + globalfilterpitch=NoteGlobalPar.FilterEnvelope->envout()+NoteGlobalPar.FilterLfo->lfoout() + +NoteGlobalPar.FilterCenterPitch; + + REALTYPE tmpfilterfreq=globalfilterpitch+ctl->filtercutoff.relfreq + +NoteGlobalPar.FilterFreqTracking; + + tmpfilterfreq=NoteGlobalPar.GlobalFilterL->getrealfreq(tmpfilterfreq); + + REALTYPE globalfilterq=NoteGlobalPar.FilterQ*ctl->filterq.relq; + NoteGlobalPar.GlobalFilterL->setfreq_and_q(tmpfilterfreq,globalfilterq); + if (stereo!=0) NoteGlobalPar.GlobalFilterR->setfreq_and_q(tmpfilterfreq,globalfilterq); + + //compute the portamento, if it is used by this note + REALTYPE portamentofreqrap=1.0; + if (portamento!=0){//this voice use portamento + portamentofreqrap=ctl->portamento.freqrap; + if (ctl->portamento.used==0){//the portamento has finished + portamento=0;//this note is no longer "portamented" + }; + }; + + //compute parameters for all voices + for (nvoice=0;nvoice0) continue; + + /*******************/ + /* Voice Amplitude */ + /*******************/ + oldamplitude[nvoice]=newamplitude[nvoice]; + newamplitude[nvoice]=1.0; + + if (NoteVoicePar[nvoice].AmpEnvelope!=NULL) + newamplitude[nvoice]*=NoteVoicePar[nvoice].AmpEnvelope->envout_dB(); + + if (NoteVoicePar[nvoice].AmpLfo!=NULL) + newamplitude[nvoice]*=NoteVoicePar[nvoice].AmpLfo->amplfoout(); + + /****************/ + /* Voice Filter */ + /****************/ + if (NoteVoicePar[nvoice].VoiceFilter!=NULL){ + filterpitch=NoteVoicePar[nvoice].FilterCenterPitch; + + if (NoteVoicePar[nvoice].FilterEnvelope!=NULL) + filterpitch+=NoteVoicePar[nvoice].FilterEnvelope->envout(); + + if (NoteVoicePar[nvoice].FilterLfo!=NULL) + filterpitch+=NoteVoicePar[nvoice].FilterLfo->lfoout(); + + filterfreq=filterpitch+NoteVoicePar[nvoice].FilterFreqTracking; + filterfreq=NoteVoicePar[nvoice].VoiceFilter->getrealfreq(filterfreq); + + NoteVoicePar[nvoice].VoiceFilter->setfreq(filterfreq); + }; + + if (NoteVoicePar[nvoice].noisetype==0){//compute only if the voice isn't noise + + /*******************/ + /* Voice Frequency */ + /*******************/ + voicepitch=0.0; + if (NoteVoicePar[nvoice].FreqLfo!=NULL) + voicepitch+=NoteVoicePar[nvoice].FreqLfo->lfoout()/100.0 + *ctl->bandwidth.relbw; + + if (NoteVoicePar[nvoice].FreqEnvelope!=NULL) voicepitch+=NoteVoicePar[nvoice].FreqEnvelope->envout()/100.0; + voicefreq=getvoicebasefreq(nvoice)*pow(2,(voicepitch+globalpitch)/12.0);//Hz frequency + voicefreq*=ctl->pitchwheel.relfreq;//change the frequency by the controller + setfreq(nvoice,voicefreq*portamentofreqrap); + + /***************/ + /* Modulator */ + /***************/ + if (NoteVoicePar[nvoice].FMEnabled!=NONE){ + FMrelativepitch=NoteVoicePar[nvoice].FMDetune/100.0; + if (NoteVoicePar[nvoice].FMFreqEnvelope!=NULL) FMrelativepitch+=NoteVoicePar[nvoice].FMFreqEnvelope->envout()/100; + FMfreq=pow(2.0,FMrelativepitch/12.0)*voicefreq*portamentofreqrap; + setfreqFM(nvoice,FMfreq); + + FMoldamplitude[nvoice]=FMnewamplitude[nvoice]; + FMnewamplitude[nvoice]=NoteVoicePar[nvoice].FMVolume*ctl->fmamp.relamp; + if (NoteVoicePar[nvoice].FMAmpEnvelope!=NULL) + FMnewamplitude[nvoice]*=NoteVoicePar[nvoice].FMAmpEnvelope->envout_dB(); + }; + }; + + }; + time+=(REALTYPE)SOUND_BUFFER_SIZE/(REALTYPE)SAMPLE_RATE; +}; + + +/* + * Fadein in a way that removes clicks but keep sound "punchy" + */ +inline void ADnote::fadein(REALTYPE *smps){ + int zerocrossings=0; + for (int i=1;i0.0)) zerocrossings++;//this is only the possitive crossings + + REALTYPE tmp=(SOUND_BUFFER_SIZE-1.0)/(zerocrossings+1)/3.0; + if (tmp<8.0) tmp=8.0; + + int n; + F2I(tmp,n);//how many samples is the fade-in + if (n>SOUND_BUFFER_SIZE) n=SOUND_BUFFER_SIZE; + for (int i=0;i=1.0) { + poslo-=1.0; + poshi++; + }; + poshi+=oscfreqhi[nvoice]; + poshi&=OSCIL_SIZE-1; + }; + oscposhi[nvoice]=poshi; + oscposlo[nvoice]=poslo; +}; + + + +/* + * Computes the Oscillator (Without Modulation) - CubicInterpolation + * + The differences from the Linear are to little to deserve to be used. This is because I am using a large OSCIL_SIZE (>512) +inline void ADnote::ComputeVoiceOscillator_CubicInterpolation(int nvoice){ + int i,poshi; + REALTYPE poslo; + + poshi=oscposhi[nvoice]; + poslo=oscposlo[nvoice]; + REALTYPE *smps=NoteVoicePar[nvoice].OscilSmp; + REALTYPE xm1,x0,x1,x2,a,b,c; + for (i=0;i=1.0) { + poslo-=1.0; + poshi++; + }; + poshi+=oscfreqhi[nvoice]; + poshi&=OSCIL_SIZE-1; + }; + oscposhi[nvoice]=poshi; + oscposlo[nvoice]=poslo; +}; +*/ +/* + * Computes the Oscillator (Morphing) + */ +inline void ADnote::ComputeVoiceOscillatorMorph(int nvoice){ + int i; + REALTYPE amp; + ComputeVoiceOscillator_LinearInterpolation(nvoice); + if (FMnewamplitude[nvoice]>1.0) FMnewamplitude[nvoice]=1.0; + if (FMoldamplitude[nvoice]>1.0) FMoldamplitude[nvoice]=1.0; + + if (NoteVoicePar[nvoice].FMVoice>=0){ + //if I use VoiceOut[] as modullator + int FMVoice=NoteVoicePar[nvoice].FMVoice; + for (i=0;i=1.0) { + posloFM-=1.0; + poshiFM++; + }; + poshiFM+=oscfreqhiFM[nvoice]; + poshiFM&=OSCIL_SIZE-1; + }; + oscposhiFM[nvoice]=poshiFM; + oscposloFM[nvoice]=posloFM; + }; +}; + +/* + * Computes the Oscillator (Ring Modulation) + */ +inline void ADnote::ComputeVoiceOscillatorRingModulation(int nvoice){ + int i; + REALTYPE amp; + ComputeVoiceOscillator_LinearInterpolation(nvoice); + if (FMnewamplitude[nvoice]>1.0) FMnewamplitude[nvoice]=1.0; + if (FMoldamplitude[nvoice]>1.0) FMoldamplitude[nvoice]=1.0; + if (NoteVoicePar[nvoice].FMVoice>=0){ + // if I use VoiceOut[] as modullator + for (i=0;i=1.0) { + posloFM-=1.0; + poshiFM++; + }; + poshiFM+=oscfreqhiFM[nvoice]; + poshiFM&=OSCIL_SIZE-1; + }; + oscposhiFM[nvoice]=poshiFM; + oscposloFM[nvoice]=posloFM; + }; +}; + + + +/* + * Computes the Oscillator (Phase Modulation or Frequency Modulation) + */ +inline void ADnote::ComputeVoiceOscillatorFrequencyModulation(int nvoice,int FMmode){ + int carposhi; + int i,FMmodfreqhi; + REALTYPE FMmodfreqlo,carposlo; + + if (NoteVoicePar[nvoice].FMVoice>=0){ + //if I use VoiceOut[] as modulator + for (i=0;i=1.0) { + posloFM=fmod(posloFM,1.0); + poshiFM++; + }; + poshiFM+=oscfreqhiFM[nvoice]; + poshiFM&=OSCIL_SIZE-1; + }; + oscposhiFM[nvoice]=poshiFM; + oscposloFM[nvoice]=posloFM; + }; + // Amplitude interpolation + if (ABOVE_AMPLITUDE_THRESHOLD(FMoldamplitude[nvoice],FMnewamplitude[nvoice])){ + for (i=0;i=1.0) { + carposhi++; + carposlo=fmod(carposlo,1.0); + }; + carposhi&=(OSCIL_SIZE-1); + + tmpwave[i]=NoteVoicePar[nvoice].OscilSmp[carposhi]*(1.0-carposlo) + +NoteVoicePar[nvoice].OscilSmp[carposhi+1]*carposlo; + + oscposlo[nvoice]+=oscfreqlo[nvoice]; + if (oscposlo[nvoice]>=1.0) { + oscposlo[nvoice]=fmod(oscposlo[nvoice],1.0); + oscposhi[nvoice]++; + }; + + oscposhi[nvoice]+=oscfreqhi[nvoice]; + oscposhi[nvoice]&=OSCIL_SIZE-1; + }; +}; + + +/*Calculeaza Oscilatorul cu PITCH MODULATION*/ +inline void ADnote::ComputeVoiceOscillatorPitchModulation(int nvoice){ +//TODO +}; + +/* + * Computes the Noise + */ +inline void ADnote::ComputeVoiceNoise(int nvoice){ + for (int i=0;i0)) continue; + if (NoteVoicePar[nvoice].noisetype==0){//voice mode=sound + switch (NoteVoicePar[nvoice].FMEnabled){ + case MORPH:ComputeVoiceOscillatorMorph(nvoice);break; + case RING_MOD:ComputeVoiceOscillatorRingModulation(nvoice);break; + case PHASE_MOD:ComputeVoiceOscillatorFrequencyModulation(nvoice,0);break; + case FREQ_MOD:ComputeVoiceOscillatorFrequencyModulation(nvoice,1);break; + //case PITCH_MOD:ComputeVoiceOscillatorPitchModulation(nvoice);break; + default:ComputeVoiceOscillator_LinearInterpolation(nvoice); + //if (config.cfg.Interpolation) ComputeVoiceOscillator_CubicInterpolation(nvoice); + + }; + } else ComputeVoiceNoise(nvoice); + // Voice Processing + + // Amplitude + if (ABOVE_AMPLITUDE_THRESHOLD(oldamplitude[nvoice],newamplitude[nvoice])){ + int rest=SOUND_BUFFER_SIZE; + //test if the amplitude if raising and the difference is high + if ((newamplitude[nvoice]>oldamplitude[nvoice])&&((newamplitude[nvoice]-oldamplitude[nvoice])>0.25)){ + rest=10; + if (rest>SOUND_BUFFER_SIZE) rest=SOUND_BUFFER_SIZE; + for (int i=0;ifilterout(&tmpwave[0]); + + //check if the amplitude envelope is finished, if yes, the voice will be fadeout + if (NoteVoicePar[nvoice].AmpEnvelope!=NULL) { + if (NoteVoicePar[nvoice].AmpEnvelope->finished()!=0) + for (i=0;ifinished()!=0) KillVoice(nvoice); + }; + }; + + + //Processing Global parameters + NoteGlobalPar.GlobalFilterL->filterout(&outl[0]); + + if (stereo==0) { + for (i=0;ifilterout(&outr[0]); + + for (i=0;ifinished()!=0) { + for (i=0;irelasekey(); + if (NoteVoicePar[nvoice].FreqEnvelope!=NULL) NoteVoicePar[nvoice].FreqEnvelope->relasekey(); + if (NoteVoicePar[nvoice].FilterEnvelope!=NULL) NoteVoicePar[nvoice].FilterEnvelope->relasekey(); + if (NoteVoicePar[nvoice].FMFreqEnvelope!=NULL) NoteVoicePar[nvoice].FMFreqEnvelope->relasekey(); + if (NoteVoicePar[nvoice].FMAmpEnvelope!=NULL) NoteVoicePar[nvoice].FMAmpEnvelope->relasekey(); + }; + NoteGlobalPar.FreqEnvelope->relasekey(); + NoteGlobalPar.FilterEnvelope->relasekey(); + NoteGlobalPar.AmpEnvelope->relasekey(); + +}; + +/* + * Check if the note is finished + */ +int ADnote::finished(){ + if (NoteEnabled==ON) return(0); + else return(1); +}; + + + diff --git a/plugins/zynaddsubfx/src/Synth/ADnote.h b/plugins/zynaddsubfx/src/Synth/ADnote.h new file mode 100644 index 000000000..8215b4035 --- /dev/null +++ b/plugins/zynaddsubfx/src/Synth/ADnote.h @@ -0,0 +1,277 @@ +/* + ZynAddSubFX - a software synthesizer + + ADnote.h - The "additive" synthesizer + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef AD_NOTE_H +#define AD_NOTE_H + +#include "../globals.h" +#include "Envelope.h" +#include "LFO.h" +#include "../DSP/Filter.h" +#include "../Params/ADnoteParameters.h" +#include "../Params/Controller.h" + +//Globals + +//FM amplitude tune +#define FM_AMP_MULTIPLIER 14.71280603 + +#define OSCIL_SMP_EXTRA_SAMPLES 5 + +class ADnote{ //ADDitive note + public: + ADnote(ADnoteParameters *pars,Controller *ctl_,REALTYPE freq,REALTYPE velocity,int portamento_,int midinote_,bool besilent);//(gf)Added the besilent parameter to tell it to start silent (if true). + ~ADnote(); + + void ADlegatonote(REALTYPE freq, REALTYPE velocity, int portamento_, int midinote_, bool externcall); + + int noteout(REALTYPE *outl,REALTYPE *outr); + void relasekey(); + int finished(); + + + /*ready - this is 0 if it is not ready (the parameters has to be computed) + or other value if the parameters has been computed and if it is ready to output*/ + char ready; + + private: + + void setfreq(int nvoice,REALTYPE freq); + void setfreqFM(int nvoice,REALTYPE freq); + void computecurrentparameters(); + void initparameters(); + void KillVoice(int nvoice); + void KillNote(); + inline REALTYPE getvoicebasefreq(int nvoice); + inline REALTYPE getFMvoicebasefreq(int nvoice); + inline void ComputeVoiceOscillator_LinearInterpolation(int nvoice); + inline void ComputeVoiceOscillator_CubicInterpolation(int nvoice); + inline void ComputeVoiceOscillatorMorph(int nvoice); + inline void ComputeVoiceOscillatorRingModulation(int nvoice); + inline void ComputeVoiceOscillatorFrequencyModulation(int nvoice,int FMmode);//FMmode=0 for phase modulation, 1 for Frequency modulation +// inline void ComputeVoiceOscillatorFrequencyModulation(int nvoice); + inline void ComputeVoiceOscillatorPitchModulation(int nvoice); + + inline void ComputeVoiceNoise(int nvoice); + + inline void fadein(REALTYPE *smps); + + + //GLOBALS + ADnoteParameters *partparams; + unsigned char stereo;//if the note is stereo (allows note Panning) + int midinote; + REALTYPE velocity,basefreq; + + ONOFFTYPE NoteEnabled; + Controller *ctl; + + /*****************************************************************/ + /* GLOBAL PARAMETERS */ + /*****************************************************************/ + + struct ADnoteGlobal{ + /****************************************** + * FREQUENCY GLOBAL PARAMETERS * + ******************************************/ + REALTYPE Detune;//cents + + Envelope *FreqEnvelope; + LFO *FreqLfo; + + /******************************************** + * AMPLITUDE GLOBAL PARAMETERS * + ********************************************/ + REALTYPE Volume;// [ 0 .. 1 ] + + REALTYPE Panning;// [ 0 .. 1 ] + + Envelope *AmpEnvelope; + LFO *AmpLfo; + + struct { + int Enabled; + REALTYPE initialvalue,dt,t; + } Punch; + + /****************************************** + * FILTER GLOBAL PARAMETERS * + ******************************************/ + Filter *GlobalFilterL,*GlobalFilterR; + + REALTYPE FilterCenterPitch;//octaves + REALTYPE FilterQ; + REALTYPE FilterFreqTracking; + + Envelope *FilterEnvelope; + + LFO *FilterLfo; + } NoteGlobalPar; + + + + /***********************************************************/ + /* VOICE PARAMETERS */ + /***********************************************************/ + struct ADnoteVoice{ + /* If the voice is enabled */ + ONOFFTYPE Enabled; + + /* Voice Type (sound/noise)*/ + int noisetype; + + /* Filter Bypass */ + int filterbypass; + + /* Delay (ticks) */ + int DelayTicks; + + /* Waveform of the Voice */ + REALTYPE *OscilSmp; + + /************************************ + * FREQUENCY PARAMETERS * + ************************************/ + int fixedfreq;//if the frequency is fixed to 440 Hz + int fixedfreqET;//if the "fixed" frequency varies according to the note (ET) + + // cents = basefreq*VoiceDetune + REALTYPE Detune,FineDetune; + + Envelope *FreqEnvelope; + LFO *FreqLfo; + + + /*************************** + * AMPLITUDE PARAMETERS * + ***************************/ + + /* Panning 0.0=left, 0.5 - center, 1.0 = right */ + REALTYPE Panning; + REALTYPE Volume;// [-1.0 .. 1.0] + + Envelope *AmpEnvelope; + LFO *AmpLfo; + + /************************* + * FILTER PARAMETERS * + *************************/ + + Filter *VoiceFilter; + + REALTYPE FilterCenterPitch;/* Filter center Pitch*/ + REALTYPE FilterFreqTracking; + + Envelope *FilterEnvelope; + LFO *FilterLfo; + + + /**************************** + * MODULLATOR PARAMETERS * + ****************************/ + + FMTYPE FMEnabled; + + int FMVoice; + + // Voice Output used by other voices if use this as modullator + REALTYPE *VoiceOut; + + /* Wave of the Voice */ + REALTYPE *FMSmp; + + REALTYPE FMVolume; + REALTYPE FMDetune; //in cents + + Envelope *FMFreqEnvelope; + Envelope *FMAmpEnvelope; + } NoteVoicePar[NUM_VOICES]; + + + /********************************************************/ + /* INTERNAL VALUES OF THE NOTE AND OF THE VOICES */ + /********************************************************/ + + //time from the start of the note + REALTYPE time; + + //fractional part (skip) + REALTYPE oscposlo[NUM_VOICES],oscfreqlo[NUM_VOICES]; + + //integer part (skip) + int oscposhi[NUM_VOICES],oscfreqhi[NUM_VOICES]; + + //fractional part (skip) of the Modullator + REALTYPE oscposloFM[NUM_VOICES],oscfreqloFM[NUM_VOICES]; + + //integer part (skip) of the Modullator + unsigned short int oscposhiFM[NUM_VOICES],oscfreqhiFM[NUM_VOICES]; + + //used to compute and interpolate the amplitudes of voices and modullators + REALTYPE oldamplitude[NUM_VOICES], + newamplitude[NUM_VOICES], + FMoldamplitude[NUM_VOICES], + FMnewamplitude[NUM_VOICES]; + + //used by Frequency Modulation (for integration) + REALTYPE FMoldsmp[NUM_VOICES]; + + //temporary buffer + REALTYPE *tmpwave; + + //Filter bypass samples + REALTYPE *bypassl,*bypassr; + + //interpolate the amplitudes + REALTYPE globaloldamplitude,globalnewamplitude; + + //1 - if it is the fitst tick (used to fade in the sound) + char firsttick[NUM_VOICES]; + + //1 if the note has portamento + int portamento; + + //how the fine detunes are made bigger or smaller + REALTYPE bandwidthDetuneMultiplier; + + // Legato vars + struct { + bool silent; + REALTYPE lastfreq; + LegatoMsg msg; + int decounter; + struct { // Fade In/Out vars + int length; + REALTYPE m, step; + } fade; + struct { // Note parameters + REALTYPE freq, vel; + int portamento, midinote; + } param; + } Legato; +}; + +#endif + + + + diff --git a/plugins/zynaddsubfx/src/Synth/Envelope.C b/plugins/zynaddsubfx/src/Synth/Envelope.C new file mode 100644 index 000000000..6337ab421 --- /dev/null +++ b/plugins/zynaddsubfx/src/Synth/Envelope.C @@ -0,0 +1,165 @@ +/* + ZynAddSubFX - a software synthesizer + + Envelope.C - Envelope implementation + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include +#include "Envelope.h" + +Envelope::Envelope(EnvelopeParams *envpars,REALTYPE basefreq){ + int i; + envpoints=envpars->Penvpoints; + if (envpoints>MAX_ENVELOPE_POINTS) envpoints=MAX_ENVELOPE_POINTS; + envsustain=(envpars->Penvsustain==0)?-1:envpars->Penvsustain; + forcedrelase=envpars->Pforcedrelease; + envstretch=pow(440.0/basefreq,envpars->Penvstretch/64.0); + linearenvelope=envpars->Plinearenvelope; + + if (envpars->Pfreemode==0) envpars->converttofree(); + + REALTYPE bufferdt=SOUND_BUFFER_SIZE/(REALTYPE)SAMPLE_RATE; + + int mode=envpars->Envmode; + + //for amplitude envelopes + if ((mode==1)&&(linearenvelope==0)) mode=2;//change to log envelope + if ((mode==2)&&(linearenvelope!=0)) mode=1;//change to linear + + for (i=0;igetdt(i)/1000.0*envstretch; + if (tmp>bufferdt) envdt[i]=bufferdt/tmp; + else envdt[i]=2.0;//any value larger than 1 + + switch (mode){ + case 2:envval[i]=(1.0-envpars->Penvval[i]/127.0)*MIN_ENVELOPE_DB; + break; + case 3:envval[i]=(pow(2,6.0*fabs(envpars->Penvval[i]-64.0)/64.0)-1.0)*100.0; + if (envpars->Penvval[i]<64) envval[i]=-envval[i]; + break; + case 4:envval[i]=(envpars->Penvval[i]-64.0)/64.0*6.0;//6 octaves (filtru) + break; + case 5:envval[i]=(envpars->Penvval[i]-64.0)/64.0*10; + break; + default:envval[i]=envpars->Penvval[i]/127.0; + }; + + }; + + envdt[0]=1.0; + + currentpoint=1;//the envelope starts from 1 + keyreleased=0; + t=0.0; + envfinish=0; + inct=envdt[1]; + envoutval=0.0; +}; + +Envelope::~Envelope(){ +}; + + +/* + * Relase the key (note envelope) + */ +void Envelope::relasekey(){ + if (keyreleased==1) return; + keyreleased=1; + if (forcedrelase!=0) t=0.0; +}; + +/* + * Envelope Output + */ +REALTYPE Envelope::envout(){ + REALTYPE out; + + if (envfinish!=0) {//if the envelope is finished + envoutval=envval[envpoints-1]; + return(envoutval); + }; + if ((currentpoint==envsustain+1)&&(keyreleased==0)) {//if it is sustaining now + envoutval=envval[envsustain]; + return(envoutval); + }; + + if ((keyreleased!=0) && (forcedrelase!=0)){//do the forced release + + int tmp=(envsustain<0) ? (envpoints-1):(envsustain+1);//if there is no sustain point, use the last point for release + + if (envdt[tmp]<0.00000001) out=envval[tmp]; + else out=envoutval+(envval[tmp]-envoutval)*t; + t+=envdt[tmp]*envstretch; + + if (t>=1.0) { + currentpoint=envsustain+2; + forcedrelase=0; + t=0.0; + inct=envdt[currentpoint]; + if ((currentpoint>=envpoints)||(envsustain<0)) envfinish=1; + }; + return(out); + }; + if (inct>=1.0) out=envval[currentpoint]; + else out=envval[currentpoint-1]+(envval[currentpoint]-envval[currentpoint-1])*t; + + t+=inct; + if (t>=1.0){ + if (currentpoint>=envpoints-1) envfinish=1; + else currentpoint++; + t=0.0; + inct=envdt[currentpoint]; + }; + + envoutval=out; + return (out); +}; + +/* + * Envelope Output (dB) + */ +REALTYPE Envelope::envout_dB(){ + REALTYPE out; + if (linearenvelope!=0) return (envout()); + + if ((currentpoint==1)&&((keyreleased==0)||(forcedrelase==0))) {//first point is always lineary interpolated + REALTYPE v1=dB2rap(envval[0]); + REALTYPE v2=dB2rap(envval[1]); + out=v1+(v2-v1)*t; + + t+=inct; + if (t>=1.0) { + t=0.0; + inct=envdt[2]; + currentpoint++; + out=v2; + }; + + if (out>0.001) envoutval=rap2dB(out); + else envoutval=-40.0; + } else out=dB2rap(envout()); + + return(out); +}; + +int Envelope::finished(){ + return(envfinish); +}; + diff --git a/plugins/zynaddsubfx/src/Synth/Envelope.h b/plugins/zynaddsubfx/src/Synth/Envelope.h new file mode 100644 index 000000000..4c2598ff4 --- /dev/null +++ b/plugins/zynaddsubfx/src/Synth/Envelope.h @@ -0,0 +1,58 @@ +/* + ZynAddSubFX - a software synthesizer + + Envelope.h - Envelope implementation + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef ENVELOPE_H +#define ENVELOPE_H + +#include +#include "../globals.h" +#include "../Params/EnvelopeParams.h" + +class Envelope{ +public: + Envelope(EnvelopeParams *envpars,REALTYPE basefreq); + ~Envelope(); + void relasekey(); + REALTYPE envout(); + REALTYPE envout_dB(); + int finished();//returns 1 if the envelope is finished +private: + int envpoints; + int envsustain;//"-1" means disabled + REALTYPE envdt[MAX_ENVELOPE_POINTS];//millisecons + REALTYPE envval[MAX_ENVELOPE_POINTS];// [0.0 .. 1.0] + REALTYPE envstretch; + int linearenvelope; + + int currentpoint; //current envelope point (starts from 1) + int forcedrelase; + char keyreleased; //if the key was released + char envfinish; + REALTYPE t; // the time from the last point + REALTYPE inct;// the time increment + REALTYPE envoutval;//used to do the forced release +}; + + +#endif + + diff --git a/plugins/zynaddsubfx/src/Synth/LFO.C b/plugins/zynaddsubfx/src/Synth/LFO.C new file mode 100644 index 000000000..420158eac --- /dev/null +++ b/plugins/zynaddsubfx/src/Synth/LFO.C @@ -0,0 +1,145 @@ +/* + ZynAddSubFX - a software synthesizer + + LFO.C - LFO implementation + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include +#include +#include + +#include "LFO.h" + + +LFO::LFO(LFOParams *lfopars,REALTYPE basefreq){ + if (lfopars->Pstretch==0) lfopars->Pstretch=1; + REALTYPE lfostretch=pow(basefreq/440.0,(lfopars->Pstretch-64.0)/63.0);//max 2x/octave + + REALTYPE lfofreq=(pow(2,lfopars->Pfreq*10.0)-1.0)/12.0*lfostretch; + incx=fabs(lfofreq)*(REALTYPE)SOUND_BUFFER_SIZE/(REALTYPE)SAMPLE_RATE; + + if (lfopars->Pcontinous==0){ + if (lfopars->Pstartphase==0) x=RND; + else x=fmod((lfopars->Pstartphase-64.0)/127.0+1.0,1.0); + } else { + REALTYPE tmp=fmod(lfopars->time*incx,1.0); + x=fmod((lfopars->Pstartphase-64.0)/127.0+1.0+tmp,1.0); + }; + + //Limit the Frequency(or else...) + if (incx>0.49999999) incx=0.499999999; + + + lfornd=lfopars->Prandomness/127.0; + if (lfornd<0.0) lfornd=0.0; else if (lfornd>1.0) lfornd=1.0; + +// lfofreqrnd=pow(lfopars->Pfreqrand/127.0,2.0)*2.0*4.0; + lfofreqrnd=pow(lfopars->Pfreqrand/127.0,2.0)*4.0; + + switch (lfopars->fel){ + case 1:lfointensity=lfopars->Pintensity/127.0;break; + case 2:lfointensity=lfopars->Pintensity/127.0*4.0;break;//in octave + default:lfointensity=pow(2,lfopars->Pintensity/127.0*11.0)-1.0;//in centi + x-=0.25;//chance the starting phase + break; + }; + + amp1=(1-lfornd)+lfornd*RND; + amp2=(1-lfornd)+lfornd*RND; + lfotype=lfopars->PLFOtype; + lfodelay=lfopars->Pdelay/127.0*4.0;//0..4 sec + incrnd=nextincrnd=1.0; + freqrndenabled=(lfopars->Pfreqrand!=0); + computenextincrnd(); + computenextincrnd();//twice because I want incrnd & nextincrnd to be random +}; + +LFO::~LFO(){ +}; + +/* + * LFO out + */ +REALTYPE LFO::lfoout(){ + REALTYPE out; + switch (lfotype){ + case 1: //LFO_TRIANGLE + if ((x>=0.0)&&(x<0.25)) out=4.0*x; + else if ((x>0.25)&&(x<0.75)) out=2-4*x; + else out=4.0*x-4.0; + break; + case 2: //LFO_SQUARE + if (x<0.5) out=-1; + else out=1; + break; + case 3: //LFO_RAMPUP + out=(x-0.5)*2.0; + break; + case 4: //LFO_RAMPDOWN + out=(0.5-x)*2.0; + break; + case 5: //LFO_EXP_DOWN 1 + out=pow(0.05,x)*2.0-1.0; + break; + case 6: //LFO_EXP_DOWN 2 + out=pow(0.001,x)*2.0-1.0; + break; + default:out=cos(x*2.0*PI);//LFO_SINE + }; + + + if ((lfotype==0)||(lfotype==1)) out*=lfointensity*(amp1+x*(amp2-amp1)); + else out*=lfointensity*amp2; + if (lfodelay<0.00001) { + if (freqrndenabled==0) x+=incx; + else { + float tmp=(incrnd*(1.0-x)+nextincrnd*x); + if (tmp>1.0) tmp=1.0; + else if (tmp<0.0) tmp=0.0; + x+=incx*tmp; + }; + if (x>=1) { + x=fmod(x,1.0); + amp1=amp2; + amp2=(1-lfornd)+lfornd*RND; + + computenextincrnd(); + }; + } else lfodelay-=(REALTYPE)SOUND_BUFFER_SIZE/(REALTYPE)SAMPLE_RATE; + return(out); +}; + +/* + * LFO out (for amplitude) + */ +REALTYPE LFO::amplfoout(){ + REALTYPE out; + out=1.0-lfointensity+lfoout(); + if (out<-1.0) out=-1.0; + else if (out>1.0) out=1.0; + return(out); +}; + + +void LFO::computenextincrnd(){ + if (freqrndenabled==0) return; + incrnd=nextincrnd; + nextincrnd=pow(0.5,lfofreqrnd)+RND*(pow(2.0,lfofreqrnd)-1.0); +}; + diff --git a/plugins/zynaddsubfx/src/Synth/LFO.h b/plugins/zynaddsubfx/src/Synth/LFO.h new file mode 100644 index 000000000..ac66e780d --- /dev/null +++ b/plugins/zynaddsubfx/src/Synth/LFO.h @@ -0,0 +1,52 @@ +/* + ZynAddSubFX - a software synthesizer + + LFO.h - LFO implementation + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef LFO_H +#define LFO_H + +#include "../globals.h" +#include "../Params/LFOParams.h" + + +class LFO{ + public: + LFO(LFOParams *lfopars, REALTYPE basefreq); + ~LFO(); + REALTYPE lfoout(); + REALTYPE amplfoout(); + private: + REALTYPE x; + REALTYPE incx,incrnd,nextincrnd; + REALTYPE amp1,amp2;// used for randomness + REALTYPE lfointensity; + REALTYPE lfornd,lfofreqrnd; + REALTYPE lfodelay; + char lfotype; + int freqrndenabled; + + + void computenextincrnd(); + +}; + + +#endif diff --git a/plugins/zynaddsubfx/src/Synth/OscilGen.C b/plugins/zynaddsubfx/src/Synth/OscilGen.C new file mode 100644 index 000000000..ba1102735 --- /dev/null +++ b/plugins/zynaddsubfx/src/Synth/OscilGen.C @@ -0,0 +1,1182 @@ +/* + ZynAddSubFX - a software synthesizer + + OscilGen.C - Waveform generator for ADnote + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include +#include +#include + +#include "OscilGen.h" +#include "../Effects/Distorsion.h" + +REALTYPE *OscilGen::tmpsmps;//this array stores some termporary data and it has SOUND_BUFFER_SIZE elements +FFTFREQS OscilGen::outoscilFFTfreqs; + + +OscilGen::OscilGen(FFTwrapper *fft_,Resonance *res_):Presets(){ + setpresettype("Poscilgen"); + fft=fft_; + res=res_; + newFFTFREQS(&oscilFFTfreqs,OSCIL_SIZE/2); + newFFTFREQS(&basefuncFFTfreqs,OSCIL_SIZE/2); + + randseed=1; + ADvsPAD=false; + + defaults(); +}; + +OscilGen::~OscilGen(){ + deleteFFTFREQS(&basefuncFFTfreqs); + deleteFFTFREQS(&oscilFFTfreqs); +}; + + +void OscilGen::defaults(){ + + oldbasefunc=0;oldbasepar=64;oldhmagtype=0;oldwaveshapingfunction=0;oldwaveshaping=64; + oldbasefuncmodulation=0;oldharmonicshift=0;oldbasefuncmodulationpar1=0;oldbasefuncmodulationpar2=0;oldbasefuncmodulationpar3=0; + oldmodulation=0;oldmodulationpar1=0;oldmodulationpar2=0;oldmodulationpar3=0; + + for (int i=0;ismps2freqs(oscil,freqs); + delete(fft); + + REALTYPE max=0.0; + + mag[0]=0; + phase[0]=0; + for (int i=0;i127) Phphase[i]=127; + + if (Phmag[i]==64) Phphase[i]=64; + }; + deleteFFTFREQS(&freqs); + prepare(); +}; + +/* + * Base Functions - START + */ +REALTYPE OscilGen::basefunc_pulse(REALTYPE x,REALTYPE a){ + return((fmod(x,1.0)0.99999) a=0.99999; + x=fmod(x,1); + if (x1.0) x=1.0; + return(x); +}; + +REALTYPE OscilGen::basefunc_power(REALTYPE x,REALTYPE a){ + x=fmod(x,1); + if (a<0.00001) a=0.00001; + else if (a>0.99999) a=0.99999; + return(pow(x,exp((a-0.5)*10.0))*2.0-1.0); +}; + +REALTYPE OscilGen::basefunc_gauss(REALTYPE x,REALTYPE a){ + x=fmod(x,1)*2.0-1.0; + if (a<0.00001) a=0.00001; + return(exp(-x*x*(exp(a*8)+5.0))*2.0-1.0); +}; + +REALTYPE OscilGen::basefunc_diode(REALTYPE x,REALTYPE a){ + if (a<0.00001) a=0.00001; + else if (a>0.99999) a=0.99999; + a=a*2.0-1.0; + x=cos((x+0.5)*2.0*PI)-a; + if (x<0.0) x=0.0; + return(x/(1.0-a)*2-1.0); +}; + +REALTYPE OscilGen::basefunc_abssine(REALTYPE x,REALTYPE a){ + x=fmod(x,1); + if (a<0.00001) a=0.00001; + else if (a>0.99999) a=0.99999; + return(sin(pow(x,exp((a-0.5)*5.0))*PI)*2.0-1.0); +}; + +REALTYPE OscilGen::basefunc_pulsesine(REALTYPE x,REALTYPE a){ + if (a<0.00001) a=0.00001; + x=(fmod(x,1)-0.5)*exp((a-0.5)*log(128)); + if (x<-0.5) x=-0.5; + else if (x>0.5) x=0.5; + x=sin(x*PI*2.0); + return(x); +}; + +REALTYPE OscilGen::basefunc_stretchsine(REALTYPE x,REALTYPE a){ + x=fmod(x+0.5,1)*2.0-1.0; + a=(a-0.5)*4;if (a>0.0) a*=2; + a=pow(3.0,a); + REALTYPE b=pow(fabs(x),a); + if (x<0) b=-b; + return(-sin(b*PI)); +}; + +REALTYPE OscilGen::basefunc_chirp(REALTYPE x,REALTYPE a){ + x=fmod(x,1.0)*2.0*PI; + a=(a-0.5)*4;if (a<0.0) a*=2.0; + a=pow(3.0,a); + return(sin(x/2.0)*sin(a*x*x)); +}; + +REALTYPE OscilGen::basefunc_absstretchsine(REALTYPE x,REALTYPE a){ + x=fmod(x+0.5,1)*2.0-1.0; + a=(a-0.5)*9; + a=pow(3.0,a); + REALTYPE b=pow(fabs(x),a); + if (x<0) b=-b; + return(-pow(sin(b*PI),2)); +}; + +REALTYPE OscilGen::basefunc_chebyshev(REALTYPE x,REALTYPE a){ + a=a*a*a*30.0+1.0; + return(cos(acos(x*2.0-1.0)*a)); +}; + +REALTYPE OscilGen::basefunc_sqr(REALTYPE x,REALTYPE a){ + a=a*a*a*a*160.0+0.001; + return(-atan(sin(x*2.0*PI)*a)); +}; +/* + * Base Functions - END + */ + + +/* + * Get the base function + */ +void OscilGen::getbasefunction(REALTYPE *smps){ + int i; + REALTYPE par=(Pbasefuncpar+0.5)/128.0; + if (Pbasefuncpar==64) par=0.5; + + REALTYPE basefuncmodulationpar1=Pbasefuncmodulationpar1/127.0, + basefuncmodulationpar2=Pbasefuncmodulationpar2/127.0, + basefuncmodulationpar3=Pbasefuncmodulationpar3/127.0; + + switch(Pbasefuncmodulation){ + case 1:basefuncmodulationpar1=(pow(2,basefuncmodulationpar1*5.0)-1.0)/10.0; + basefuncmodulationpar3=floor((pow(2,basefuncmodulationpar3*5.0)-1.0)); + if (basefuncmodulationpar3<0.9999) basefuncmodulationpar3=-1.0; + break; + case 2:basefuncmodulationpar1=(pow(2,basefuncmodulationpar1*5.0)-1.0)/10.0; + basefuncmodulationpar3=1.0+floor((pow(2,basefuncmodulationpar3*5.0)-1.0)); + break; + case 3:basefuncmodulationpar1=(pow(2,basefuncmodulationpar1*7.0)-1.0)/10.0; + basefuncmodulationpar3=0.01+(pow(2,basefuncmodulationpar3*16.0)-1.0)/10.0; + break; + }; + +// printf("%.5f %.5f\n",basefuncmodulationpar1,basefuncmodulationpar3); + + for (i=0;ipow(2,(1.0-par)*10)?0.0:1.0)*par2+(1.0-par2);//lp2 + break; + case 7: tmp=pow(par2,0.33); + //tmp=1.0-(1.0-par2)*(1.0-par2); + gain=(i+1>pow(2,(1.0-par)*7)?1.0:0.0)*par2+(1.0-par2);//hp2 + if (Pfilterpar1==0) gain=1.0; + break; + case 8: tmp=pow(par2,0.33); + //tmp=1.0-(1.0-par2)*(1.0-par2); + gain=(fabs(pow(2,(1.0-par)*7)-i)>i/2+1?0.0:1.0)*par2+(1.0-par2);//bp2 + break; + case 9: tmp=pow(par2,0.33); + gain=(fabs(pow(2,(1.0-par)*7)-i)1.0) x=1.0; + tmp=pow(1.0-par2,2.0); + gain=cos(x*PI)*(1.0-tmp)+1.01+tmp;//low shelf + break; + case 13:tmp=(int) (pow(2.0,(1.0-par)*7.2)); + gain=1.0; + if (i==(int) (tmp)) gain=pow(2.0,par2*par2*8.0); + break; + }; + + + oscilFFTfreqs.s[i]*=gain; + oscilFFTfreqs.c[i]*=gain; + REALTYPE tmp=oscilFFTfreqs.s[i]*oscilFFTfreqs.s[i]+ + oscilFFTfreqs.c[i]*oscilFFTfreqs.c[i]; + if (maxsmps2freqs(tmpsmps,basefuncFFTfreqs); + basefuncFFTfreqs.c[0]=0.0; + } else { + for (int i=0;ifreqs2smps(oscilFFTfreqs,tmpsmps); + + //Normalize + REALTYPE max=0.0; + for (i=0;ismps2freqs(tmpsmps,oscilFFTfreqs);//perform FFT +}; + + +/* + * Do the Frequency Modulation of the Oscil + */ +void OscilGen::modulation(){ + int i; + + oldmodulation=Pmodulation; + oldmodulationpar1=Pmodulationpar1; + oldmodulationpar2=Pmodulationpar2; + oldmodulationpar3=Pmodulationpar3; + if (Pmodulation==0) return; + + + REALTYPE modulationpar1=Pmodulationpar1/127.0, + modulationpar2=0.5-Pmodulationpar2/127.0, + modulationpar3=Pmodulationpar3/127.0; + + switch(Pmodulation){ + case 1:modulationpar1=(pow(2,modulationpar1*7.0)-1.0)/100.0; + modulationpar3=floor((pow(2,modulationpar3*5.0)-1.0)); + if (modulationpar3<0.9999) modulationpar3=-1.0; + break; + case 2:modulationpar1=(pow(2,modulationpar1*7.0)-1.0)/100.0; + modulationpar3=1.0+floor((pow(2,modulationpar3*5.0)-1.0)); + break; + case 3:modulationpar1=(pow(2,modulationpar1*9.0)-1.0)/100.0; + modulationpar3=0.01+(pow(2,modulationpar3*16.0)-1.0)/10.0; + break; + }; + + oscilFFTfreqs.c[0]=0.0;//remove the DC + //reduce the amplitude of the freqs near the nyquist + for (i=1;ifreqs2smps(oscilFFTfreqs,tmpsmps); + int extra_points=2; + REALTYPE *in=new REALTYPE[OSCIL_SIZE+extra_points]; + + //Normalize + REALTYPE max=0.0; + for (i=0;ismps2freqs(tmpsmps,oscilFFTfreqs);//perform FFT +}; + + + +/* + * Adjust the spectrum + */ +void OscilGen::spectrumadjust(){ + if (Psatype==0) return; + REALTYPE par=Psapar/127.0; + switch(Psatype){ + case 1: par=1.0-par*2.0; + if (par>=0.0) par=pow(5.0,par); + else par=pow(8.0,par); + break; + case 2: par=pow(10.0,(1.0-par)*3.0)*0.25; + break; + case 3: par=pow(10.0,(1.0-par)*3.0)*0.25; + break; + }; + + + REALTYPE max=0.0; + for (int i=0;i1.0) mag=1.0; + break; + }; + oscilFFTfreqs.c[i]=mag*cos(phase); + oscilFFTfreqs.s[i]=mag*sin(phase); + }; + +}; + +void OscilGen::shiftharmonics(){ + if (Pharmonicshift==0) return; + + REALTYPE hc,hs; + int harmonicshift=-Pharmonicshift; + + if (harmonicshift>0){ + for (int i=OSCIL_SIZE/2-2;i>=0;i--){ + int oldh=i-harmonicshift; + if (oldh<0){ + hc=0.0; + hs=0.0; + } else { + hc=oscilFFTfreqs.c[oldh+1]; + hs=oscilFFTfreqs.s[oldh+1]; + }; + oscilFFTfreqs.c[i+1]=hc; + oscilFFTfreqs.s[i+1]=hs; + }; + } else { + for (int i=0;i=(OSCIL_SIZE/2-1)){ + hc=0.0; + hs=0.0; + } else { + hc=oscilFFTfreqs.c[oldh+1]; + hs=oscilFFTfreqs.s[oldh+1]; + if (fabs(hc)<0.000001) hc=0.0; + if (fabs(hs)<0.000001) hs=0.0; + }; + + oscilFFTfreqs.c[i+1]=hc; + oscilFFTfreqs.s[i+1]=hs; + }; + }; + + oscilFFTfreqs.c[0]=0.0; +}; + +/* + * Prepare the Oscillator + */ +void OscilGen::prepare(){ + int i,j,k; + REALTYPE a,b,c,d,hmagnew; + + if ((oldbasepar!=Pbasefuncpar)||(oldbasefunc!=Pcurrentbasefunc)|| + (oldbasefuncmodulation!=Pbasefuncmodulation)|| + (oldbasefuncmodulationpar1!=Pbasefuncmodulationpar1)|| + (oldbasefuncmodulationpar2!=Pbasefuncmodulationpar2)|| + (oldbasefuncmodulationpar3!=Pbasefuncmodulationpar3)) + changebasefunction(); + + for (i=0;i=OSCIL_SIZE/2) break; + a=basefuncFFTfreqs.c[i]; + b=basefuncFFTfreqs.s[i]; + c=hmag[j]*cos(hphase[j]*k); + d=hmag[j]*sin(hphase[j]*k); + oscilFFTfreqs.c[k]+=a*c-b*d; + oscilFFTfreqs.s[k]+=a*d+b*c; + }; + }; + + }; + + if (Pharmonicshiftfirst!=0) shiftharmonics(); + + + + if (Pfilterbeforews==0){ + waveshape(); + oscilfilter(); + } else { + oscilfilter(); + waveshape(); + }; + + modulation(); + spectrumadjust(); + if (Pharmonicshiftfirst==0) shiftharmonics(); + + oscilFFTfreqs.c[0]=0.0; + + oldhmagtype=Phmagtype; + oldharmonicshift=Pharmonicshift+Pharmonicshiftfirst*256; + + oscilprepared=1; +}; + +void OscilGen::adaptiveharmonic(FFTFREQS f,REALTYPE freq){ + if ((Padaptiveharmonics==0)/*||(freq<1.0)*/) return; + if (freq<1.0) freq=440.0; + + FFTFREQS inf; + newFFTFREQS(&inf,OSCIL_SIZE/2); + for (int i=0;i1.0) { + rap=1.0/rap; + down=true; + }; + + for (int i=0;i=(OSCIL_SIZE/2-2)){ + break; + } else { + if (down){ + f.c[high]+=inf.c[i]*(1.0-low); + f.s[high]+=inf.s[i]*(1.0-low); + f.c[high+1]+=inf.c[i]*low; + f.s[high+1]+=inf.s[i]*low; + } else { + hc=inf.c[high]*(1.0-low)+inf.c[high+1]*low; + hs=inf.s[high]*(1.0-low)+inf.s[high+1]*low; + }; + if (fabs(hc)<0.000001) hc=0.0; + if (fabs(hs)<0.000001) hs=0.0; + }; + + if (!down){ + if (i==0) {//corect the aplitude of the first harmonic + hc*=rap; + hs*=rap; + }; + f.c[i]=hc; + f.s[i]=hs; + }; + }; + + f.c[1]+=f.c[0];f.s[1]+=f.s[0]; + f.c[0]=0.0;f.s[0]=0.0; + deleteFFTFREQS(&inf); +}; + +void OscilGen::adaptiveharmonicpostprocess(REALTYPE *f,int size){ + if (Padaptiveharmonics<=1) return; + REALTYPE *inf=new REALTYPE[size]; + REALTYPE par=Padaptiveharmonicspar*0.01; + par=1.0-pow((1.0-par),1.5); + + for (int i=0;iget(smps,freqHz,0)); +}; + +void OscilGen::newrandseed(unsigned int randseed){ + this->randseed=randseed; +}; + +/* + * Get the oscillator function + */ +short int OscilGen::get(REALTYPE *smps,REALTYPE freqHz,int resonance){ + int i; + int nyquist,outpos; + + if ((oldbasepar!=Pbasefuncpar)||(oldbasefunc!=Pcurrentbasefunc)||(oldhmagtype!=Phmagtype) + ||(oldwaveshaping!=Pwaveshaping)||(oldwaveshapingfunction!=Pwaveshapingfunction)) oscilprepared=0; + if (oldfilterpars!=Pfiltertype*256+Pfilterpar1+Pfilterpar2*65536+Pfilterbeforews*16777216){ + oscilprepared=0; + oldfilterpars=Pfiltertype*256+Pfilterpar1+Pfilterpar2*65536+Pfilterbeforews*16777216; + }; + if (oldsapars!=Psatype*256+Psapar){ + oscilprepared=0; + oldsapars=Psatype*256+Psapar; + }; + + if ((oldbasefuncmodulation!=Pbasefuncmodulation)|| + (oldbasefuncmodulationpar1!=Pbasefuncmodulationpar1)|| + (oldbasefuncmodulationpar2!=Pbasefuncmodulationpar2)|| + (oldbasefuncmodulationpar3!=Pbasefuncmodulationpar3)) + oscilprepared=0; + + if ((oldmodulation!=Pmodulation)|| + (oldmodulationpar1!=Pmodulationpar1)|| + (oldmodulationpar2!=Pmodulationpar2)|| + (oldmodulationpar3!=Pmodulationpar3)) + oscilprepared=0; + + if (oldharmonicshift!=Pharmonicshift+Pharmonicshiftfirst*256) oscilprepared=0; + + if (oscilprepared!=1) prepare(); + + outpos=(int)((RND*2.0-1.0)*(REALTYPE) OSCIL_SIZE*(Prand-64.0)/64.0); + outpos=(outpos+2*OSCIL_SIZE) % OSCIL_SIZE; + + + for (i=0;iOSCIL_SIZE/2) nyquist=OSCIL_SIZE/2; + + + int realnyquist=nyquist; + + if (Padaptiveharmonics!=0) nyquist=OSCIL_SIZE/2; + for (i=1;i64)&&(freqHz>=0.0)&&(!ADvsPAD)){ + REALTYPE rnd,angle,a,b,c,d; + rnd=PI*pow((Prand-64.0)/64.0,2.0); + for (i=1;i0.1)&&(!ADvsPAD)) { + unsigned int realrnd=rand(); + srand(randseed); + REALTYPE power=Pamprandpower/127.0; + REALTYPE normalize=1.0/(1.2-power); + switch (Pamprandtype){ + case 1: power=power*2.0-0.5; + power=pow(15.0,power); + for (i=1;i0.1)&&(resonance!=0)) res->applyres(nyquist-1,outoscilFFTfreqs,freqHz); + + //Full RMS normalize + REALTYPE sum=0; + for (int j=1;j0.1)){//in this case the smps will contain the freqs + for (i=1;ifreqs2smps(outoscilFFTfreqs,smps); + for (i=0;iOSCIL_SIZE/2) n=OSCIL_SIZE/2; + + for (int i=1;ifreqs2smps(basefuncFFTfreqs,smps); + } else getbasefunction(smps);//the sine case +}; + + +void OscilGen::add2XML(XMLwrapper *xml){ + xml->addpar("harmonic_mag_type",Phmagtype); + + xml->addpar("base_function",Pcurrentbasefunc); + xml->addpar("base_function_par",Pbasefuncpar); + xml->addpar("base_function_modulation",Pbasefuncmodulation); + xml->addpar("base_function_modulation_par1",Pbasefuncmodulationpar1); + xml->addpar("base_function_modulation_par2",Pbasefuncmodulationpar2); + xml->addpar("base_function_modulation_par3",Pbasefuncmodulationpar3); + + xml->addpar("modulation",Pmodulation); + xml->addpar("modulation_par1",Pmodulationpar1); + xml->addpar("modulation_par2",Pmodulationpar2); + xml->addpar("modulation_par3",Pmodulationpar3); + + xml->addpar("wave_shaping",Pwaveshaping); + xml->addpar("wave_shaping_function",Pwaveshapingfunction); + + xml->addpar("filter_type",Pfiltertype); + xml->addpar("filter_par1",Pfilterpar1); + xml->addpar("filter_par2",Pfilterpar2); + xml->addpar("filter_before_wave_shaping",Pfilterbeforews); + + xml->addpar("spectrum_adjust_type",Psatype); + xml->addpar("spectrum_adjust_par",Psapar); + + xml->addpar("rand",Prand); + xml->addpar("amp_rand_type",Pamprandtype); + xml->addpar("amp_rand_power",Pamprandpower); + + xml->addpar("harmonic_shift",Pharmonicshift); + xml->addparbool("harmonic_shift_first",Pharmonicshiftfirst); + + xml->addpar("adaptive_harmonics",Padaptiveharmonics); + xml->addpar("adaptive_harmonics_base_frequency",Padaptiveharmonicsbasefreq); + xml->addpar("adaptive_harmonics_power",Padaptiveharmonicspower); + + xml->beginbranch("HARMONICS"); + for (int n=0;nbeginbranch("HARMONIC",n+1); + xml->addpar("mag",Phmag[n]); + xml->addpar("phase",Phphase[n]); + xml->endbranch(); + }; + xml->endbranch(); + + if (Pcurrentbasefunc==127){ + REALTYPE max=0.0; + + for (int i=0;ibeginbranch("BASE_FUNCTION"); + for (int i=1;i0.00001)&&(fabs(xs)>0.00001)){ + xml->beginbranch("BF_HARMONIC",i); + xml->addparreal("cos",xc); + xml->addparreal("sin",xs); + xml->endbranch(); + }; + }; + xml->endbranch(); + }; +}; + + +void OscilGen::getfromXML(XMLwrapper *xml){ + + Phmagtype=xml->getpar127("harmonic_mag_type",Phmagtype); + + Pcurrentbasefunc=xml->getpar127("base_function",Pcurrentbasefunc); + Pbasefuncpar=xml->getpar127("base_function_par",Pbasefuncpar); + + Pbasefuncmodulation=xml->getpar127("base_function_modulation",Pbasefuncmodulation); + Pbasefuncmodulationpar1=xml->getpar127("base_function_modulation_par1",Pbasefuncmodulationpar1); + Pbasefuncmodulationpar2=xml->getpar127("base_function_modulation_par2",Pbasefuncmodulationpar2); + Pbasefuncmodulationpar3=xml->getpar127("base_function_modulation_par3",Pbasefuncmodulationpar3); + + Pmodulation=xml->getpar127("modulation",Pmodulation); + Pmodulationpar1=xml->getpar127("modulation_par1",Pmodulationpar1); + Pmodulationpar2=xml->getpar127("modulation_par2",Pmodulationpar2); + Pmodulationpar3=xml->getpar127("modulation_par3",Pmodulationpar3); + + Pwaveshaping=xml->getpar127("wave_shaping",Pwaveshaping); + Pwaveshapingfunction=xml->getpar127("wave_shaping_function",Pwaveshapingfunction); + + Pfiltertype=xml->getpar127("filter_type",Pfiltertype); + Pfilterpar1=xml->getpar127("filter_par1",Pfilterpar1); + Pfilterpar2=xml->getpar127("filter_par2",Pfilterpar2); + Pfilterbeforews=xml->getpar127("filter_before_wave_shaping",Pfilterbeforews); + + Psatype=xml->getpar127("spectrum_adjust_type",Psatype); + Psapar=xml->getpar127("spectrum_adjust_par",Psapar); + + Prand=xml->getpar127("rand",Prand); + Pamprandtype=xml->getpar127("amp_rand_type",Pamprandtype); + Pamprandpower=xml->getpar127("amp_rand_power",Pamprandpower); + + Pharmonicshift=xml->getpar("harmonic_shift",Pharmonicshift,-64,64); + Pharmonicshiftfirst=xml->getparbool("harmonic_shift_first",Pharmonicshiftfirst); + + Padaptiveharmonics=xml->getpar("adaptive_harmonics",Padaptiveharmonics,0,127); + Padaptiveharmonicsbasefreq=xml->getpar("adaptive_harmonics_base_frequency",Padaptiveharmonicsbasefreq,0,255); + Padaptiveharmonicspower=xml->getpar("adaptive_harmonics_power",Padaptiveharmonicspower,0,200); + + + if (xml->enterbranch("HARMONICS")){ + Phmag[0]=64;Phphase[0]=64; + for (int n=0;nenterbranch("HARMONIC",n+1)==0) continue; + Phmag[n]=xml->getpar127("mag",64); + Phphase[n]=xml->getpar127("phase",64); + xml->exitbranch(); + }; + xml->exitbranch(); + }; + + if (Pcurrentbasefunc!=0) changebasefunction(); + + + if (xml->enterbranch("BASE_FUNCTION")){ + for (int i=1;ienterbranch("BF_HARMONIC",i)){ + basefuncFFTfreqs.c[i]=xml->getparreal("cos",0.0); + basefuncFFTfreqs.s[i]=xml->getparreal("sin",0.0); + xml->exitbranch(); + }; + + + }; + xml->exitbranch(); + + REALTYPE max=0.0; + + basefuncFFTfreqs.c[0]=0.0; + for (int i=0;i +#include "PADnote.h" +#include "../Misc/Config.h" + +PADnote::PADnote(PADnoteParameters *parameters, Controller *ctl_,REALTYPE freq, REALTYPE velocity, int portamento_, int midinote, bool besilent){ + ready=0; + + // Initialise some legato-specific vars + Legato.msg=LM_Norm; + Legato.fade.length=(int)(SAMPLE_RATE*0.005);// 0.005 seems ok. + if (Legato.fade.length<1) Legato.fade.length=1;// (if something's fishy) + Legato.fade.step=(1.0/Legato.fade.length); + Legato.decounter=-10; + Legato.param.freq=freq; + Legato.param.vel=velocity; + Legato.param.portamento=portamento_; + Legato.param.midinote=midinote; + Legato.silent=besilent; + + pars=parameters; + portamento=portamento_; + ctl=ctl_; + this->velocity=velocity; + finished_=false; + + + if (pars->Pfixedfreq==0) basefreq=freq; + else { + basefreq=440.0; + int fixedfreqET=pars->PfixedfreqET; + if (fixedfreqET!=0) {//if the frequency varies according the keyboard note + REALTYPE tmp=(midinote-69.0)/12.0*(pow(2.0,(fixedfreqET-1)/63.0)-1.0); + if (fixedfreqET<=64) basefreq*=pow(2.0,tmp); + else basefreq*=pow(3.0,tmp); + }; + + }; + + firsttime=true; + released=false; + realfreq=basefreq; + NoteGlobalPar.Detune=getdetune(pars->PDetuneType + ,pars->PCoarseDetune,pars->PDetune); + + + //find out the closest note + REALTYPE logfreq=log(basefreq*pow(2.0,NoteGlobalPar.Detune/1200.0)); + REALTYPE mindist=fabs(logfreq-log(pars->sample[0].basefreq+0.0001)); + nsample=0; + for (int i=1;isample[i].smp==NULL) break; + REALTYPE dist=fabs(logfreq-log(pars->sample[i].basefreq+0.0001)); +// printf("(mindist=%g) %i %g %g\n",mindist,i,dist,pars->sample[i].basefreq); + + if (distsample[nsample].size; + if (size==0) size=1; + + + poshi_l=(int)(RND*(size-1)); + if (pars->PStereo!=0) poshi_r=(poshi_l+size/2)%size; + else poshi_r=poshi_l; + poslo=0.0; + + tmpwave=new REALTYPE [SOUND_BUFFER_SIZE]; + + + + if (pars->PPanning==0) NoteGlobalPar.Panning=RND; + else NoteGlobalPar.Panning=pars->PPanning/128.0; + + NoteGlobalPar.FilterCenterPitch=pars->GlobalFilter->getfreq()+//center freq + pars->PFilterVelocityScale/127.0*6.0* //velocity sensing + (VelF(velocity,pars->PFilterVelocityScaleFunction)-1); + + if (pars->PPunchStrength!=0) { + NoteGlobalPar.Punch.Enabled=1; + NoteGlobalPar.Punch.t=1.0;//start from 1.0 and to 0.0 + NoteGlobalPar.Punch.initialvalue=( (pow(10,1.5*pars->PPunchStrength/127.0)-1.0) + *VelF(velocity,pars->PPunchVelocitySensing) ); + REALTYPE time=pow(10,3.0*pars->PPunchTime/127.0)/10000.0;//0.1 .. 100 ms + REALTYPE stretch=pow(440.0/freq,pars->PPunchStretch/64.0); + NoteGlobalPar.Punch.dt=1.0/(time*SAMPLE_RATE*stretch); + } else NoteGlobalPar.Punch.Enabled=0; + + + + NoteGlobalPar.FreqEnvelope=new Envelope(pars->FreqEnvelope,basefreq); + NoteGlobalPar.FreqLfo=new LFO(pars->FreqLfo,basefreq); + + NoteGlobalPar.AmpEnvelope=new Envelope(pars->AmpEnvelope,basefreq); + NoteGlobalPar.AmpLfo=new LFO(pars->AmpLfo,basefreq); + + NoteGlobalPar.Volume=4.0*pow(0.1,3.0*(1.0-pars->PVolume/96.0))//-60 dB .. 0 dB + *VelF(velocity,pars->PAmpVelocityScaleFunction);//velocity sensing + + NoteGlobalPar.AmpEnvelope->envout_dB();//discard the first envelope output + globaloldamplitude=globalnewamplitude=NoteGlobalPar.Volume*NoteGlobalPar.AmpEnvelope->envout_dB()*NoteGlobalPar.AmpLfo->amplfoout(); + + NoteGlobalPar.GlobalFilterL=new Filter(pars->GlobalFilter); + NoteGlobalPar.GlobalFilterR=new Filter(pars->GlobalFilter); + + NoteGlobalPar.FilterEnvelope=new Envelope(pars->FilterEnvelope,basefreq); + NoteGlobalPar.FilterLfo=new LFO(pars->FilterLfo,basefreq); + NoteGlobalPar.FilterQ=pars->GlobalFilter->getq(); + NoteGlobalPar.FilterFreqTracking=pars->GlobalFilter->getfreqtracking(basefreq); + + ready=1;///sa il pun pe asta doar cand e chiar gata + + if (parameters->sample[nsample].smp==NULL){ + finished_=true; + return; + }; +}; + + +// PADlegatonote: This function is (mostly) a copy of PADnote(...) +// with some lines removed so that it only alter the already playing +// note (to perform legato). It is possible I left stuff that is not +// required for this. +void PADnote::PADlegatonote(REALTYPE freq, REALTYPE velocity, int portamento_, int midinote, bool externcall){ + PADnoteParameters *parameters=pars; + //Controller *ctl_=ctl; + + // Manage legato stuff + if (externcall) Legato.msg=LM_Norm; + if (Legato.msg!=LM_CatchUp){ + Legato.lastfreq=Legato.param.freq; + Legato.param.freq=freq; + Legato.param.vel=velocity; + Legato.param.portamento=portamento_; + Legato.param.midinote=midinote; + if (Legato.msg==LM_Norm){ + if (Legato.silent){ + Legato.fade.m=0.0; + Legato.msg=LM_FadeIn; + } else { + Legato.fade.m=1.0; + Legato.msg=LM_FadeOut; + return; + } + } + if (Legato.msg==LM_ToNorm) Legato.msg=LM_Norm; + } + + portamento=portamento_; + this->velocity=velocity; + finished_=false; + + if (pars->Pfixedfreq==0) basefreq=freq; + else { + basefreq=440.0; + int fixedfreqET=pars->PfixedfreqET; + if (fixedfreqET!=0) {//if the frequency varies according the keyboard note + REALTYPE tmp=(midinote-69.0)/12.0*(pow(2.0,(fixedfreqET-1)/63.0)-1.0); + if (fixedfreqET<=64) basefreq*=pow(2.0,tmp); + else basefreq*=pow(3.0,tmp); + }; + }; + + released=false; + realfreq=basefreq; + + getdetune(pars->PDetuneType,pars->PCoarseDetune,pars->PDetune); + + + //find out the closest note + REALTYPE logfreq=log(basefreq*pow(2.0,NoteGlobalPar.Detune/1200.0)); + REALTYPE mindist=fabs(logfreq-log(pars->sample[0].basefreq+0.0001)); + nsample=0; + for (int i=1;isample[i].smp==NULL) break; + REALTYPE dist=fabs(logfreq-log(pars->sample[i].basefreq+0.0001)); + + if (distsample[nsample].size; + if (size==0) size=1; + + if (pars->PPanning==0) NoteGlobalPar.Panning=RND; + else NoteGlobalPar.Panning=pars->PPanning/128.0; + + NoteGlobalPar.FilterCenterPitch=pars->GlobalFilter->getfreq()+//center freq + pars->PFilterVelocityScale/127.0*6.0* //velocity sensing + (VelF(velocity,pars->PFilterVelocityScaleFunction)-1); + + + NoteGlobalPar.Volume=4.0*pow(0.1,3.0*(1.0-pars->PVolume/96.0))//-60 dB .. 0 dB + *VelF(velocity,pars->PAmpVelocityScaleFunction);//velocity sensing + + NoteGlobalPar.AmpEnvelope->envout_dB();//discard the first envelope output + globaloldamplitude=globalnewamplitude=NoteGlobalPar.Volume*NoteGlobalPar.AmpEnvelope->envout_dB()*NoteGlobalPar.AmpLfo->amplfoout(); + + NoteGlobalPar.FilterQ=pars->GlobalFilter->getq(); + NoteGlobalPar.FilterFreqTracking=pars->GlobalFilter->getfreqtracking(basefreq); + + + if (parameters->sample[nsample].smp==NULL){ + finished_=true; + return; + }; + + // End of the PADlegatonote function. +}; + + +PADnote::~PADnote(){ + delete (NoteGlobalPar.FreqEnvelope); + delete (NoteGlobalPar.FreqLfo); + delete (NoteGlobalPar.AmpEnvelope); + delete (NoteGlobalPar.AmpLfo); + delete (NoteGlobalPar.GlobalFilterL); + delete (NoteGlobalPar.GlobalFilterR); + delete (NoteGlobalPar.FilterEnvelope); + delete (NoteGlobalPar.FilterLfo); + delete [] tmpwave; +}; + + +inline void PADnote::fadein(REALTYPE *smps){ + int zerocrossings=0; + for (int i=1;i0.0)) zerocrossings++;//this is only the possitive crossings + + REALTYPE tmp=(SOUND_BUFFER_SIZE-1.0)/(zerocrossings+1)/3.0; + if (tmp<8.0) tmp=8.0; + + int n; + F2I(tmp,n);//how many samples is the fade-in + if (n>SOUND_BUFFER_SIZE) n=SOUND_BUFFER_SIZE; + for (int i=0;ienvout()+ + NoteGlobalPar.FreqLfo->lfoout()*ctl->modwheel.relmod+NoteGlobalPar.Detune); + globaloldamplitude=globalnewamplitude; + globalnewamplitude=NoteGlobalPar.Volume*NoteGlobalPar.AmpEnvelope->envout_dB()*NoteGlobalPar.AmpLfo->amplfoout(); + + globalfilterpitch=NoteGlobalPar.FilterEnvelope->envout()+NoteGlobalPar.FilterLfo->lfoout() + +NoteGlobalPar.FilterCenterPitch; + + REALTYPE tmpfilterfreq=globalfilterpitch+ctl->filtercutoff.relfreq + +NoteGlobalPar.FilterFreqTracking; + + tmpfilterfreq=NoteGlobalPar.GlobalFilterL->getrealfreq(tmpfilterfreq); + + REALTYPE globalfilterq=NoteGlobalPar.FilterQ*ctl->filterq.relq; + NoteGlobalPar.GlobalFilterL->setfreq_and_q(tmpfilterfreq,globalfilterq); + NoteGlobalPar.GlobalFilterR->setfreq_and_q(tmpfilterfreq,globalfilterq); + + //compute the portamento, if it is used by this note + REALTYPE portamentofreqrap=1.0; + if (portamento!=0){//this voice use portamento + portamentofreqrap=ctl->portamento.freqrap; + if (ctl->portamento.used==0){//the portamento has finished + portamento=0;//this note is no longer "portamented" + }; + }; + + realfreq=basefreq*portamentofreqrap*pow(2.0,globalpitch/12.0)*ctl->pitchwheel.relfreq; +}; + + +int PADnote::Compute_Linear(REALTYPE *outl,REALTYPE *outr,int freqhi,REALTYPE freqlo){ + REALTYPE *smps=pars->sample[nsample].smp; + if (smps==NULL){ + finished_=true; + return(1); + }; + int size=pars->sample[nsample].size; + for (int i=0;i=1.0){ + poshi_l+=1; + poshi_r+=1; + poslo-=1.0; + }; + if (poshi_l>=size) poshi_l%=size; + if (poshi_r>=size) poshi_r%=size; + + outl[i]=smps[poshi_l]*(1.0-poslo)+smps[poshi_l+1]*poslo; + outr[i]=smps[poshi_r]*(1.0-poslo)+smps[poshi_r+1]*poslo; + }; + return(1); +}; +int PADnote::Compute_Cubic(REALTYPE *outl,REALTYPE *outr,int freqhi,REALTYPE freqlo){ + REALTYPE *smps=pars->sample[nsample].smp; + if (smps==NULL){ + finished_=true; + return(1); + }; + int size=pars->sample[nsample].size; + REALTYPE xm1,x0,x1,x2,a,b,c; + for (int i=0;i=1.0){ + poshi_l+=1; + poshi_r+=1; + poslo-=1.0; + }; + if (poshi_l>=size) poshi_l%=size; + if (poshi_r>=size) poshi_r%=size; + + + //left + xm1=smps[poshi_l]; + x0=smps[poshi_l + 1]; + x1=smps[poshi_l + 2]; + x2=smps[poshi_l + 3]; + a = (3.0 * (x0-x1) - xm1 + x2)*0.5; + b = 2.0*x1 + xm1 - (5.0*x0 + x2)*0.5; + c = (x1 - xm1)*0.5; + outl[i] = (((a * poslo) + b) * poslo + c) * poslo + x0; + //right + xm1=smps[poshi_r]; + x0=smps[poshi_r + 1]; + x1=smps[poshi_r + 2]; + x2=smps[poshi_r + 3]; + a = (3.0 * (x0-x1) - xm1 + x2)*0.5; + b = 2.0*x1 + xm1 - (5.0*x0 + x2)*0.5; + c = (x1 - xm1)*0.5; + outr[i] = (((a * poslo) + b) * poslo + c) * poslo + x0; + }; + return(1); +}; + + +int PADnote::noteout(REALTYPE *outl,REALTYPE *outr){ + computecurrentparameters(); + REALTYPE *smps=pars->sample[nsample].smp; + if (smps==NULL){ + for (int i=0;isample[nsample].basefreq; + + + REALTYPE freqrap=realfreq/smpfreq; + int freqhi=(int) (floor(freqrap)); + REALTYPE freqlo=freqrap-floor(freqrap); + + + if (config.cfg.Interpolation) Compute_Cubic(outl,outr,freqhi,freqlo); + else Compute_Linear(outl,outr,freqhi,freqlo); + + + if (firsttime){ + fadein(outl); + fadein(outr); + firsttime=false; + }; + + NoteGlobalPar.GlobalFilterL->filterout(outl); + NoteGlobalPar.GlobalFilterR->filterout(outr); + + //Apply the punch + if (NoteGlobalPar.Punch.Enabled!=0){ + for (int i=0;ifinished()!=0) { + for (int i=0;irelasekey(); + NoteGlobalPar.FilterEnvelope->relasekey(); + NoteGlobalPar.AmpEnvelope->relasekey(); +}; + diff --git a/plugins/zynaddsubfx/src/Synth/PADnote.h b/plugins/zynaddsubfx/src/Synth/PADnote.h new file mode 100644 index 000000000..8d18c75a1 --- /dev/null +++ b/plugins/zynaddsubfx/src/Synth/PADnote.h @@ -0,0 +1,124 @@ +/* + ZynAddSubFX - a software synthesizer + + PADnote.h - The "pad" synthesizer + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#ifndef PAD_NOTE_H +#define PAD_NOTE_H + +#include "../globals.h" +#include "../Params/PADnoteParameters.h" +#include "../Params/Controller.h" +#include "Envelope.h" +#include "LFO.h" +#include "../DSP/Filter.h" +#include "../Params/Controller.h" + +class PADnote{ + public: + PADnote(PADnoteParameters *parameters, Controller *ctl_,REALTYPE freq, REALTYPE velocity, int portamento_, int midinote, bool besilent); + ~PADnote(); + + void PADlegatonote(REALTYPE freq, REALTYPE velocity, int portamento_, int midinote, bool externcall); + + int noteout(REALTYPE *outl,REALTYPE *outr); + int finished(); + void relasekey(); + + int ready; + + private: + void fadein(REALTYPE *smps); + void computecurrentparameters(); + bool finished_; + PADnoteParameters *pars; + + int poshi_l,poshi_r; + REALTYPE poslo; + + REALTYPE basefreq; + bool firsttime,released; + + int nsample,portamento; + + int Compute_Linear(REALTYPE *outl,REALTYPE *outr,int freqhi,REALTYPE freqlo); + int Compute_Cubic(REALTYPE *outl,REALTYPE *outr,int freqhi,REALTYPE freqlo); + + + struct{ + /****************************************** + * FREQUENCY GLOBAL PARAMETERS * + ******************************************/ + REALTYPE Detune;//cents + + Envelope *FreqEnvelope; + LFO *FreqLfo; + + /******************************************** + * AMPLITUDE GLOBAL PARAMETERS * + ********************************************/ + REALTYPE Volume;// [ 0 .. 1 ] + + REALTYPE Panning;// [ 0 .. 1 ] + + Envelope *AmpEnvelope; + LFO *AmpLfo; + + struct { + int Enabled; + REALTYPE initialvalue,dt,t; + } Punch; + + /****************************************** + * FILTER GLOBAL PARAMETERS * + ******************************************/ + Filter *GlobalFilterL,*GlobalFilterR; + + REALTYPE FilterCenterPitch;//octaves + REALTYPE FilterQ; + REALTYPE FilterFreqTracking; + + Envelope *FilterEnvelope; + + LFO *FilterLfo; + } NoteGlobalPar; + + + REALTYPE globaloldamplitude,globalnewamplitude,velocity,realfreq; + REALTYPE *tmpwave; + Controller *ctl; + + // Legato vars + struct { + bool silent; + REALTYPE lastfreq; + LegatoMsg msg; + int decounter; + struct { // Fade In/Out vars + int length; + REALTYPE m, step; + } fade; + struct { // Note parameters + REALTYPE freq, vel; + int portamento, midinote; + } param; + } Legato; +}; + + +#endif diff --git a/plugins/zynaddsubfx/src/Synth/Resonance.C b/plugins/zynaddsubfx/src/Synth/Resonance.C new file mode 100644 index 000000000..ce5d3dd8b --- /dev/null +++ b/plugins/zynaddsubfx/src/Synth/Resonance.C @@ -0,0 +1,231 @@ +/* + ZynAddSubFX - a software synthesizer + + Resonance.C - Resonance + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include "Resonance.h" + + +#include + +Resonance::Resonance():Presets(){ + setpresettype("Presonance"); + defaults(); +}; + +Resonance::~Resonance(){ +}; + + +void Resonance::defaults(){ + Penabled=0; + PmaxdB=20; + Pcenterfreq=64;//1 kHz + Poctavesfreq=64; + Pprotectthefundamental=0; + ctlcenter=1.0; + ctlbw=1.0; + for (int i=0;i=N_RES_POINTS)) return; + Prespoints[n]=p; +}; + +/* + * Apply the resonance to FFT data + */ +void Resonance::applyres(int n,FFTFREQS fftdata,REALTYPE freq){ + if (Penabled==0) return;//if the resonance is disabled + REALTYPE sum=0.0, + l1=log(getfreqx(0.0)*ctlcenter), + l2=log(2.0)*getoctavesfreq()*ctlbw; + + for (int i=0;i=N_RES_POINTS) kx1=N_RES_POINTS-1; + int kx2=kx1+1;if (kx2>=N_RES_POINTS) kx2=N_RES_POINTS-1; + REALTYPE y=(Prespoints[kx1]*(1.0-dx)+Prespoints[kx2]*dx)/127.0-sum/127.0; + + y=pow(10.0,y*PmaxdB/20.0); + + if ((Pprotectthefundamental!=0)&&(i==1)) y=1.0; + + fftdata.c[i]*=y; + fftdata.s[i]*=y; + }; +}; + +/* + * Gets the response at the frequency "freq" + */ + +REALTYPE Resonance::getfreqresponse(REALTYPE freq){ + REALTYPE l1=log(getfreqx(0.0)*ctlcenter), + l2=log(2.0)*getoctavesfreq()*ctlbw,sum=0.0; + + for (int i=0;i=N_RES_POINTS) kx1=N_RES_POINTS-1; + int kx2=kx1+1;if (kx2>=N_RES_POINTS) kx2=N_RES_POINTS-1; + REALTYPE result=(Prespoints[kx1]*(1.0-dx)+Prespoints[kx2]*dx)/127.0-sum/127.0; + result=pow(10.0,result*PmaxdB/20.0); + return(result); +}; + + +/* + * Smooth the resonance function + */ +void Resonance::smooth(){ + REALTYPE old=Prespoints[0]; + for (int i=0;i0;i--){ + old=old*0.4+Prespoints[i]*0.6; + Prespoints[i]=(int) old+1; + if (Prespoints[i]>127) Prespoints[i]=127; + }; +}; + +/* + * Randomize the resonance function + */ +void Resonance::randomize(int type){ + int r=(int)(RND*127.0); + for (int i=0;i1.0) x=1.0; + REALTYPE octf=pow(2.0,getoctavesfreq()); + return(getcenterfreq()/sqrt(octf)*pow(octf,x)); +}; + +/* + * Get the x coordinate from frequency (used by the UI) + */ +REALTYPE Resonance::getfreqpos(REALTYPE freq){ + return((log(freq)-log(getfreqx(0.0)))/log(2.0)/getoctavesfreq()); +}; + +/* + * Get the center frequency of the resonance graph + */ +REALTYPE Resonance::getcenterfreq(){ + return(10000.0*pow(10,-(1.0-Pcenterfreq/127.0)*2.0)); +}; + +/* + * Get the number of octave that the resonance functions applies to + */ +REALTYPE Resonance::getoctavesfreq(){ + return(0.25+10.0*Poctavesfreq/127.0); +}; + +void Resonance::sendcontroller(MidiControllers ctl,REALTYPE par){ + if (ctl==C_resonance_center) ctlcenter=par; + else ctlbw=par; +}; + + + + +void Resonance::add2XML(XMLwrapper *xml){ + xml->addparbool("enabled",Penabled); + + if ((Penabled==0)&&(xml->minimal)) return; + + xml->addpar("max_db",PmaxdB); + xml->addpar("center_freq",Pcenterfreq); + xml->addpar("octaves_freq",Poctavesfreq); + xml->addparbool("protect_fundamental_frequency",Pprotectthefundamental); + xml->addpar("resonance_points",N_RES_POINTS); + for (int i=0;ibeginbranch("RESPOINT",i); + xml->addpar("val",Prespoints[i]); + xml->endbranch(); + }; +}; + + +void Resonance::getfromXML(XMLwrapper *xml){ + Penabled=xml->getparbool("enabled",Penabled); + + PmaxdB=xml->getpar127("max_db",PmaxdB); + Pcenterfreq=xml->getpar127("center_freq",Pcenterfreq); + Poctavesfreq=xml->getpar127("octaves_freq",Poctavesfreq); + Pprotectthefundamental=xml->getparbool("protect_fundamental_frequency",Pprotectthefundamental); + for (int i=0;ienterbranch("RESPOINT",i)==0) continue; + Prespoints[i]=xml->getpar127("val",Prespoints[i]); + xml->exitbranch(); + }; +}; + + diff --git a/plugins/zynaddsubfx/src/Synth/Resonance.h b/plugins/zynaddsubfx/src/Synth/Resonance.h new file mode 100644 index 000000000..31d2fd4e1 --- /dev/null +++ b/plugins/zynaddsubfx/src/Synth/Resonance.h @@ -0,0 +1,68 @@ +/* + ZynAddSubFX - a software synthesizer + + Resonance.h - Resonance + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ +#ifndef RESONANCE_H +#define RESONANCE_H + +#include "../globals.h" +#include "../Misc/Util.h" +#include "../Misc/XMLwrapper.h" +#include "../Params/Presets.h" + +#define N_RES_POINTS 256 + +class Resonance:public Presets{ + public: + Resonance(); + ~Resonance(); + void setpoint(int n,unsigned char p); + void applyres(int n,FFTFREQS fftdata,REALTYPE freq); + void smooth(); + void interpolatepeaks(int type); + void randomize(int type); + + void add2XML(XMLwrapper *xml); + void defaults(); + void getfromXML(XMLwrapper *xml); + + + REALTYPE getfreqpos(REALTYPE freq); + REALTYPE getfreqx(REALTYPE x); + REALTYPE getfreqresponse(REALTYPE freq); + REALTYPE getcenterfreq(); + REALTYPE getoctavesfreq(); + void sendcontroller(MidiControllers ctl,REALTYPE par); + + //parameters + unsigned char Penabled; //if the ressonance is enabled + unsigned char Prespoints[N_RES_POINTS]; //how many points define the resonance function + unsigned char PmaxdB; //how many dB the signal may be amplified + unsigned char Pcenterfreq,Poctavesfreq; //the center frequency of the res. func., and the number of octaves + unsigned char Pprotectthefundamental; //the fundamental (1-st harmonic) is not damped, even it resonance function is low + + //controllers + REALTYPE ctlcenter;//center frequency(relative) + REALTYPE ctlbw;//bandwidth(relative) + + private: +}; + +#endif diff --git a/plugins/zynaddsubfx/src/Synth/SUBnote.C b/plugins/zynaddsubfx/src/Synth/SUBnote.C new file mode 100644 index 000000000..4b0ca1ecb --- /dev/null +++ b/plugins/zynaddsubfx/src/Synth/SUBnote.C @@ -0,0 +1,641 @@ +/* + ZynAddSubFX - a software synthesizer + + SUBnote.C - The "subtractive" synthesizer + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include +#include +#include +#include "../globals.h" +#include "SUBnote.h" +#include "../Misc/Util.h" + +SUBnote::SUBnote(SUBnoteParameters *parameters,Controller *ctl_,REALTYPE freq,REALTYPE velocity,int portamento_,int midinote,bool besilent){ + ready=0; + + tmpsmp=new REALTYPE[SOUND_BUFFER_SIZE]; + tmprnd=new REALTYPE[SOUND_BUFFER_SIZE]; + + // Initialise some legato-specific vars + Legato.msg=LM_Norm; + Legato.fade.length=(int)(SAMPLE_RATE*0.005);// 0.005 seems ok. + if (Legato.fade.length<1) Legato.fade.length=1;// (if something's fishy) + Legato.fade.step=(1.0/Legato.fade.length); + Legato.decounter=-10; + Legato.param.freq=freq; + Legato.param.vel=velocity; + Legato.param.portamento=portamento_; + Legato.param.midinote=midinote; + Legato.silent=besilent; + + pars=parameters; + ctl=ctl_; + portamento=portamento_; + NoteEnabled=ON; + volume=pow(0.1,3.0*(1.0-pars->PVolume/96.0));//-60 dB .. 0 dB + volume*=VelF(velocity,pars->PAmpVelocityScaleFunction); + if (pars->PPanning!=0) panning=pars->PPanning/127.0; + else panning=RND; + numstages=pars->Pnumstages; + stereo=pars->Pstereo; + start=pars->Pstart; + firsttick=1; + int pos[MAX_SUB_HARMONICS]; + + if (pars->Pfixedfreq==0) basefreq=freq; + else { + basefreq=440.0; + int fixedfreqET=pars->PfixedfreqET; + if (fixedfreqET!=0) {//if the frequency varies according the keyboard note + REALTYPE tmp=(midinote-69.0)/12.0*(pow(2.0,(fixedfreqET-1)/63.0)-1.0); + if (fixedfreqET<=64) basefreq*=pow(2.0,tmp); + else basefreq*=pow(3.0,tmp); + }; + + }; + REALTYPE detune=getdetune(pars->PDetuneType,pars->PCoarseDetune,pars->PDetune); + basefreq*=pow(2.0,detune/1200.0);//detune +// basefreq*=ctl->pitchwheel.relfreq;//pitch wheel + + //global filter + GlobalFilterCenterPitch=pars->GlobalFilter->getfreq()+//center freq + (pars->PGlobalFilterVelocityScale/127.0*6.0)* //velocity sensing + (VelF(velocity,pars->PGlobalFilterVelocityScaleFunction)-1); + + GlobalFilterL=NULL;GlobalFilterR=NULL; + GlobalFilterEnvelope=NULL; + + //select only harmonics that desire to compute + numharmonics=0; + for (int n=0;nPhmag[n]==0)continue; + if (n*basefreq>SAMPLE_RATE/2.0) break;//remove the freqs above the Nyquist freq + pos[numharmonics++]=n; + }; + firstnumharmonics=numharmonics;//(gf)Useful in legato mode. + + if (numharmonics==0) { + NoteEnabled=OFF; + return; + }; + + + lfilter=new bpfilter[numstages*numharmonics]; + if (stereo!=0) rfilter=new bpfilter[numstages*numharmonics]; + + //how much the amplitude is normalised (because the harmonics) + REALTYPE reduceamp=0.0; + + for (int n=0;nPbandwidth-127.0)/127.0*4)*numstages; + + //Bandwidth Scale + bw*=pow(1000/freq,(pars->Pbwscale-64.0)/64.0*3.0); + + //Relative BandWidth + bw*=pow(100,(pars->Phrelbw[pos[n]]-64.0)/64.0); + + if (bw>25.0) bw=25.0; + + //try to keep same amplitude on all freqs and bw. (empirically) + REALTYPE gain=sqrt(1500.0/(bw*freq)); + + REALTYPE hmagnew=1.0-pars->Phmag[pos[n]]/127.0; + REALTYPE hgain; + + switch(pars->Phmagtype){ + case 1:hgain=exp(hmagnew*log(0.01)); break; + case 2:hgain=exp(hmagnew*log(0.001));break; + case 3:hgain=exp(hmagnew*log(0.0001));break; + case 4:hgain=exp(hmagnew*log(0.00001));break; + default:hgain=1.0-hmagnew; + }; + gain*=hgain; + reduceamp+=hgain; + + for (int nph=0;nphPfixedfreq==0) initparameters(basefreq); + else initparameters(basefreq/440.0*freq); + + oldamplitude=newamplitude; + ready=1; +}; + + +// SUBlegatonote: This function is (mostly) a copy of SUBnote(...) and +// initparameters(...) stuck together with some lines removed so that +// it only alter the already playing note (to perform legato). It is +// possible I left stuff that is not required for this. +void SUBnote::SUBlegatonote(REALTYPE freq, REALTYPE velocity, int portamento_, int midinote, bool externcall){ + //SUBnoteParameters *parameters=pars; + //Controller *ctl_=ctl; + + // Manage legato stuff + if (externcall) Legato.msg=LM_Norm; + if (Legato.msg!=LM_CatchUp){ + Legato.lastfreq=Legato.param.freq; + Legato.param.freq=freq; + Legato.param.vel=velocity; + Legato.param.portamento=portamento_; + Legato.param.midinote=midinote; + if (Legato.msg==LM_Norm){ + if (Legato.silent){ + Legato.fade.m=0.0; + Legato.msg=LM_FadeIn; + } else { + Legato.fade.m=1.0; + Legato.msg=LM_FadeOut; + return; + } + } + if (Legato.msg==LM_ToNorm) Legato.msg=LM_Norm; + } + + portamento=portamento_; + + volume=pow(0.1,3.0*(1.0-pars->PVolume/96.0));//-60 dB .. 0 dB + volume*=VelF(velocity,pars->PAmpVelocityScaleFunction); + if (pars->PPanning!=0) panning=pars->PPanning/127.0; + else panning=RND; + + ///start=pars->Pstart; + + int pos[MAX_SUB_HARMONICS]; + + if (pars->Pfixedfreq==0) basefreq=freq; + else { + basefreq=440.0; + int fixedfreqET=pars->PfixedfreqET; + if (fixedfreqET!=0) {//if the frequency varies according the keyboard note + REALTYPE tmp=(midinote-69.0)/12.0*(pow(2.0,(fixedfreqET-1)/63.0)-1.0); + if (fixedfreqET<=64) basefreq*=pow(2.0,tmp); + else basefreq*=pow(3.0,tmp); + }; + }; + REALTYPE detune=getdetune(pars->PDetuneType,pars->PCoarseDetune,pars->PDetune); + basefreq*=pow(2.0,detune/1200.0);//detune + + //global filter + GlobalFilterCenterPitch=pars->GlobalFilter->getfreq()+//center freq + (pars->PGlobalFilterVelocityScale/127.0*6.0)* //velocity sensing + (VelF(velocity,pars->PGlobalFilterVelocityScaleFunction)-1); + + + int legatonumharmonics=0; + for (int n=0;nPhmag[n]==0)continue; + if (n*basefreq>SAMPLE_RATE/2.0) break;//remove the freqs above the Nyquist freq + pos[legatonumharmonics++]=n; + }; + if (legatonumharmonics>firstnumharmonics) numharmonics=firstnumharmonics; + else numharmonics=legatonumharmonics; + + if (numharmonics==0) { + NoteEnabled=OFF; + return; + }; + + + //how much the amplitude is normalised (because the harmonics) + REALTYPE reduceamp=0.0; + + for (int n=0;nPbandwidth-127.0)/127.0*4)*numstages; + + //Bandwidth Scale + bw*=pow(1000/freq,(pars->Pbwscale-64.0)/64.0*3.0); + + //Relative BandWidth + bw*=pow(100,(pars->Phrelbw[pos[n]]-64.0)/64.0); + + if (bw>25.0) bw=25.0; + + //try to keep same amplitude on all freqs and bw. (empirically) + REALTYPE gain=sqrt(1500.0/(bw*freq)); + + REALTYPE hmagnew=1.0-pars->Phmag[pos[n]]/127.0; + REALTYPE hgain; + + switch(pars->Phmagtype){ + case 1:hgain=exp(hmagnew*log(0.01)); break; + case 2:hgain=exp(hmagnew*log(0.001));break; + case 3:hgain=exp(hmagnew*log(0.0001));break; + case 4:hgain=exp(hmagnew*log(0.00001));break; + default:hgain=1.0-hmagnew; + }; + gain*=hgain; + reduceamp+=hgain; + + for (int nph=0;nphPfixedfreq==0) freq=basefreq; + else freq*=basefreq/440.0; + + + /////////////// + // Altered initparameters(...) content: + + if (pars->PGlobalFilterEnabled!=0){ + globalfiltercenterq=pars->GlobalFilter->getq(); + GlobalFilterFreqTracking=pars->GlobalFilter->getfreqtracking(basefreq); + }; + + // end of the altered initparameters function content. + /////////////// + + oldamplitude=newamplitude; + + // End of the SUBlegatonote function. +}; + + +SUBnote::~SUBnote(){ + if (NoteEnabled!=OFF) KillNote(); + delete [] tmpsmp; + delete [] tmprnd; +}; + +/* + * Kill the note + */ +void SUBnote::KillNote(){ + if (NoteEnabled!=OFF){ + delete [] lfilter; + lfilter=NULL; + if (stereo!=0) delete [] rfilter; + rfilter=NULL; + delete(AmpEnvelope); + if (FreqEnvelope!=NULL) delete(FreqEnvelope); + if (BandWidthEnvelope!=NULL) delete(BandWidthEnvelope); + NoteEnabled=OFF; + }; + +}; + + +/* + * Compute the filters coefficients + */ +void SUBnote::computefiltercoefs(bpfilter &filter,REALTYPE freq,REALTYPE bw,REALTYPE gain){ + if (freq>SAMPLE_RATE/2.0-200.0) { + freq=SAMPLE_RATE/2.0-200.0; + }; + + REALTYPE omega=2.0*PI*freq/SAMPLE_RATE; + REALTYPE sn=sin(omega);REALTYPE cs=cos(omega); + REALTYPE alpha=sn*sinh(LOG_2/2.0*bw*omega/sn); + + if (alpha>1) alpha=1; + if (alpha>bw) alpha=bw; + + filter.b0=alpha/(1.0+alpha)*filter.amp*gain; + filter.b2=-alpha/(1.0+alpha)*filter.amp*gain; + filter.a1=-2.0*cs/(1.0+alpha); + filter.a2=(1.0-alpha)/(1.0+alpha); + +}; + + +/* + * Initialise the filters + */ +void SUBnote::initfilter(bpfilter &filter,REALTYPE freq,REALTYPE bw,REALTYPE amp,REALTYPE mag){ + filter.xn1=0.0;filter.xn2=0.0; + + if (start==0) { + filter.yn1=0.0; + filter.yn2=0.0; + } else { + REALTYPE a=0.1*mag;//empirically + REALTYPE p=RND*2.0*PI; + if (start==1) a*=RND; + filter.yn1=a*cos(p); + filter.yn2=a*cos(p+freq*2.0*PI/SAMPLE_RATE); + + //correct the error of computation the start amplitude + //at very high frequencies + if (freq>SAMPLE_RATE*0.96) { + filter.yn1=0.0; + filter.yn2=0.0; + + }; + }; + + filter.amp=amp; + filter.freq=freq; + filter.bw=bw; + computefiltercoefs(filter,freq,bw,1.0); +}; + +/* + * Do the filtering + */ +void SUBnote::filter(bpfilter &filter,REALTYPE *smps){ + int i; + REALTYPE out; + for (i=0;iAmpEnvelope,freq); + if (pars->PFreqEnvelopeEnabled!=0) FreqEnvelope=new Envelope(pars->FreqEnvelope,freq); + else FreqEnvelope=NULL; + if (pars->PBandWidthEnvelopeEnabled!=0) BandWidthEnvelope=new Envelope(pars->BandWidthEnvelope,freq); + else BandWidthEnvelope=NULL; + if (pars->PGlobalFilterEnabled!=0){ + globalfiltercenterq=pars->GlobalFilter->getq(); + GlobalFilterL=new Filter(pars->GlobalFilter); + if (stereo!=0) GlobalFilterR=new Filter(pars->GlobalFilter); + GlobalFilterEnvelope=new Envelope(pars->GlobalFilterEnvelope,freq); + GlobalFilterFreqTracking=pars->GlobalFilter->getfreqtracking(basefreq); + }; + computecurrentparameters(); +}; + + +/* + * Compute Parameters of SUBnote for each tick + */ +void SUBnote::computecurrentparameters(){ + if ((FreqEnvelope!=NULL)||(BandWidthEnvelope!=NULL)|| + (oldpitchwheel!=ctl->pitchwheel.data)|| + (oldbandwidth!=ctl->bandwidth.data)|| + (portamento!=0)){ + REALTYPE envfreq=1.0; + REALTYPE envbw=1.0; + REALTYPE gain=1.0; + + if (FreqEnvelope!=NULL) { + envfreq=FreqEnvelope->envout()/1200; + envfreq=pow(2.0,envfreq); + }; + envfreq*=ctl->pitchwheel.relfreq;//pitch wheel + if (portamento!=0) {//portamento is used + envfreq*=ctl->portamento.freqrap; + if (ctl->portamento.used==0){//the portamento has finished + portamento=0;//this note is no longer "portamented" + }; + }; + + if (BandWidthEnvelope!=NULL) { + envbw=BandWidthEnvelope->envout(); + envbw=pow(2,envbw); + }; + envbw*=ctl->bandwidth.relbw;//bandwidth controller + + REALTYPE tmpgain=1.0/sqrt(envbw*envfreq); + + for (int n=0;nbandwidth.data; + oldpitchwheel=ctl->pitchwheel.data; + }; + newamplitude=volume*AmpEnvelope->envout_dB()*2.0; + + //Filter + if (GlobalFilterL!=NULL){ + REALTYPE globalfilterpitch=GlobalFilterCenterPitch+GlobalFilterEnvelope->envout(); + REALTYPE filterfreq=globalfilterpitch+ctl->filtercutoff.relfreq+GlobalFilterFreqTracking; + filterfreq=GlobalFilterL->getrealfreq(filterfreq); + + GlobalFilterL->setfreq_and_q(filterfreq,globalfiltercenterq*ctl->filterq.relq); + if (GlobalFilterR!=NULL) GlobalFilterR->setfreq_and_q(filterfreq,globalfiltercenterq*ctl->filterq.relq); + }; + +}; + +/* + * Note Output + */ +int SUBnote::noteout(REALTYPE *outl,REALTYPE *outr){ + int i; + + for (i=0;ifilterout(&outl[0]); + + //right channel + if (stereo!=0){ + for (i=0;ifilterout(&outr[0]); + } else for (i=0;iSOUND_BUFFER_SIZE) n=SOUND_BUFFER_SIZE; + for (i=0;ifinished()!=0){ + for (i=0;irelasekey(); + if (FreqEnvelope!=NULL) FreqEnvelope->relasekey(); + if (BandWidthEnvelope!=NULL) BandWidthEnvelope->relasekey(); + if (GlobalFilterEnvelope!=NULL) GlobalFilterEnvelope->relasekey(); +}; + +/* + * Check if the note is finished + */ +int SUBnote::finished(){ + if (NoteEnabled==OFF) return(1); + else return(0); +}; + diff --git a/plugins/zynaddsubfx/src/Synth/SUBnote.h b/plugins/zynaddsubfx/src/Synth/SUBnote.h new file mode 100644 index 000000000..892e1a476 --- /dev/null +++ b/plugins/zynaddsubfx/src/Synth/SUBnote.h @@ -0,0 +1,117 @@ +/* + ZynAddSubFX - a software synthesizer + + SUBnote.h - The subtractive synthesizer + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef SUB_NOTE_H +#define SUB_NOTE_H + +#include "../globals.h" +#include "../Params/SUBnoteParameters.h" +#include "../Params/Controller.h" +#include "Envelope.h" +#include "../DSP/Filter.h" + +class SUBnote{ + public: + SUBnote(SUBnoteParameters *parameters,Controller *ctl_,REALTYPE freq,REALTYPE velocity,int portamento_,int midinote,bool besilent); + ~SUBnote(); + + void SUBlegatonote(REALTYPE freq, REALTYPE velocity, int portamento_, int midinote, bool externcall); + + int noteout(REALTYPE *outl,REALTYPE *outr);//note output,return 0 if the note is finished + void relasekey(); + int finished(); + + int ready; //if I can get the sampledata + + private: + + void computecurrentparameters(); + void initparameters(REALTYPE freq); + void KillNote(); + + SUBnoteParameters *pars; + + //parameters + int stereo; + int numstages;//number of stages of filters + int numharmonics;//number of harmonics (after the too higher hamonics are removed) + int firstnumharmonics;//To keep track of the first note's numharmonics value, useful in legato mode. + int start;//how the harmonics start + REALTYPE basefreq; + REALTYPE panning; + Envelope *AmpEnvelope; + Envelope *FreqEnvelope; + Envelope *BandWidthEnvelope; + + Filter *GlobalFilterL,*GlobalFilterR; + + Envelope *GlobalFilterEnvelope; + + //internal values + ONOFFTYPE NoteEnabled; + int firsttick,portamento; + REALTYPE volume,oldamplitude,newamplitude; + + REALTYPE GlobalFilterCenterPitch;//octaves + REALTYPE GlobalFilterFreqTracking; + + struct bpfilter{ + REALTYPE freq,bw,amp; //filter parameters + REALTYPE a1,a2,b0,b2;//filter coefs. b1=0 + REALTYPE xn1,xn2,yn1,yn2; //filter internal values + }; + + void initfilter(bpfilter &filter,REALTYPE freq,REALTYPE bw,REALTYPE amp,REALTYPE mag); + void computefiltercoefs(bpfilter &filter,REALTYPE freq,REALTYPE bw,REALTYPE gain); + void filter(bpfilter &filter,REALTYPE *smps); + + bpfilter *lfilter,*rfilter; + + REALTYPE *tmpsmp; + REALTYPE *tmprnd;//this is filled with random numbers + + Controller *ctl; + int oldpitchwheel,oldbandwidth; + REALTYPE globalfiltercenterq; + + // Legato vars + struct { + bool silent; + REALTYPE lastfreq; + LegatoMsg msg; + int decounter; + struct { // Fade In/Out vars + int length; + REALTYPE m, step; + } fade; + struct { // Note parameters + REALTYPE freq, vel; + int portamento, midinote; + } param; + } Legato; +}; + + + + +#endif + diff --git a/plugins/zynaddsubfx/src/UI/ADnoteUI.cc b/plugins/zynaddsubfx/src/UI/ADnoteUI.cc new file mode 100644 index 000000000..478489068 --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/ADnoteUI.cc @@ -0,0 +1,2056 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0109 + +#include "ADnoteUI.h" +//Copyright (c) 2002-2005 Nasca Octavian Paul +//License: GNU GPL version 2 or later +#include +#include +#include +#include + +void ADvoicelistitem::cb_voicevolume_i(Fl_Value_Slider* o, void*) { + pars->VoicePar[nvoice].PVolume=(int)o->value(); +} +void ADvoicelistitem::cb_voicevolume(Fl_Value_Slider* o, void* v) { + ((ADvoicelistitem*)(o->parent()->parent()->user_data()))->cb_voicevolume_i(o,v); +} + +void ADvoicelistitem::cb_voiceresonanceenabled_i(Fl_Check_Button* o, void*) { + pars->VoicePar[nvoice].Presonance=(int)o->value(); +} +void ADvoicelistitem::cb_voiceresonanceenabled(Fl_Check_Button* o, void* v) { + ((ADvoicelistitem*)(o->parent()->parent()->user_data()))->cb_voiceresonanceenabled_i(o,v); +} + +void ADvoicelistitem::cb_voicelfofreq_i(Fl_Value_Slider* o, void*) { + pars->VoicePar[nvoice].FreqLfo->Pintensity=(int)o->value(); +} +void ADvoicelistitem::cb_voicelfofreq(Fl_Value_Slider* o, void* v) { + ((ADvoicelistitem*)(o->parent()->parent()->user_data()))->cb_voicelfofreq_i(o,v); +} + +void ADvoicelistitem::cb_voicepanning_i(WidgetPDial* o, void*) { + pars->VoicePar[nvoice].PPanning=(int) o->value(); +} +void ADvoicelistitem::cb_voicepanning(WidgetPDial* o, void* v) { + ((ADvoicelistitem*)(o->parent()->parent()->user_data()))->cb_voicepanning_i(o,v); +} + +void ADvoicelistitem::cb_detunevalueoutput_i(Fl_Value_Output* o, void*) { + o->value(getdetune((pars->VoicePar[nvoice].PDetuneType==0)?(pars->GlobalPar.PDetuneType) : (pars->VoicePar[nvoice].PDetuneType),0,pars->VoicePar[nvoice].PDetune)*pars->getBandwidthDetuneMultiplier()); +} +void ADvoicelistitem::cb_detunevalueoutput(Fl_Value_Output* o, void* v) { + ((ADvoicelistitem*)(o->parent()->parent()->user_data()))->cb_detunevalueoutput_i(o,v); +} + +void ADvoicelistitem::cb_voicedetune_i(Fl_Slider* o, void*) { + pars->VoicePar[nvoice].PDetune=(int)o->value()+8192; +detunevalueoutput->do_callback(); +} +void ADvoicelistitem::cb_voicedetune(Fl_Slider* o, void* v) { + ((ADvoicelistitem*)(o->parent()->parent()->user_data()))->cb_voicedetune_i(o,v); +} + +void ADvoicelistitem::cb_noiselabel_i(Fl_Box* o, void*) { + if (pars->VoicePar[nvoice].Type==0) { + o->hide(); + voiceresonanceenabled->activate(); + detunevalueoutput->activate(); + voicedetune->activate(); + voicelfofreq->activate(); + voiceoscil->activate(); +} else { + o->show(); + voiceresonanceenabled->deactivate(); + detunevalueoutput->deactivate(); + voicedetune->deactivate(); + voicelfofreq->deactivate(); + voiceoscil->deactivate(); +}; +} +void ADvoicelistitem::cb_noiselabel(Fl_Box* o, void* v) { + ((ADvoicelistitem*)(o->parent()->parent()->user_data()))->cb_noiselabel_i(o,v); +} + +void ADvoicelistitem::cb_voiceenabled_i(Fl_Check_Button* o, void*) { + pars->VoicePar[nvoice].Enabled=(int)o->value(); +if (o->value()==0) voicelistitemgroup->deactivate(); +else voicelistitemgroup->activate(); +o->redraw(); +} +void ADvoicelistitem::cb_voiceenabled(Fl_Check_Button* o, void* v) { + ((ADvoicelistitem*)(o->parent()->user_data()))->cb_voiceenabled_i(o,v); +} + +Fl_Group* ADvoicelistitem::make_window() { + { ADnoteVoiceListItem = new Fl_Group(0, 0, 615, 30); + ADnoteVoiceListItem->box(FL_FLAT_BOX); + ADnoteVoiceListItem->color(FL_BACKGROUND_COLOR); + ADnoteVoiceListItem->selection_color(FL_BACKGROUND_COLOR); + ADnoteVoiceListItem->labeltype(FL_NO_LABEL); + ADnoteVoiceListItem->labelfont(0); + ADnoteVoiceListItem->labelsize(14); + ADnoteVoiceListItem->labelcolor(FL_FOREGROUND_COLOR); + ADnoteVoiceListItem->user_data((void*)(this)); + ADnoteVoiceListItem->align(FL_ALIGN_TOP); + ADnoteVoiceListItem->when(FL_WHEN_RELEASE); + { Fl_Group* o = voicelistitemgroup = new Fl_Group(50, 0, 570, 25); + voicelistitemgroup->box(FL_FLAT_BOX); + { Fl_Value_Slider* o = voicevolume = new Fl_Value_Slider(90, 5, 115, 20); + voicevolume->tooltip("Volume"); + voicevolume->type(5); + voicevolume->box(FL_FLAT_BOX); + voicevolume->labelsize(8); + voicevolume->maximum(127); + voicevolume->step(1); + voicevolume->callback((Fl_Callback*)cb_voicevolume); + voicevolume->align(FL_ALIGN_TOP_LEFT); + o->value(pars->VoicePar[nvoice].PVolume); + } // Fl_Value_Slider* voicevolume + { Fl_Check_Button* o = voiceresonanceenabled = new Fl_Check_Button(245, 7, 15, 17); + voiceresonanceenabled->tooltip("Resonance On/Off"); + voiceresonanceenabled->down_box(FL_DOWN_BOX); + voiceresonanceenabled->labeltype(FL_EMBOSSED_LABEL); + voiceresonanceenabled->labelfont(1); + voiceresonanceenabled->labelsize(11); + voiceresonanceenabled->callback((Fl_Callback*)cb_voiceresonanceenabled); + voiceresonanceenabled->align(FL_ALIGN_LEFT); + o->value(pars->VoicePar[nvoice].Presonance); + } // Fl_Check_Button* voiceresonanceenabled + { Fl_Value_Slider* o = voicelfofreq = new Fl_Value_Slider(500, 5, 115, 20); + voicelfofreq->tooltip("Frequency LFO amount"); + voicelfofreq->type(5); + voicelfofreq->box(FL_FLAT_BOX); + voicelfofreq->labelsize(8); + voicelfofreq->maximum(127); + voicelfofreq->step(1); + voicelfofreq->callback((Fl_Callback*)cb_voicelfofreq); + voicelfofreq->align(FL_ALIGN_TOP_LEFT); + o->value(pars->VoicePar[nvoice].FreqLfo->Pintensity); + } // Fl_Value_Slider* voicelfofreq + { WidgetPDial* o = voicepanning = new WidgetPDial(215, 5, 20, 20); + voicepanning->tooltip("Panning (leftmost is Random)"); + voicepanning->box(FL_ROUND_UP_BOX); + voicepanning->color(FL_BACKGROUND_COLOR); + voicepanning->selection_color(FL_INACTIVE_COLOR); + voicepanning->labeltype(FL_NORMAL_LABEL); + voicepanning->labelfont(0); + voicepanning->labelsize(10); + voicepanning->labelcolor(FL_FOREGROUND_COLOR); + voicepanning->maximum(127); + voicepanning->step(1); + voicepanning->callback((Fl_Callback*)cb_voicepanning); + voicepanning->align(FL_ALIGN_LEFT); + voicepanning->when(FL_WHEN_CHANGED); + o->value(pars->VoicePar[nvoice].PPanning); + } // WidgetPDial* voicepanning + { Fl_Group* o = voiceoscil = new Fl_Group(60, 5, 30, 20); + voiceoscil->box(FL_THIN_DOWN_BOX); + voiceoscil->color(FL_GRAY0); + voiceoscil->selection_color((Fl_Color)71); + voiceoscil->labelcolor((Fl_Color)179); + osc=new Oscilloscope(o->x(),o->y(),o->w(),o->h(),""); + osc->init(pars->VoicePar[nvoice].OscilSmp,0,pars->VoicePar[nvoice].Poscilphase,master); + if (pars->VoicePar[nvoice].Pextoscil != -1) {osc->init(pars->VoicePar[pars->VoicePar[nvoice].Pextoscil].OscilSmp,master);} + voiceoscil->end(); + } // Fl_Group* voiceoscil + { Fl_Value_Output* o = detunevalueoutput = new Fl_Value_Output(265, 5, 45, 20); + detunevalueoutput->labelsize(10); + detunevalueoutput->minimum(-5000); + detunevalueoutput->maximum(5000); + detunevalueoutput->step(0.01); + detunevalueoutput->textfont(1); + detunevalueoutput->textsize(10); + detunevalueoutput->callback((Fl_Callback*)cb_detunevalueoutput); + detunevalueoutput->align(FL_ALIGN_TOP_LEFT); + o->value(getdetune(pars->VoicePar[nvoice].PDetuneType,0,pars->VoicePar[nvoice].PDetune)*pars->getBandwidthDetuneMultiplier()); + } // Fl_Value_Output* detunevalueoutput + { Fl_Slider* o = voicedetune = new Fl_Slider(315, 5, 185, 20); + voicedetune->tooltip("Fine Detune (cents)"); + voicedetune->type(5); + voicedetune->box(FL_FLAT_BOX); + voicedetune->minimum(-8192); + voicedetune->maximum(8191); + voicedetune->step(1); + voicedetune->callback((Fl_Callback*)cb_voicedetune); + o->value(pars->VoicePar[nvoice].PDetune-8192); + } // Fl_Slider* voicedetune + { Fl_Box* o = noiselabel = new Fl_Box(65, 5, 20, 20, "N"); + noiselabel->labelfont(1); + noiselabel->labelsize(13); + noiselabel->labelcolor(FL_BACKGROUND2_COLOR); + noiselabel->callback((Fl_Callback*)cb_noiselabel); + if (pars->VoicePar[nvoice].Type==0) o->hide(); + } // Fl_Box* noiselabel + if (pars->VoicePar[nvoice].Enabled==0) o->deactivate(); + voicelistitemgroup->end(); + } // Fl_Group* voicelistitemgroup + { Fl_Check_Button* o = voiceenabled = new Fl_Check_Button(30, 5, 20, 20, "01"); + voiceenabled->down_box(FL_DOWN_BOX); + voiceenabled->labeltype(FL_EMBOSSED_LABEL); + voiceenabled->labelfont(1); + voiceenabled->labelsize(13); + voiceenabled->callback((Fl_Callback*)cb_voiceenabled); + voiceenabled->align(FL_ALIGN_LEFT); + char tmp[10];snprintf(tmp,10,"%d",nvoice+1);o->label(strdup(tmp)); + o->value(pars->VoicePar[nvoice].Enabled); + } // Fl_Check_Button* voiceenabled + ADnoteVoiceListItem->end(); + } // Fl_Group* ADnoteVoiceListItem + return ADnoteVoiceListItem; +} + +ADvoicelistitem::ADvoicelistitem(int x,int y, int w, int h, const char *label):Fl_Group(x,y,w,h,label) { + nvoice=0; +pars=NULL; +} + +void ADvoicelistitem::init(ADnoteParameters *parameters,int nvoice_,Master *master_) { + pars=parameters; +nvoice=nvoice_; +master=master_; +make_window(); +ADnoteVoiceListItem->show(); +end(); +} + +void ADvoicelistitem::refreshlist() { + voiceenabled->value(pars->VoicePar[nvoice].Enabled); +voiceresonanceenabled->value(pars->VoicePar[nvoice].Presonance); +voicevolume->value(pars->VoicePar[nvoice].PVolume); +voicedetune->value(pars->VoicePar[nvoice].PDetune-8192); +voicepanning->value(pars->VoicePar[nvoice].PPanning); +voicelfofreq->value(pars->VoicePar[nvoice].FreqLfo->Pintensity); +if (pars->VoicePar[nvoice].Pextoscil != -1) { + osc->init(pars->VoicePar[pars->VoicePar[nvoice].Pextoscil].OscilSmp,0,pars->VoicePar[nvoice].Poscilphase,master); +} else + osc->init(pars->VoicePar[nvoice].OscilSmp,0,pars->VoicePar[nvoice].Poscilphase,master); +if (pars->VoicePar[nvoice].Enabled==0) voicelistitemgroup->deactivate(); + else voicelistitemgroup->activate(); +detunevalueoutput->do_callback(); +noiselabel->do_callback(); +ADnoteVoiceListItem->redraw(); +} + +ADvoicelistitem::~ADvoicelistitem() { + ADnoteVoiceListItem->hide(); +//delete(ADnoteVoiceListItem); +} + +void ADvoiceUI::cb_Enable_i(Fl_Check_Button* o, void*) { + pars->VoicePar[nvoice].PFMFreqEnvelopeEnabled=(int)o->value(); +if (o->value()==0) voiceFMfreqenvgroup->deactivate(); +else voiceFMfreqenvgroup->activate(); +o->redraw(); +} +void ADvoiceUI::cb_Enable(Fl_Check_Button* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->parent()->parent()->user_data()))->cb_Enable_i(o,v); +} + +void ADvoiceUI::cb_Coarse_i(Fl_Counter* o, void*) { + int k=(int) o->value(); +if (k<0) k+=1024; +pars->VoicePar[nvoice].PFMCoarseDetune = k+ + (pars->VoicePar[nvoice].PFMCoarseDetune/1024)*1024; +} +void ADvoiceUI::cb_Coarse(Fl_Counter* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->parent()->parent()->user_data()))->cb_Coarse_i(o,v); +} + +void ADvoiceUI::cb_Octave_i(Fl_Counter* o, void*) { + int k=(int) o->value(); +if (k<0) k+=16; +pars->VoicePar[nvoice].PFMCoarseDetune = k*1024+ + pars->VoicePar[nvoice].PFMCoarseDetune%1024; +} +void ADvoiceUI::cb_Octave(Fl_Counter* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->parent()->parent()->user_data()))->cb_Octave_i(o,v); +} + +void ADvoiceUI::cb__i(Fl_Slider* o, void*) { + pars->VoicePar[nvoice].PFMDetune=(int)o->value()+8192; +fmdetunevalueoutput->do_callback(); +} +void ADvoiceUI::cb_(Fl_Slider* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->parent()->parent()->user_data()))->cb__i(o,v); +} + +void ADvoiceUI::cb_fmdetunevalueoutput_i(Fl_Value_Output* o, void*) { + o->value(getdetune((pars->VoicePar[nvoice].PFMDetuneType==0)?(pars->GlobalPar.PDetuneType) : (pars->VoicePar[nvoice].PFMDetuneType),0,pars->VoicePar[nvoice].PFMDetune)); +} +void ADvoiceUI::cb_fmdetunevalueoutput(Fl_Value_Output* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->parent()->parent()->user_data()))->cb_fmdetunevalueoutput_i(o,v); +} + +void ADvoiceUI::cb_Detune_i(Fl_Choice* o, void*) { + pars->VoicePar[nvoice].PFMDetuneType=(int) o->value(); +fmdetunevalueoutput->do_callback(); +} +void ADvoiceUI::cb_Detune(Fl_Choice* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->parent()->parent()->user_data()))->cb_Detune_i(o,v); +} + +void ADvoiceUI::cb_Vol_i(Fl_Value_Slider* o, void*) { + pars->VoicePar[nvoice].PFMVolume=(int)o->value(); +} +void ADvoiceUI::cb_Vol(Fl_Value_Slider* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->parent()->parent()->user_data()))->cb_Vol_i(o,v); +} + +void ADvoiceUI::cb_V_i(Fl_Value_Slider* o, void*) { + pars->VoicePar[nvoice].PFMVelocityScaleFunction=(int) o->value(); +} +void ADvoiceUI::cb_V(Fl_Value_Slider* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->parent()->parent()->user_data()))->cb_V_i(o,v); +} + +void ADvoiceUI::cb_Enable1_i(Fl_Check_Button* o, void*) { + pars->VoicePar[nvoice].PFMAmpEnvelopeEnabled=(int)o->value(); +if (o->value()==0) voiceFMampenvgroup->deactivate(); +else voiceFMampenvgroup->activate(); +o->redraw(); +} +void ADvoiceUI::cb_Enable1(Fl_Check_Button* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->parent()->parent()->user_data()))->cb_Enable1_i(o,v); +} + +void ADvoiceUI::cb_F_i(Fl_Value_Slider* o, void*) { + pars->VoicePar[nvoice].PFMVolumeDamp=(int) o->value()+64; +} +void ADvoiceUI::cb_F(Fl_Value_Slider* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->parent()->parent()->user_data()))->cb_F_i(o,v); +} + +void ADvoiceUI::cb_changeFMoscilbutton_i(Fl_Button*, void*) { + if (oscedit!=NULL) delete(oscedit); + +int nv=nvoice; +if (pars->VoicePar[nvoice].PextFMoscil>=0) nv=pars->VoicePar[nvoice].PextFMoscil; + +oscedit=new OscilEditor(pars->VoicePar[nv].FMSmp,fmoscil,NULL,NULL,master); +} +void ADvoiceUI::cb_changeFMoscilbutton(Fl_Button* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->parent()->parent()->user_data()))->cb_changeFMoscilbutton_i(o,v); +} + +void ADvoiceUI::cb_Phase_i(Fl_Slider* o, void*) { + pars->VoicePar[nvoice].PFMoscilphase=64-(int)o->value(); +oscFM->phase=64-(int) o->value(); +fmoscil->redraw(); +} +void ADvoiceUI::cb_Phase(Fl_Slider* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->parent()->parent()->user_data()))->cb_Phase_i(o,v); +} + +void ADvoiceUI::cb_Use_i(Fl_Choice* o, void*) { + pars->VoicePar[nvoice].PextFMoscil=(int)o->value()-1; +if ((int) o->value() != 0) { + oscFM->init(pars->VoicePar[(int) o->value()-1].FMSmp,master); + changeFMoscilbutton->labelcolor(FL_BLUE); +} else { + oscFM->init(pars->VoicePar[nvoice].FMSmp,master); + changeFMoscilbutton->labelcolor(FL_BLACK); +}; +voiceFMparametersgroup->redraw(); +} +void ADvoiceUI::cb_Use(Fl_Choice* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->parent()->parent()->user_data()))->cb_Use_i(o,v); +} + +void ADvoiceUI::cb_External_i(Fl_Choice* o, void*) { + pars->VoicePar[nvoice].PFMVoice=(int)o->value()-1; +if ((int) o->value() != 0) { + modoscil->deactivate(); + modfrequency->deactivate(); +} else { + modoscil->activate(); + modfrequency->activate(); +}; +voiceFMparametersgroup->redraw(); +} +void ADvoiceUI::cb_External(Fl_Choice* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_External_i(o,v); +} + +void ADvoiceUI::cb_Type_i(Fl_Choice* o, void*) { + pars->VoicePar[nvoice].PFMEnabled=(int)o->value(); +if (o->value()==0) voiceFMparametersgroup->deactivate(); +else voiceFMparametersgroup->activate(); +o->redraw(); +} +void ADvoiceUI::cb_Type(Fl_Choice* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->user_data()))->cb_Type_i(o,v); +} + +Fl_Menu_Item ADvoiceUI::menu_Type[] = { + {"OFF", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 14, 0}, + {"MORPH", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 14, 0}, + {"RING", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 14, 0}, + {"PM", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 14, 0}, + {"FM", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 14, 0}, + {"PITCH", 0, 0, 0, 1, FL_NORMAL_LABEL, 1, 14, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void ADvoiceUI::cb_Enable2_i(Fl_Check_Button* o, void*) { + pars->VoicePar[nvoice].PFreqEnvelopeEnabled=(int)o->value(); +if (o->value()==0) voicefreqenvgroup->deactivate(); +else voicefreqenvgroup->activate(); +o->redraw(); +} +void ADvoiceUI::cb_Enable2(Fl_Check_Button* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_Enable2_i(o,v); +} + +void ADvoiceUI::cb_Enable3_i(Fl_Check_Button* o, void*) { + pars->VoicePar[nvoice].PFreqLfoEnabled=(int)o->value(); +if (o->value()==0) voicefreqlfogroup->deactivate(); +else voicefreqlfogroup->activate(); +o->redraw(); +} +void ADvoiceUI::cb_Enable3(Fl_Check_Button* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_Enable3_i(o,v); +} + +void ADvoiceUI::cb_Octave1_i(Fl_Counter* o, void*) { + int k=(int) o->value(); +if (k<0) k+=16; +pars->VoicePar[nvoice].PCoarseDetune = k*1024+ + pars->VoicePar[nvoice].PCoarseDetune%1024; +} +void ADvoiceUI::cb_Octave1(Fl_Counter* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_Octave1_i(o,v); +} + +void ADvoiceUI::cb_Coarse1_i(Fl_Counter* o, void*) { + int k=(int) o->value(); +if (k<0) k+=1024; +pars->VoicePar[nvoice].PCoarseDetune = k+ + (pars->VoicePar[nvoice].PCoarseDetune/1024)*1024; +} +void ADvoiceUI::cb_Coarse1(Fl_Counter* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_Coarse1_i(o,v); +} + +void ADvoiceUI::cb_1_i(Fl_Slider* o, void*) { + pars->VoicePar[nvoice].PDetune=(int)o->value()+8192; +detunevalueoutput->do_callback(); +} +void ADvoiceUI::cb_1(Fl_Slider* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_1_i(o,v); +} + +void ADvoiceUI::cb_detunevalueoutput1_i(Fl_Value_Output* o, void*) { + o->value(getdetune((pars->VoicePar[nvoice].PDetuneType==0)?(pars->GlobalPar.PDetuneType) : (pars->VoicePar[nvoice].PDetuneType),0,pars->VoicePar[nvoice].PDetune)*pars->getBandwidthDetuneMultiplier()); +} +void ADvoiceUI::cb_detunevalueoutput1(Fl_Value_Output* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_detunevalueoutput1_i(o,v); +} + +void ADvoiceUI::cb_440Hz_i(Fl_Check_Button* o, void*) { + int x=(int) o->value(); +pars->VoicePar[nvoice].Pfixedfreq=x; +if (x==0) fixedfreqetdial->deactivate(); + else fixedfreqetdial->activate(); +} +void ADvoiceUI::cb_440Hz(Fl_Check_Button* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_440Hz_i(o,v); +} + +void ADvoiceUI::cb_fixedfreqetdial_i(WidgetPDial* o, void*) { + pars->VoicePar[nvoice].PfixedfreqET=(int) o->value(); +} +void ADvoiceUI::cb_fixedfreqetdial(WidgetPDial* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_fixedfreqetdial_i(o,v); +} + +void ADvoiceUI::cb_Detune1_i(Fl_Choice* o, void*) { + pars->VoicePar[nvoice].PDetuneType=(int) o->value(); +detunevalueoutput->do_callback(); +} +void ADvoiceUI::cb_Detune1(Fl_Choice* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_Detune1_i(o,v); +} + +void ADvoiceUI::cb_changevoiceoscilbutton_i(Fl_Button*, void*) { + if (oscedit!=NULL) delete(oscedit); + +int nv=nvoice; +if (pars->VoicePar[nvoice].Pextoscil>=0) nv=pars->VoicePar[nvoice].Pextoscil; + +oscedit=new OscilEditor(pars->VoicePar[nv].OscilSmp,voiceoscil,NULL,NULL,master); +} +void ADvoiceUI::cb_changevoiceoscilbutton(Fl_Button* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->user_data()))->cb_changevoiceoscilbutton_i(o,v); +} + +void ADvoiceUI::cb_Phase1_i(Fl_Slider* o, void*) { + pars->VoicePar[nvoice].Poscilphase=64-(int)o->value(); +osc->phase=64-(int) o->value(); +voiceoscil->redraw(); +} +void ADvoiceUI::cb_Phase1(Fl_Slider* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->user_data()))->cb_Phase1_i(o,v); +} + +void ADvoiceUI::cb_R_i(Fl_Check_Button* o, void*) { + pars->VoicePar[nvoice].Presonance=(int) o->value(); +} +void ADvoiceUI::cb_R(Fl_Check_Button* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->user_data()))->cb_R_i(o,v); +} + +void ADvoiceUI::cb_Use1_i(Fl_Choice* o, void*) { + pars->VoicePar[nvoice].Pextoscil=(int)o->value()-1; +if ((int) o->value() != 0) { + osc->init(pars->VoicePar[(int) o->value()-1].OscilSmp,master); + changevoiceoscilbutton->labelcolor(FL_BLUE); +} else { + osc->init(pars->VoicePar[nvoice].OscilSmp,master); + changevoiceoscilbutton->labelcolor(FL_BLACK); +}; + +voiceparametersgroup->redraw(); +voiceonbutton->redraw(); +} +void ADvoiceUI::cb_Use1(Fl_Choice* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->user_data()))->cb_Use1_i(o,v); +} + +void ADvoiceUI::cb_Vol1_i(Fl_Value_Slider* o, void*) { + pars->VoicePar[nvoice].PVolume=(int)o->value(); +} +void ADvoiceUI::cb_Vol1(Fl_Value_Slider* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->user_data()))->cb_Vol1_i(o,v); +} + +void ADvoiceUI::cb_V1_i(Fl_Value_Slider* o, void*) { + pars->VoicePar[nvoice].PAmpVelocityScaleFunction=(int) o->value(); +} +void ADvoiceUI::cb_V1(Fl_Value_Slider* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->user_data()))->cb_V1_i(o,v); +} + +void ADvoiceUI::cb_Pan_i(WidgetPDial* o, void*) { + pars->VoicePar[nvoice].PPanning=(int) o->value(); +} +void ADvoiceUI::cb_Pan(WidgetPDial* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->user_data()))->cb_Pan_i(o,v); +} + +void ADvoiceUI::cb_Enable4_i(Fl_Check_Button* o, void*) { + pars->VoicePar[nvoice].PAmpEnvelopeEnabled=(int)o->value(); +if (o->value()==0) voiceampenvgroup->deactivate(); +else voiceampenvgroup->activate(); +o->redraw(); +} +void ADvoiceUI::cb_Enable4(Fl_Check_Button* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->user_data()))->cb_Enable4_i(o,v); +} + +void ADvoiceUI::cb_Enable5_i(Fl_Check_Button* o, void*) { + pars->VoicePar[nvoice].PAmpLfoEnabled=(int)o->value(); +if (o->value()==0) voiceamplfogroup->deactivate(); +else voiceamplfogroup->activate(); +o->redraw(); +} +void ADvoiceUI::cb_Enable5(Fl_Check_Button* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->user_data()))->cb_Enable5_i(o,v); +} + +void ADvoiceUI::cb_Minus_i(Fl_Check_Button* o, void*) { + pars->VoicePar[nvoice].PVolumeminus=(int)o->value(); +} +void ADvoiceUI::cb_Minus(Fl_Check_Button* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->user_data()))->cb_Minus_i(o,v); +} + +void ADvoiceUI::cb_Enable6_i(Fl_Check_Button* o, void*) { + pars->VoicePar[nvoice].PFilterEnvelopeEnabled=(int)o->value(); +if (o->value()==0) voicefilterenvgroup->deactivate(); +else voicefilterenvgroup->activate(); +o->redraw(); +} +void ADvoiceUI::cb_Enable6(Fl_Check_Button* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->user_data()))->cb_Enable6_i(o,v); +} + +void ADvoiceUI::cb_Enable7_i(Fl_Check_Button* o, void*) { + pars->VoicePar[nvoice].PFilterLfoEnabled=(int)o->value(); +if (o->value()==0) voicefilterlfogroup->deactivate(); +else voicefilterlfogroup->activate(); +o->redraw(); +} +void ADvoiceUI::cb_Enable7(Fl_Check_Button* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->user_data()))->cb_Enable7_i(o,v); +} + +void ADvoiceUI::cb_2_i(Fl_Choice* o, void*) { + int x=(int) o->value(); +pars->VoicePar[nvoice].Type=x; +if (x==0) voicemodegroup->activate(); + else voicemodegroup->deactivate(); +noiselabel->do_callback(); +} +void ADvoiceUI::cb_2(Fl_Choice* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->user_data()))->cb_2_i(o,v); +} + +Fl_Menu_Item ADvoiceUI::menu_[] = { + {"Sound", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"NOISE", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 1}, + {0,0,0,0,0,0,0,0,0} +}; + +void ADvoiceUI::cb_bypassfiltercheckbutton_i(Fl_Check_Button* o, void*) { + pars->VoicePar[nvoice].Pfilterbypass=(int)o->value(); +} +void ADvoiceUI::cb_bypassfiltercheckbutton(Fl_Check_Button* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->user_data()))->cb_bypassfiltercheckbutton_i(o,v); +} + +void ADvoiceUI::cb_Delay_i(Fl_Value_Slider* o, void*) { + pars->VoicePar[nvoice].PDelay=(int)o->value(); +} +void ADvoiceUI::cb_Delay(Fl_Value_Slider* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->parent()->user_data()))->cb_Delay_i(o,v); +} + +void ADvoiceUI::cb_Enable8_i(Fl_Check_Button* o, void*) { + pars->VoicePar[nvoice].PFilterEnabled=(int)o->value(); +if (o->value()==0) voicefiltergroup->deactivate(); +else voicefiltergroup->activate(); +o->redraw(); +bypassfiltercheckbutton->redraw(); +} +void ADvoiceUI::cb_Enable8(Fl_Check_Button* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->user_data()))->cb_Enable8_i(o,v); +} + +void ADvoiceUI::cb_noiselabel1_i(Fl_Box* o, void*) { + if (pars->VoicePar[nvoice].Type==0) o->hide(); else o->show(); +} +void ADvoiceUI::cb_noiselabel1(Fl_Box* o, void* v) { + ((ADvoiceUI*)(o->parent()->parent()->user_data()))->cb_noiselabel1_i(o,v); +} + +void ADvoiceUI::cb_voiceonbutton_i(Fl_Check_Button* o, void*) { + pars->VoicePar[nvoice].Enabled=(int)o->value(); +if (o->value()==0) voiceparametersgroup->deactivate(); +else voiceparametersgroup->activate(); +o->redraw(); +} +void ADvoiceUI::cb_voiceonbutton(Fl_Check_Button* o, void* v) { + ((ADvoiceUI*)(o->parent()->user_data()))->cb_voiceonbutton_i(o,v); +} + +Fl_Group* ADvoiceUI::make_window() { + { ADnoteVoiceParameters = new Fl_Group(0, 0, 765, 525, "Voice"); + ADnoteVoiceParameters->box(FL_FLAT_BOX); + ADnoteVoiceParameters->color(FL_BACKGROUND_COLOR); + ADnoteVoiceParameters->selection_color(FL_BACKGROUND_COLOR); + ADnoteVoiceParameters->labeltype(FL_NO_LABEL); + ADnoteVoiceParameters->labelfont(0); + ADnoteVoiceParameters->labelsize(14); + ADnoteVoiceParameters->labelcolor(FL_FOREGROUND_COLOR); + ADnoteVoiceParameters->user_data((void*)(this)); + ADnoteVoiceParameters->align(FL_ALIGN_TOP); + ADnoteVoiceParameters->when(FL_WHEN_RELEASE); + { Fl_Group* o = voiceparametersgroup = new Fl_Group(0, 0, 765, 525); + voiceparametersgroup->box(FL_THIN_UP_BOX); + voiceparametersgroup->color((Fl_Color)48); + { voicemodegroup = new Fl_Group(0, 5, 760, 515); + { Fl_Group* o = voiceFMparametersgroup = new Fl_Group(530, 5, 230, 515, "MODULATOR"); + voiceFMparametersgroup->box(FL_THIN_UP_FRAME); + voiceFMparametersgroup->color((Fl_Color)48); + voiceFMparametersgroup->labeltype(FL_EMBOSSED_LABEL); + voiceFMparametersgroup->labelfont(1); + voiceFMparametersgroup->labelsize(13); + voiceFMparametersgroup->align(FL_ALIGN_TOP|FL_ALIGN_INSIDE); + { modfrequency = new Fl_Group(535, 220, 220, 145, "Mod.FREQUENCY"); + modfrequency->box(FL_THIN_UP_BOX); + modfrequency->labeltype(FL_EMBOSSED_LABEL); + modfrequency->labelfont(1); + modfrequency->labelsize(13); + modfrequency->align(FL_ALIGN_TOP|FL_ALIGN_INSIDE); + { EnvelopeUI* o = voiceFMfreqenvgroup = new EnvelopeUI(540, 290, 205, 70, "ADSynth Modulator - Frequency Envelope"); + voiceFMfreqenvgroup->box(FL_FLAT_BOX); + voiceFMfreqenvgroup->color((Fl_Color)51); + voiceFMfreqenvgroup->selection_color(FL_BACKGROUND_COLOR); + voiceFMfreqenvgroup->labeltype(FL_NORMAL_LABEL); + voiceFMfreqenvgroup->labelfont(0); + voiceFMfreqenvgroup->labelsize(14); + voiceFMfreqenvgroup->labelcolor(FL_FOREGROUND_COLOR); + voiceFMfreqenvgroup->align(FL_ALIGN_WRAP|FL_ALIGN_INSIDE); + voiceFMfreqenvgroup->when(FL_WHEN_RELEASE); + o->init(pars->VoicePar[nvoice].FMFreqEnvelope); + if (pars->VoicePar[nvoice].PFMFreqEnvelopeEnabled==0) o->deactivate(); + voiceFMfreqenvgroup->end(); + } // EnvelopeUI* voiceFMfreqenvgroup + { Fl_Check_Button* o = new Fl_Check_Button(545, 295, 50, 10, "Enable"); + o->tooltip("Forced Relase"); + o->down_box(FL_DOWN_BOX); + o->labelfont(1); + o->labelsize(10); + o->callback((Fl_Callback*)cb_Enable); + o->value(pars->VoicePar[nvoice].PFMFreqEnvelopeEnabled); + } // Fl_Check_Button* o + { Fl_Counter* o = new Fl_Counter(685, 270, 60, 15, "Coarse Det."); + o->tooltip("Coarse Detune"); + o->labelsize(10); + o->minimum(-64); + o->maximum(63); + o->step(1); + o->textfont(1); + o->textsize(11); + o->callback((Fl_Callback*)cb_Coarse); + o->align(FL_ALIGN_TOP); + int k=pars->VoicePar[nvoice].PFMCoarseDetune%1024; + if (k>=512) k-=1024; + o->value(k); + o->lstep(10); + } // Fl_Counter* o + { Fl_Counter* o = new Fl_Counter(625, 270, 45, 15, "Octave"); + o->tooltip("Octave"); + o->type(1); + o->labelsize(10); + o->minimum(-8); + o->maximum(7); + o->step(1); + o->textfont(1); + o->textsize(11); + o->callback((Fl_Callback*)cb_Octave); + o->align(FL_ALIGN_TOP); + int k=pars->VoicePar[nvoice].PFMCoarseDetune/1024; + if (k>=8) k-=16; + o->value(k); + } // Fl_Counter* o + { Fl_Slider* o = new Fl_Slider(590, 245, 160, 10); + o->tooltip("Fine Detune (cents)"); + o->type(5); + o->box(FL_FLAT_BOX); + o->minimum(-8192); + o->maximum(8191); + o->step(1); + o->callback((Fl_Callback*)cb_); + o->value(pars->VoicePar[nvoice].PFMDetune-8192); + } // Fl_Slider* o + { Fl_Value_Output* o = fmdetunevalueoutput = new Fl_Value_Output(540, 245, 45, 13, "Detune"); + fmdetunevalueoutput->labelsize(8); + fmdetunevalueoutput->minimum(-5000); + fmdetunevalueoutput->maximum(5000); + fmdetunevalueoutput->step(0.01); + fmdetunevalueoutput->textfont(1); + fmdetunevalueoutput->textsize(8); + fmdetunevalueoutput->callback((Fl_Callback*)cb_fmdetunevalueoutput); + fmdetunevalueoutput->align(FL_ALIGN_TOP_LEFT); + o->value(getdetune((pars->VoicePar[nvoice].PFMDetuneType==0)?(pars->GlobalPar.PDetuneType) : (pars->VoicePar[nvoice].PFMDetuneType),0,pars->VoicePar[nvoice].PFMDetune)); + //o->value(getdetune(pars->VoicePar[nvoice].PFMDetuneType,0,pars->VoicePar[nvoice].PFMDetune)); + } // Fl_Value_Output* fmdetunevalueoutput + { Fl_Choice* o = new Fl_Choice(540, 270, 75, 15, "Detune Type"); + o->down_box(FL_BORDER_BOX); + o->labelsize(10); + o->textfont(1); + o->textsize(10); + o->callback((Fl_Callback*)cb_Detune); + o->align(FL_ALIGN_TOP_LEFT); + o->add("Default");o->add("L35cents");o->add("L10cents");o->add("E100cents");o->add("E1200cents"); + o->value(pars->VoicePar[nvoice].PFMDetuneType); + } // Fl_Choice* o + modfrequency->end(); + } // Fl_Group* modfrequency + { Fl_Group* o = new Fl_Group(535, 60, 220, 160, "Mod.AMPLITUDE"); + o->box(FL_THIN_UP_BOX); + o->labeltype(FL_EMBOSSED_LABEL); + o->labelfont(1); + o->labelsize(13); + o->align(FL_ALIGN_TOP|FL_ALIGN_INSIDE); + { Fl_Value_Slider* o = new Fl_Value_Slider(540, 80, 160, 15, "Vol"); + o->tooltip("Volume"); + o->type(5); + o->box(FL_FLAT_BOX); + o->labelsize(11); + o->maximum(127); + o->step(1); + o->callback((Fl_Callback*)cb_Vol); + o->align(FL_ALIGN_RIGHT); + o->value(pars->VoicePar[nvoice].PFMVolume); + } // Fl_Value_Slider* o + { Fl_Value_Slider* o = new Fl_Value_Slider(540, 100, 160, 15, "V.Sns"); + o->tooltip("Velocity Sensing Function (rightmost to disable)"); + o->type(5); + o->box(FL_FLAT_BOX); + o->labelsize(11); + o->maximum(127); + o->step(1); + o->callback((Fl_Callback*)cb_V); + o->align(FL_ALIGN_RIGHT); + o->value(pars->VoicePar[nvoice].PFMVelocityScaleFunction); + } // Fl_Value_Slider* o + { EnvelopeUI* o = voiceFMampenvgroup = new EnvelopeUI(540, 145, 205, 70, "ADSynth Modulator - Amplitude Envelope"); + voiceFMampenvgroup->box(FL_FLAT_BOX); + voiceFMampenvgroup->color((Fl_Color)51); + voiceFMampenvgroup->selection_color(FL_BACKGROUND_COLOR); + voiceFMampenvgroup->labeltype(FL_NORMAL_LABEL); + voiceFMampenvgroup->labelfont(0); + voiceFMampenvgroup->labelsize(14); + voiceFMampenvgroup->labelcolor(FL_FOREGROUND_COLOR); + voiceFMampenvgroup->align(FL_ALIGN_WRAP|FL_ALIGN_INSIDE); + voiceFMampenvgroup->when(FL_WHEN_RELEASE); + o->init(pars->VoicePar[nvoice].FMAmpEnvelope); + if (pars->VoicePar[nvoice].PFMAmpEnvelopeEnabled==0) o->deactivate(); + voiceFMampenvgroup->end(); + } // EnvelopeUI* voiceFMampenvgroup + { Fl_Check_Button* o = new Fl_Check_Button(545, 150, 50, 10, "Enable"); + o->tooltip("Forced Relase"); + o->down_box(FL_DOWN_BOX); + o->labelfont(1); + o->labelsize(10); + o->callback((Fl_Callback*)cb_Enable1); + o->value(pars->VoicePar[nvoice].PFMAmpEnvelopeEnabled); + } // Fl_Check_Button* o + { Fl_Value_Slider* o = new Fl_Value_Slider(540, 120, 160, 15, "F.Damp"); + o->tooltip("Modulator Damp at Higher frequency"); + o->type(5); + o->box(FL_FLAT_BOX); + o->labelsize(11); + o->minimum(-64); + o->maximum(63); + o->step(1); + o->callback((Fl_Callback*)cb_F); + o->align(FL_ALIGN_RIGHT); + o->value(pars->VoicePar[nvoice].PFMVolumeDamp-64); + } // Fl_Value_Slider* o + o->end(); + } // Fl_Group* o + { modoscil = new Fl_Group(535, 365, 220, 150); + { Fl_Group* o = fmoscil = new Fl_Group(535, 405, 220, 110); + fmoscil->box(FL_THIN_DOWN_BOX); + fmoscil->color(FL_GRAY0); + fmoscil->selection_color((Fl_Color)71); + fmoscil->labelcolor((Fl_Color)179); + oscFM=new Oscilloscope(o->x(),o->y(),o->w(),o->h(),""); + int nv=nvoice; if (pars->VoicePar[nvoice].PextFMoscil>=0) nv=pars->VoicePar[nvoice].PextFMoscil; + oscFM->init(pars->VoicePar[nv].FMSmp,0,pars->VoicePar[nvoice].PFMoscilphase,master); + fmoscil->end(); + } // Fl_Group* fmoscil + { Fl_Box* o = new Fl_Box(535, 365, 155, 20, "Mod.Oscillator"); + o->labelfont(1); + o->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE); + } // Fl_Box* o + { Fl_Button* o = changeFMoscilbutton = new Fl_Button(700, 370, 55, 15, "Change"); + changeFMoscilbutton->box(FL_THIN_UP_BOX); + changeFMoscilbutton->labelfont(1); + changeFMoscilbutton->labelsize(11); + changeFMoscilbutton->callback((Fl_Callback*)cb_changeFMoscilbutton); + if (pars->VoicePar[nvoice].PextFMoscil>=0) o->labelcolor(FL_BLUE); + } // Fl_Button* changeFMoscilbutton + { Fl_Slider* o = new Fl_Slider(665, 395, 65, 10, "Phase"); + o->type(5); + o->box(FL_FLAT_BOX); + o->labelsize(10); + o->minimum(-64); + o->maximum(63); + o->step(1); + o->callback((Fl_Callback*)cb_Phase); + o->align(FL_ALIGN_TOP_LEFT); + o->value(64-pars->VoicePar[nvoice].PFMoscilphase); + } // Fl_Slider* o + { Fl_Choice* o = new Fl_Choice(560, 390, 75, 15, "Use"); + o->down_box(FL_BORDER_BOX); + o->labelsize(10); + o->textfont(1); + o->textsize(10); + o->callback((Fl_Callback*)cb_Use); + o->add("Internal"); + char tmp[50]; for (int i=0;iadd(tmp);}; + o->value(pars->VoicePar[nvoice].PextFMoscil+1); + } // Fl_Choice* o + modoscil->end(); + } // Fl_Group* modoscil + { Fl_Choice* o = new Fl_Choice(635, 40, 85, 20, "External Mod."); + o->down_box(FL_BORDER_BOX); + o->labelsize(10); + o->textfont(1); + o->textsize(10); + o->callback((Fl_Callback*)cb_External); + o->align(FL_ALIGN_TOP_LEFT); + o->add("OFF"); + char tmp[50]; for (int i=0;iadd(tmp);}; + o->value(pars->VoicePar[nvoice].PFMVoice+1); + if ((int) o->value() != 0) {modoscil->deactivate();modfrequency->deactivate();} + } // Fl_Choice* o + if (pars->VoicePar[nvoice].PFMEnabled==0) o->deactivate(); + voiceFMparametersgroup->end(); + } // Fl_Group* voiceFMparametersgroup + { Fl_Choice* o = new Fl_Choice(535, 40, 80, 20, "Type:"); + o->down_box(FL_BORDER_BOX); + o->callback((Fl_Callback*)cb_Type); + o->align(FL_ALIGN_TOP_LEFT); + o->menu(menu_Type); + o->value(pars->VoicePar[nvoice].PFMEnabled); + } // Fl_Choice* o + { Fl_Group* o = new Fl_Group(5, 250, 525, 120, "FREQUENCY"); + o->box(FL_THIN_UP_BOX); + o->labeltype(FL_EMBOSSED_LABEL); + o->labelfont(1); + o->labelsize(13); + o->align(FL_ALIGN_TOP|FL_ALIGN_INSIDE); + { EnvelopeUI* o = voicefreqenvgroup = new EnvelopeUI(10, 290, 205, 70, "ADSynth Voice - Frequency Envelope"); + voicefreqenvgroup->box(FL_FLAT_BOX); + voicefreqenvgroup->color((Fl_Color)51); + voicefreqenvgroup->selection_color(FL_BACKGROUND_COLOR); + voicefreqenvgroup->labeltype(FL_NORMAL_LABEL); + voicefreqenvgroup->labelfont(0); + voicefreqenvgroup->labelsize(14); + voicefreqenvgroup->labelcolor(FL_FOREGROUND_COLOR); + voicefreqenvgroup->align(FL_ALIGN_WRAP|FL_ALIGN_INSIDE); + voicefreqenvgroup->when(FL_WHEN_RELEASE); + o->init(pars->VoicePar[nvoice].FreqEnvelope); + if (pars->VoicePar[nvoice].PFreqEnvelopeEnabled==0) o->deactivate(); + voicefreqenvgroup->end(); + } // EnvelopeUI* voicefreqenvgroup + { Fl_Check_Button* o = new Fl_Check_Button(15, 295, 50, 10, "Enable"); + o->tooltip("Forced Relase"); + o->down_box(FL_DOWN_BOX); + o->labelfont(1); + o->labelsize(10); + o->callback((Fl_Callback*)cb_Enable2); + o->value(pars->VoicePar[nvoice].PFreqEnvelopeEnabled); + } // Fl_Check_Button* o + { LFOUI* o = voicefreqlfogroup = new LFOUI(215, 290, 230, 70, "Frequency LFO "); + voicefreqlfogroup->box(FL_FLAT_BOX); + voicefreqlfogroup->color(FL_DARK1); + voicefreqlfogroup->selection_color(FL_BACKGROUND_COLOR); + voicefreqlfogroup->labeltype(FL_NORMAL_LABEL); + voicefreqlfogroup->labelfont(0); + voicefreqlfogroup->labelsize(14); + voicefreqlfogroup->labelcolor(FL_FOREGROUND_COLOR); + voicefreqlfogroup->align(FL_ALIGN_WRAP|FL_ALIGN_INSIDE); + voicefreqlfogroup->when(FL_WHEN_RELEASE); + o->init(pars->VoicePar[nvoice].FreqLfo); + if (pars->VoicePar[nvoice].PFreqLfoEnabled==0) o->deactivate(); + voicefreqlfogroup->end(); + } // LFOUI* voicefreqlfogroup + { Fl_Check_Button* o = new Fl_Check_Button(220, 295, 55, 10, "Enable"); + o->tooltip("Forced Relase"); + o->down_box(FL_DOWN_BOX); + o->labelfont(1); + o->labelsize(10); + o->callback((Fl_Callback*)cb_Enable3); + o->value(pars->VoicePar[nvoice].PFreqLfoEnabled); + } // Fl_Check_Button* o + { Fl_Counter* o = new Fl_Counter(470, 270, 45, 15, "Octave"); + o->tooltip("Octave"); + o->type(1); + o->labelsize(10); + o->minimum(-8); + o->maximum(7); + o->step(1); + o->textfont(1); + o->textsize(11); + o->callback((Fl_Callback*)cb_Octave1); + o->align(FL_ALIGN_TOP); + int k=pars->VoicePar[nvoice].PCoarseDetune/1024; + if (k>=8) k-=16; + o->value(k); + } // Fl_Counter* o + { Fl_Counter* o = new Fl_Counter(455, 340, 60, 20, "Coarse Det."); + o->tooltip("Coarse Detune"); + o->labelsize(10); + o->minimum(-64); + o->maximum(63); + o->step(1); + o->textfont(1); + o->textsize(11); + o->callback((Fl_Callback*)cb_Coarse1); + o->align(FL_ALIGN_TOP); + int k=pars->VoicePar[nvoice].PCoarseDetune%1024; + if (k>=512) k-=1024; + o->value(k); + o->lstep(10); + } // Fl_Counter* o + { Fl_Slider* o = new Fl_Slider(58, 272, 392, 13); + o->tooltip("Fine Detune (cents)"); + o->type(5); + o->box(FL_FLAT_BOX); + o->minimum(-8192); + o->maximum(8191); + o->step(1); + o->callback((Fl_Callback*)cb_1); + o->value(pars->VoicePar[nvoice].PDetune-8192); + } // Fl_Slider* o + { Fl_Value_Output* o = detunevalueoutput = new Fl_Value_Output(10, 272, 45, 15, "Detune"); + detunevalueoutput->labelsize(10); + detunevalueoutput->minimum(-5000); + detunevalueoutput->maximum(5000); + detunevalueoutput->step(0.01); + detunevalueoutput->textfont(1); + detunevalueoutput->textsize(10); + detunevalueoutput->callback((Fl_Callback*)cb_detunevalueoutput1); + detunevalueoutput->align(FL_ALIGN_TOP_LEFT); + o->value(getdetune((pars->VoicePar[nvoice].PDetuneType==0)?(pars->GlobalPar.PDetuneType) : (pars->VoicePar[nvoice].PDetuneType),0,pars->VoicePar[nvoice].PDetune)*pars->getBandwidthDetuneMultiplier()); + } // Fl_Value_Output* detunevalueoutput + { Fl_Check_Button* o = new Fl_Check_Button(345, 253, 55, 15, "440Hz"); + o->tooltip("Set the voice base frequency to 440Hz"); + o->down_box(FL_DOWN_BOX); + o->labelfont(1); + o->labelsize(11); + o->callback((Fl_Callback*)cb_440Hz); + o->value(pars->VoicePar[nvoice].Pfixedfreq); + } // Fl_Check_Button* o + { WidgetPDial* o = fixedfreqetdial = new WidgetPDial(405, 255, 15, 15, "Eq.T."); + fixedfreqetdial->tooltip("How the frequency varies acording to the keyboard (leftmost for fixed frequen\ +cy)"); + fixedfreqetdial->box(FL_ROUND_UP_BOX); + fixedfreqetdial->color(FL_BACKGROUND_COLOR); + fixedfreqetdial->selection_color(FL_INACTIVE_COLOR); + fixedfreqetdial->labeltype(FL_NORMAL_LABEL); + fixedfreqetdial->labelfont(0); + fixedfreqetdial->labelsize(10); + fixedfreqetdial->labelcolor(FL_FOREGROUND_COLOR); + fixedfreqetdial->maximum(127); + fixedfreqetdial->step(1); + fixedfreqetdial->callback((Fl_Callback*)cb_fixedfreqetdial); + fixedfreqetdial->align(FL_ALIGN_RIGHT); + fixedfreqetdial->when(FL_WHEN_CHANGED); + o->value(pars->VoicePar[nvoice].PfixedfreqET); + if (pars->VoicePar[nvoice].Pfixedfreq==0) o->deactivate(); + } // WidgetPDial* fixedfreqetdial + { Fl_Choice* o = new Fl_Choice(450, 305, 75, 15, "Detune Type"); + o->down_box(FL_BORDER_BOX); + o->labelsize(10); + o->textfont(1); + o->textsize(10); + o->callback((Fl_Callback*)cb_Detune1); + o->align(FL_ALIGN_TOP_LEFT); + o->add("Default");o->add("L35cents");o->add("L10cents");o->add("E100cents");o->add("E1200cents"); + o->value(pars->VoicePar[nvoice].PDetuneType); + } // Fl_Choice* o + o->end(); + } // Fl_Group* o + { Fl_Group* o = voiceoscil = new Fl_Group(80, 375, 445, 145); + voiceoscil->box(FL_THIN_DOWN_BOX); + voiceoscil->color(FL_GRAY0); + voiceoscil->selection_color((Fl_Color)71); + voiceoscil->labelcolor((Fl_Color)179); + osc=new Oscilloscope(o->x(),o->y(),o->w(),o->h(),""); + int nv=nvoice; if (pars->VoicePar[nvoice].Pextoscil>=0) nv=pars->VoicePar[nvoice].Pextoscil; + osc->init(pars->VoicePar[nv].OscilSmp,0,pars->VoicePar[nvoice].Poscilphase,master); + voiceoscil->end(); + } // Fl_Group* voiceoscil + { Fl_Button* o = changevoiceoscilbutton = new Fl_Button(5, 475, 65, 20, "Change"); + changevoiceoscilbutton->box(FL_THIN_UP_BOX); + changevoiceoscilbutton->labelfont(1); + changevoiceoscilbutton->labelsize(11); + changevoiceoscilbutton->callback((Fl_Callback*)cb_changevoiceoscilbutton); + if (pars->VoicePar[nvoice].Pextoscil>=0) o->labelcolor(FL_BLUE); + } // Fl_Button* changevoiceoscilbutton + { Fl_Box* o = new Fl_Box(5, 375, 75, 35, "Voice Oscillator"); + o->labelfont(1); + o->labelsize(12); + o->align(FL_ALIGN_WRAP); + } // Fl_Box* o + { Fl_Slider* o = new Fl_Slider(10, 420, 65, 10, "Phase"); + o->type(5); + o->box(FL_FLAT_BOX); + o->labelsize(10); + o->minimum(-64); + o->maximum(63); + o->step(1); + o->callback((Fl_Callback*)cb_Phase1); + o->align(FL_ALIGN_TOP_LEFT); + o->value(64-pars->VoicePar[nvoice].Poscilphase); + } // Fl_Slider* o + { Fl_Check_Button* o = new Fl_Check_Button(210, 5, 35, 35, "R."); + o->tooltip("Resonance On/Off"); + o->box(FL_THIN_UP_BOX); + o->down_box(FL_DOWN_BOX); + o->labelfont(1); + o->labelsize(11); + o->callback((Fl_Callback*)cb_R); + o->value(pars->VoicePar[nvoice].Presonance); + } // Fl_Check_Button* o + { Fl_Choice* o = new Fl_Choice(5, 455, 65, 15, "Use Oscil."); + o->down_box(FL_BORDER_BOX); + o->labelsize(10); + o->textfont(1); + o->textsize(10); + o->callback((Fl_Callback*)cb_Use1); + o->align(FL_ALIGN_TOP_LEFT); + o->add("Internal"); + char tmp[50]; for (int i=0;iadd(tmp);}; + o->value(pars->VoicePar[nvoice].Pextoscil+1); + } // Fl_Choice* o + voicemodegroup->end(); + } // Fl_Group* voicemodegroup + { Fl_Group* o = new Fl_Group(5, 40, 240, 210, "AMPLITUDE"); + o->box(FL_THIN_UP_BOX); + o->labeltype(FL_EMBOSSED_LABEL); + o->labelfont(1); + o->labelsize(13); + o->align(FL_ALIGN_TOP|FL_ALIGN_INSIDE); + { Fl_Value_Slider* o = new Fl_Value_Slider(10, 60, 160, 15, "Vol"); + o->tooltip("Volume"); + o->type(5); + o->box(FL_FLAT_BOX); + o->labelsize(11); + o->maximum(127); + o->step(1); + o->callback((Fl_Callback*)cb_Vol1); + o->align(FL_ALIGN_RIGHT); + o->value(pars->VoicePar[nvoice].PVolume); + } // Fl_Value_Slider* o + { Fl_Value_Slider* o = new Fl_Value_Slider(10, 80, 160, 15, "V.Sns"); + o->tooltip("Velocity Sensing Function (rightmost to disable)"); + o->type(5); + o->box(FL_FLAT_BOX); + o->labelsize(11); + o->maximum(127); + o->step(1); + o->callback((Fl_Callback*)cb_V1); + o->align(FL_ALIGN_RIGHT); + o->value(pars->VoicePar[nvoice].PAmpVelocityScaleFunction); + } // Fl_Value_Slider* o + { EnvelopeUI* o = voiceampenvgroup = new EnvelopeUI(10, 105, 205, 70, "ADSynth Voice - Amplitude Envelope"); + voiceampenvgroup->box(FL_FLAT_BOX); + voiceampenvgroup->color((Fl_Color)51); + voiceampenvgroup->selection_color(FL_BACKGROUND_COLOR); + voiceampenvgroup->labeltype(FL_NORMAL_LABEL); + voiceampenvgroup->labelfont(0); + voiceampenvgroup->labelsize(14); + voiceampenvgroup->labelcolor(FL_FOREGROUND_COLOR); + voiceampenvgroup->align(FL_ALIGN_WRAP|FL_ALIGN_INSIDE); + voiceampenvgroup->when(FL_WHEN_RELEASE); + o->init(pars->VoicePar[nvoice].AmpEnvelope); + if (pars->VoicePar[nvoice].PAmpEnvelopeEnabled==0) o->deactivate(); + voiceampenvgroup->end(); + } // EnvelopeUI* voiceampenvgroup + { WidgetPDial* o = new WidgetPDial(210, 60, 30, 30, "Pan"); + o->tooltip("Panning (leftmost is Random)"); + o->box(FL_ROUND_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_INACTIVE_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(10); + o->labelcolor(FL_FOREGROUND_COLOR); + o->maximum(127); + o->step(1); + o->callback((Fl_Callback*)cb_Pan); + o->align(FL_ALIGN_BOTTOM); + o->when(FL_WHEN_CHANGED); + o->value(pars->VoicePar[nvoice].PPanning); + } // WidgetPDial* o + { Fl_Check_Button* o = new Fl_Check_Button(15, 110, 50, 10, "Enable"); + o->tooltip("Forced Relase"); + o->down_box(FL_DOWN_BOX); + o->labelfont(1); + o->labelsize(10); + o->callback((Fl_Callback*)cb_Enable4); + o->value(pars->VoicePar[nvoice].PAmpEnvelopeEnabled); + } // Fl_Check_Button* o + { LFOUI* o = voiceamplfogroup = new LFOUI(10, 175, 230, 70, "Amplitude LFO "); + voiceamplfogroup->box(FL_FLAT_BOX); + voiceamplfogroup->color(FL_DARK1); + voiceamplfogroup->selection_color(FL_BACKGROUND_COLOR); + voiceamplfogroup->labeltype(FL_NORMAL_LABEL); + voiceamplfogroup->labelfont(0); + voiceamplfogroup->labelsize(14); + voiceamplfogroup->labelcolor(FL_FOREGROUND_COLOR); + voiceamplfogroup->align(FL_ALIGN_WRAP|FL_ALIGN_INSIDE); + voiceamplfogroup->when(FL_WHEN_RELEASE); + o->init(pars->VoicePar[nvoice].AmpLfo); + if (pars->VoicePar[nvoice].PAmpLfoEnabled==0) o->deactivate(); + voiceamplfogroup->end(); + } // LFOUI* voiceamplfogroup + { Fl_Check_Button* o = new Fl_Check_Button(15, 180, 55, 10, "Enable"); + o->tooltip("Forced Relase"); + o->down_box(FL_DOWN_BOX); + o->labelfont(1); + o->labelsize(10); + o->callback((Fl_Callback*)cb_Enable5); + o->value(pars->VoicePar[nvoice].PAmpLfoEnabled); + } // Fl_Check_Button* o + { Fl_Check_Button* o = new Fl_Check_Button(10, 45, 50, 10, "Minus"); + o->down_box(FL_DOWN_BOX); + o->labelfont(1); + o->labelsize(10); + o->callback((Fl_Callback*)cb_Minus); + o->value(pars->VoicePar[nvoice].PVolumeminus); + } // Fl_Check_Button* o + o->end(); + } // Fl_Group* o + { Fl_Group* o = voicefiltergroup = new Fl_Group(245, 5, 285, 245, "FILTER"); + voicefiltergroup->box(FL_THIN_UP_BOX); + voicefiltergroup->labeltype(FL_EMBOSSED_LABEL); + voicefiltergroup->labelfont(1); + voicefiltergroup->labelsize(13); + voicefiltergroup->align(FL_ALIGN_TOP|FL_ALIGN_INSIDE); + { FilterUI* o = new FilterUI(250, 30, 275, 75, "ADsynth Voice - Filter"); + o->box(FL_FLAT_BOX); + o->color(FL_LIGHT1); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); + o->align(FL_ALIGN_WRAP|FL_ALIGN_INSIDE); + o->when(FL_WHEN_RELEASE); + o->init(pars->VoicePar[nvoice].VoiceFilter,NULL,NULL); + o->end(); + } // FilterUI* o + { EnvelopeUI* o = voicefilterenvgroup = new EnvelopeUI(250, 105, 275, 70, "ADSynth Voice - Filter Envelope"); + voicefilterenvgroup->box(FL_FLAT_BOX); + voicefilterenvgroup->color((Fl_Color)51); + voicefilterenvgroup->selection_color(FL_BACKGROUND_COLOR); + voicefilterenvgroup->labeltype(FL_NORMAL_LABEL); + voicefilterenvgroup->labelfont(0); + voicefilterenvgroup->labelsize(14); + voicefilterenvgroup->labelcolor(FL_FOREGROUND_COLOR); + voicefilterenvgroup->align(FL_ALIGN_WRAP|FL_ALIGN_INSIDE); + voicefilterenvgroup->when(FL_WHEN_RELEASE); + o->init(pars->VoicePar[nvoice].FilterEnvelope); + if (pars->VoicePar[nvoice].PFilterEnvelopeEnabled==0) o->deactivate(); + voicefilterenvgroup->end(); + } // EnvelopeUI* voicefilterenvgroup + { Fl_Check_Button* o = new Fl_Check_Button(255, 110, 55, 10, "Enable"); + o->tooltip("Forced Relase"); + o->down_box(FL_DOWN_BOX); + o->labelfont(1); + o->labelsize(10); + o->callback((Fl_Callback*)cb_Enable6); + o->value(pars->VoicePar[nvoice].PFilterEnvelopeEnabled); + } // Fl_Check_Button* o + { LFOUI* o = voicefilterlfogroup = new LFOUI(250, 175, 230, 70, "Filter LFO "); + voicefilterlfogroup->box(FL_FLAT_BOX); + voicefilterlfogroup->color(FL_DARK1); + voicefilterlfogroup->selection_color(FL_BACKGROUND_COLOR); + voicefilterlfogroup->labeltype(FL_NORMAL_LABEL); + voicefilterlfogroup->labelfont(0); + voicefilterlfogroup->labelsize(14); + voicefilterlfogroup->labelcolor(FL_FOREGROUND_COLOR); + voicefilterlfogroup->align(FL_ALIGN_WRAP|FL_ALIGN_INSIDE); + voicefilterlfogroup->when(FL_WHEN_RELEASE); + o->init(pars->VoicePar[nvoice].FilterLfo); + if (pars->VoicePar[nvoice].PFilterLfoEnabled==0) o->deactivate(); + voicefilterlfogroup->end(); + } // LFOUI* voicefilterlfogroup + { Fl_Check_Button* o = new Fl_Check_Button(255, 180, 55, 10, "Enable"); + o->tooltip("Forced Relase"); + o->down_box(FL_DOWN_BOX); + o->labelfont(1); + o->labelsize(10); + o->callback((Fl_Callback*)cb_Enable7); + o->value(pars->VoicePar[nvoice].PFilterLfoEnabled); + } // Fl_Check_Button* o + if (pars->VoicePar[nvoice].PFilterEnabled==0) o->deactivate(); + voicefiltergroup->end(); + } // Fl_Group* voicefiltergroup + { Fl_Group* o = new Fl_Group(5, 5, 55, 35, "01"); + o->box(FL_THIN_UP_BOX); + o->labeltype(FL_EMBOSSED_LABEL); + o->labelfont(1); + o->labelsize(22); + o->align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE); + char tmp[10];snprintf(tmp,10,"%d",nvoice+1);o->label(strdup(tmp)); + o->end(); + } // Fl_Group* o + { Fl_Choice* o = new Fl_Choice(5, 500, 65, 20); + o->tooltip("Oscillator Type (sound/noise)"); + o->down_box(FL_BORDER_BOX); + o->labelsize(10); + o->textfont(1); + o->textsize(10); + o->callback((Fl_Callback*)cb_2); + o->menu(menu_); + o->value(pars->VoicePar[nvoice].Type); + if (pars->VoicePar[nvoice].Type!=0) voicemodegroup->deactivate(); + } // Fl_Choice* o + { Fl_Check_Button* o = bypassfiltercheckbutton = new Fl_Check_Button(425, 10, 100, 20, "Bypass Global F."); + bypassfiltercheckbutton->down_box(FL_DOWN_BOX); + bypassfiltercheckbutton->labelfont(1); + bypassfiltercheckbutton->labelsize(10); + bypassfiltercheckbutton->callback((Fl_Callback*)cb_bypassfiltercheckbutton); + bypassfiltercheckbutton->align(132|FL_ALIGN_INSIDE); + o->value(pars->VoicePar[nvoice].Pfilterbypass); + } // Fl_Check_Button* bypassfiltercheckbutton + { Fl_Group* o = new Fl_Group(115, 5, 95, 35); + o->box(FL_THIN_UP_BOX); + { Fl_Value_Slider* o = new Fl_Value_Slider(120, 21, 84, 12, "Delay"); + o->tooltip("Volume"); + o->type(5); + o->box(FL_FLAT_BOX); + o->labelsize(11); + o->maximum(127); + o->step(1); + o->callback((Fl_Callback*)cb_Delay); + o->align(FL_ALIGN_TOP_LEFT); + o->value(pars->VoicePar[nvoice].PDelay); + } // Fl_Value_Slider* o + o->end(); + } // Fl_Group* o + { Fl_Check_Button* o = new Fl_Check_Button(250, 15, 60, 15, "Enable"); + o->tooltip("Enable Filter"); + o->down_box(FL_DOWN_BOX); + o->labelfont(1); + o->labelsize(10); + o->callback((Fl_Callback*)cb_Enable8); + o->value(pars->VoicePar[nvoice].PFilterEnabled); + } // Fl_Check_Button* o + { Fl_Box* o = noiselabel = new Fl_Box(150, 415, 300, 65, "White Noise"); + noiselabel->labelfont(1); + noiselabel->labelsize(50); + noiselabel->labelcolor(FL_BACKGROUND2_COLOR); + noiselabel->callback((Fl_Callback*)cb_noiselabel1); + if (pars->VoicePar[nvoice].Type==0) o->hide(); else o->show(); + } // Fl_Box* noiselabel + if (pars->VoicePar[nvoice].Enabled==0) o->deactivate(); + voiceparametersgroup->end(); + } // Fl_Group* voiceparametersgroup + { Fl_Check_Button* o = voiceonbutton = new Fl_Check_Button(60, 5, 55, 35, "On"); + voiceonbutton->box(FL_THIN_UP_BOX); + voiceonbutton->down_box(FL_DOWN_BOX); + voiceonbutton->labelfont(1); + voiceonbutton->labelsize(13); + voiceonbutton->callback((Fl_Callback*)cb_voiceonbutton); + o->value(pars->VoicePar[nvoice].Enabled); + } // Fl_Check_Button* voiceonbutton + ADnoteVoiceParameters->end(); + } // Fl_Group* ADnoteVoiceParameters + return ADnoteVoiceParameters; +} + +ADvoiceUI::ADvoiceUI(int x,int y, int w, int h, const char *label):Fl_Group(x,y,w,h,label) { + nvoice=0; +pars=NULL; +oscedit=NULL; +} + +void ADvoiceUI::init(ADnoteParameters *parameters,int nvoice_,Master *master_) { + pars=parameters; +nvoice=nvoice_; +master=master_; +make_window(); +end(); +ADnoteVoiceParameters->show(); +} + +ADvoiceUI::~ADvoiceUI() { + ADnoteVoiceParameters->hide(); +hide(); +if (oscedit!=NULL) { + delete(oscedit); +}; +//delete (ADnoteVoiceParameters); +} + +void ADnoteUI::cb_octave_i(Fl_Counter* o, void*) { + int k=(int) o->value(); +if (k<0) k+=16; +pars->GlobalPar.PCoarseDetune = k*1024+ + pars->GlobalPar.PCoarseDetune%1024; +} +void ADnoteUI::cb_octave(Fl_Counter* o, void* v) { + ((ADnoteUI*)(o->parent()->parent()->user_data()))->cb_octave_i(o,v); +} + +void ADnoteUI::cb_coarsedet_i(Fl_Counter* o, void*) { + int k=(int) o->value(); +if (k<0) k+=1024; +pars->GlobalPar.PCoarseDetune = k+ + (pars->GlobalPar.PCoarseDetune/1024)*1024; +} +void ADnoteUI::cb_coarsedet(Fl_Counter* o, void* v) { + ((ADnoteUI*)(o->parent()->parent()->user_data()))->cb_coarsedet_i(o,v); +} + +void ADnoteUI::cb_freq_i(Fl_Slider* o, void*) { + pars->GlobalPar.PDetune=(int)o->value()+8192; +detunevalueoutput->do_callback(); +} +void ADnoteUI::cb_freq(Fl_Slider* o, void* v) { + ((ADnoteUI*)(o->parent()->parent()->user_data()))->cb_freq_i(o,v); +} + +void ADnoteUI::cb_detunevalueoutput2_i(Fl_Value_Output* o, void*) { + o->value(getdetune(pars->GlobalPar.PDetuneType,0,pars->GlobalPar.PDetune)); +} +void ADnoteUI::cb_detunevalueoutput2(Fl_Value_Output* o, void* v) { + ((ADnoteUI*)(o->parent()->parent()->user_data()))->cb_detunevalueoutput2_i(o,v); +} + +void ADnoteUI::cb_detunetype_i(Fl_Choice* o, void*) { + pars->GlobalPar.PDetuneType=(int) o->value()+1; +detunevalueoutput->do_callback(); +} +void ADnoteUI::cb_detunetype(Fl_Choice* o, void* v) { + ((ADnoteUI*)(o->parent()->parent()->user_data()))->cb_detunetype_i(o,v); +} + +void ADnoteUI::cb_relBW_i(WidgetPDial* o, void*) { + pars->GlobalPar.PBandwidth=(int) o->value(); + +pars->getBandwidthDetuneMultiplier(); + +for (int i=0;irefreshlist(); +}; +} +void ADnoteUI::cb_relBW(WidgetPDial* o, void* v) { + ((ADnoteUI*)(o->parent()->parent()->user_data()))->cb_relBW_i(o,v); +} + +void ADnoteUI::cb_volume_i(Fl_Value_Slider* o, void*) { + pars->GlobalPar.PVolume=(int)o->value(); +} +void ADnoteUI::cb_volume(Fl_Value_Slider* o, void* v) { + ((ADnoteUI*)(o->parent()->parent()->user_data()))->cb_volume_i(o,v); +} + +void ADnoteUI::cb_vsns_i(Fl_Value_Slider* o, void*) { + pars->GlobalPar.PAmpVelocityScaleFunction=(int) o->value(); +} +void ADnoteUI::cb_vsns(Fl_Value_Slider* o, void* v) { + ((ADnoteUI*)(o->parent()->parent()->user_data()))->cb_vsns_i(o,v); +} + +void ADnoteUI::cb_pan_i(WidgetPDial* o, void*) { + pars->GlobalPar.PPanning=(int) o->value(); +} +void ADnoteUI::cb_pan(WidgetPDial* o, void* v) { + ((ADnoteUI*)(o->parent()->parent()->user_data()))->cb_pan_i(o,v); +} + +void ADnoteUI::cb_pstr_i(WidgetPDial* o, void*) { + pars->GlobalPar.PPunchStrength=(int) o->value(); +} +void ADnoteUI::cb_pstr(WidgetPDial* o, void* v) { + ((ADnoteUI*)(o->parent()->parent()->user_data()))->cb_pstr_i(o,v); +} + +void ADnoteUI::cb_pt_i(WidgetPDial* o, void*) { + pars->GlobalPar.PPunchTime=(int) o->value(); +} +void ADnoteUI::cb_pt(WidgetPDial* o, void* v) { + ((ADnoteUI*)(o->parent()->parent()->user_data()))->cb_pt_i(o,v); +} + +void ADnoteUI::cb_pstc_i(WidgetPDial* o, void*) { + pars->GlobalPar.PPunchStretch=(int) o->value(); +} +void ADnoteUI::cb_pstc(WidgetPDial* o, void* v) { + ((ADnoteUI*)(o->parent()->parent()->user_data()))->cb_pstc_i(o,v); +} + +void ADnoteUI::cb_pvel_i(WidgetPDial* o, void*) { + pars->GlobalPar.PPunchVelocitySensing=(int) o->value(); +} +void ADnoteUI::cb_pvel(WidgetPDial* o, void* v) { + ((ADnoteUI*)(o->parent()->parent()->user_data()))->cb_pvel_i(o,v); +} + +void ADnoteUI::cb_rndgrp_i(Fl_Check_Button* o, void*) { + pars->GlobalPar.Hrandgrouping=(int) o->value(); +} +void ADnoteUI::cb_rndgrp(Fl_Check_Button* o, void* v) { + ((ADnoteUI*)(o->parent()->parent()->user_data()))->cb_rndgrp_i(o,v); +} + +void ADnoteUI::cb_stereo_i(Fl_Check_Button* o, void*) { + pars->GlobalPar.PStereo=(int) o->value(); +} +void ADnoteUI::cb_stereo(Fl_Check_Button* o, void* v) { + ((ADnoteUI*)(o->parent()->user_data()))->cb_stereo_i(o,v); +} + +void ADnoteUI::cb_Show_i(Fl_Button*, void*) { + for (int i=0;irefreshlist(); +} +ADnoteVoiceList->show(); +} +void ADnoteUI::cb_Show(Fl_Button* o, void* v) { + ((ADnoteUI*)(o->parent()->user_data()))->cb_Show_i(o,v); +} + +void ADnoteUI::cb_Show1_i(Fl_Button*, void*) { + ADnoteVoice->show(); +} +void ADnoteUI::cb_Show1(Fl_Button* o, void* v) { + ((ADnoteUI*)(o->parent()->user_data()))->cb_Show1_i(o,v); +} + +void ADnoteUI::cb_Close_i(Fl_Button*, void*) { + ADnoteGlobalParameters->hide(); +} +void ADnoteUI::cb_Close(Fl_Button* o, void* v) { + ((ADnoteUI*)(o->parent()->user_data()))->cb_Close_i(o,v); +} + +void ADnoteUI::cb_Resonance_i(Fl_Button*, void*) { + resui->resonancewindow->redraw(); +resui->resonancewindow->show(); +} +void ADnoteUI::cb_Resonance(Fl_Button* o, void* v) { + ((ADnoteUI*)(o->parent()->user_data()))->cb_Resonance_i(o,v); +} + +void ADnoteUI::cb_C_i(Fl_Button*, void*) { + presetsui->copy(pars); +} +void ADnoteUI::cb_C(Fl_Button* o, void* v) { + ((ADnoteUI*)(o->parent()->user_data()))->cb_C_i(o,v); +} + +void ADnoteUI::cb_P_i(Fl_Button*, void*) { + presetsui->paste(pars,this); +} +void ADnoteUI::cb_P(Fl_Button* o, void* v) { + ((ADnoteUI*)(o->parent()->user_data()))->cb_P_i(o,v); +} + +void ADnoteUI::cb_Close1_i(Fl_Button*, void*) { + ADnoteVoice->hide(); +} +void ADnoteUI::cb_Close1(Fl_Button* o, void* v) { + ((ADnoteUI*)(o->parent()->user_data()))->cb_Close1_i(o,v); +} + +void ADnoteUI::cb_currentvoicecounter_i(Fl_Counter* o, void*) { + nvoice=(int)o->value()-1; +advoice->hide(); +ADnoteVoice->remove(advoice); +delete advoice; +advoice=new ADvoiceUI(0,0,765,525); +ADnoteVoice->add(advoice); +advoice->init(pars,nvoice,master); +advoice->show(); +ADnoteVoice->redraw(); +} +void ADnoteUI::cb_currentvoicecounter(Fl_Counter* o, void* v) { + ((ADnoteUI*)(o->parent()->user_data()))->cb_currentvoicecounter_i(o,v); +} + +void ADnoteUI::cb_C1_i(Fl_Button*, void*) { + presetsui->copy(pars,nvoice); +} +void ADnoteUI::cb_C1(Fl_Button* o, void* v) { + ((ADnoteUI*)(o->parent()->user_data()))->cb_C1_i(o,v); +} + +void ADnoteUI::cb_P1_i(Fl_Button*, void*) { + presetsui->paste(pars,this,nvoice); +} +void ADnoteUI::cb_P1(Fl_Button* o, void* v) { + ((ADnoteUI*)(o->parent()->user_data()))->cb_P1_i(o,v); +} + +void ADnoteUI::cb_Hide_i(Fl_Button*, void*) { + ADnoteVoiceList->hide(); +} +void ADnoteUI::cb_Hide(Fl_Button* o, void* v) { + ((ADnoteUI*)(o->parent()->user_data()))->cb_Hide_i(o,v); +} + +Fl_Double_Window* ADnoteUI::make_window() { + { ADnoteGlobalParameters = new Fl_Double_Window(535, 405, "ADsynth Global Parameters of the Instrument"); + ADnoteGlobalParameters->user_data((void*)(this)); + { Fl_Group* o = new Fl_Group(5, 255, 525, 115, "FREQUENCY"); + o->box(FL_THIN_UP_BOX); + o->labeltype(FL_EMBOSSED_LABEL); + o->labelfont(1); + o->labelsize(13); + o->align(FL_ALIGN_TOP|FL_ALIGN_INSIDE); + { EnvelopeUI* o = freqenv = new EnvelopeUI(10, 295, 205, 70, "ADSynth Global - Frequency Envelope"); + freqenv->box(FL_FLAT_BOX); + freqenv->color((Fl_Color)51); + freqenv->selection_color(FL_BACKGROUND_COLOR); + freqenv->labeltype(FL_NORMAL_LABEL); + freqenv->labelfont(0); + freqenv->labelsize(14); + freqenv->labelcolor(FL_FOREGROUND_COLOR); + freqenv->align(FL_ALIGN_WRAP|FL_ALIGN_INSIDE); + freqenv->when(FL_WHEN_RELEASE); + o->init(pars->GlobalPar.FreqEnvelope); + freqenv->end(); + } // EnvelopeUI* freqenv + { Fl_Counter* o = octave = new Fl_Counter(450, 275, 45, 15, "Octave"); + octave->tooltip("Octave"); + octave->type(1); + octave->labelsize(10); + octave->minimum(-8); + octave->maximum(7); + octave->step(1); + octave->textfont(1); + octave->textsize(11); + octave->callback((Fl_Callback*)cb_octave); + octave->align(FL_ALIGN_TOP); + int k=pars->GlobalPar.PCoarseDetune/1024;if (k>=8) k-=16; + o->value(k); + } // Fl_Counter* octave + { Fl_Counter* o = coarsedet = new Fl_Counter(455, 345, 60, 20, "Coarse det."); + coarsedet->tooltip("Coarse Detune"); + coarsedet->labelsize(10); + coarsedet->minimum(-64); + coarsedet->maximum(63); + coarsedet->step(1); + coarsedet->textfont(1); + coarsedet->textsize(11); + coarsedet->callback((Fl_Callback*)cb_coarsedet); + coarsedet->align(FL_ALIGN_TOP_LEFT); + int k=pars->GlobalPar.PCoarseDetune%1024;if (k>=512) k-=1024; + o->value(k); + o->lstep(10); + } // Fl_Counter* coarsedet + { LFOUI* o = freqlfo = new LFOUI(215, 295, 230, 70, "Frequency LFO "); + freqlfo->box(FL_FLAT_BOX); + freqlfo->color(FL_DARK1); + freqlfo->selection_color(FL_BACKGROUND_COLOR); + freqlfo->labeltype(FL_NORMAL_LABEL); + freqlfo->labelfont(0); + freqlfo->labelsize(14); + freqlfo->labelcolor(FL_FOREGROUND_COLOR); + freqlfo->align(FL_ALIGN_WRAP|FL_ALIGN_INSIDE); + freqlfo->when(FL_WHEN_RELEASE); + o->init(pars->GlobalPar.FreqLfo); + freqlfo->end(); + } // LFOUI* freqlfo + { Fl_Slider* o = freq = new Fl_Slider(60, 275, 385, 15); + freq->tooltip("Fine Detune (cents)"); + freq->type(5); + freq->box(FL_FLAT_BOX); + freq->minimum(-8192); + freq->maximum(8191); + freq->step(1); + freq->callback((Fl_Callback*)cb_freq); + o->value(pars->GlobalPar.PDetune-8192); + } // Fl_Slider* freq + { Fl_Value_Output* o = detunevalueoutput = new Fl_Value_Output(12, 275, 45, 15, "Detune"); + detunevalueoutput->labelsize(10); + detunevalueoutput->minimum(-5000); + detunevalueoutput->maximum(5000); + detunevalueoutput->step(0.01); + detunevalueoutput->textfont(1); + detunevalueoutput->textsize(10); + detunevalueoutput->callback((Fl_Callback*)cb_detunevalueoutput2); + detunevalueoutput->align(FL_ALIGN_TOP_LEFT); + o->value(getdetune(pars->GlobalPar.PDetuneType,0,pars->GlobalPar.PDetune)); + } // Fl_Value_Output* detunevalueoutput + { Fl_Choice* o = detunetype = new Fl_Choice(450, 315, 75, 15, "Detune Type"); + detunetype->down_box(FL_BORDER_BOX); + detunetype->labelsize(10); + detunetype->textfont(1); + detunetype->textsize(10); + detunetype->callback((Fl_Callback*)cb_detunetype); + detunetype->align(FL_ALIGN_TOP_LEFT); + o->add("L35cents");o->add("L10cents");o->add("E100cents");o->add("E1200cents"); + o->value(pars->GlobalPar.PDetuneType-1); + } // Fl_Choice* detunetype + { WidgetPDial* o = new WidgetPDial(500, 270, 25, 25, "relBW"); + o->tooltip("Bandwidth - how the relative fine detune of the voice are changed"); + o->box(FL_ROUND_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_INACTIVE_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(10); + o->labelcolor(FL_FOREGROUND_COLOR); + o->maximum(127); + o->step(1); + o->callback((Fl_Callback*)cb_relBW); + o->align(FL_ALIGN_TOP); + o->when(FL_WHEN_CHANGED); + o->value(pars->GlobalPar.PBandwidth); + } // WidgetPDial* o + o->end(); + } // Fl_Group* o + { Fl_Group* o = new Fl_Group(5, 5, 240, 250, "AMPLITUDE"); + o->box(FL_THIN_UP_FRAME); + o->labeltype(FL_EMBOSSED_LABEL); + o->labelfont(1); + o->labelsize(13); + o->align(FL_ALIGN_TOP|FL_ALIGN_INSIDE); + { Fl_Value_Slider* o = volume = new Fl_Value_Slider(10, 30, 160, 15, "Vol"); + volume->tooltip("Volume"); + volume->type(5); + volume->box(FL_FLAT_BOX); + volume->labelsize(11); + volume->maximum(127); + volume->step(1); + volume->callback((Fl_Callback*)cb_volume); + volume->align(FL_ALIGN_RIGHT); + o->value(pars->GlobalPar.PVolume); + } // Fl_Value_Slider* volume + { Fl_Value_Slider* o = vsns = new Fl_Value_Slider(10, 50, 160, 15, "V.Sns"); + vsns->tooltip("Velocity Sensing Function (rightmost to disable)"); + vsns->type(5); + vsns->box(FL_FLAT_BOX); + vsns->labelsize(11); + vsns->maximum(127); + vsns->step(1); + vsns->callback((Fl_Callback*)cb_vsns); + vsns->align(FL_ALIGN_RIGHT); + o->value(pars->GlobalPar.PAmpVelocityScaleFunction); + } // Fl_Value_Slider* vsns + { WidgetPDial* o = pan = new WidgetPDial(210, 25, 30, 30, "Pan"); + pan->tooltip("Panning (leftmost is Random)"); + pan->box(FL_ROUND_UP_BOX); + pan->color(FL_BACKGROUND_COLOR); + pan->selection_color(FL_INACTIVE_COLOR); + pan->labeltype(FL_NORMAL_LABEL); + pan->labelfont(0); + pan->labelsize(10); + pan->labelcolor(FL_FOREGROUND_COLOR); + pan->maximum(127); + pan->step(1); + pan->callback((Fl_Callback*)cb_pan); + pan->align(FL_ALIGN_BOTTOM); + pan->when(FL_WHEN_CHANGED); + o->value(pars->GlobalPar.PPanning); + } // WidgetPDial* pan + { WidgetPDial* o = pstr = new WidgetPDial(125, 227, 25, 25, "P.Str."); + pstr->tooltip("Punch Strength"); + pstr->box(FL_ROUND_UP_BOX); + pstr->color(FL_BACKGROUND_COLOR); + pstr->selection_color(FL_INACTIVE_COLOR); + pstr->labeltype(FL_NORMAL_LABEL); + pstr->labelfont(0); + pstr->labelsize(10); + pstr->labelcolor(FL_FOREGROUND_COLOR); + pstr->maximum(127); + pstr->step(1); + pstr->callback((Fl_Callback*)cb_pstr); + pstr->align(FL_ALIGN_TOP); + pstr->when(FL_WHEN_CHANGED); + o->value(pars->GlobalPar.PPunchStrength); + } // WidgetPDial* pstr + { WidgetPDial* o = pt = new WidgetPDial(155, 227, 25, 25, "P.t."); + pt->tooltip("Punch Time (duration)"); + pt->box(FL_ROUND_UP_BOX); + pt->color(FL_BACKGROUND_COLOR); + pt->selection_color(FL_INACTIVE_COLOR); + pt->labeltype(FL_NORMAL_LABEL); + pt->labelfont(0); + pt->labelsize(10); + pt->labelcolor(FL_FOREGROUND_COLOR); + pt->maximum(127); + pt->step(1); + pt->callback((Fl_Callback*)cb_pt); + pt->align(FL_ALIGN_TOP); + pt->when(FL_WHEN_CHANGED); + o->value(pars->GlobalPar.PPunchTime); + } // WidgetPDial* pt + { WidgetPDial* o = pstc = new WidgetPDial(185, 227, 25, 25, "P.Stc."); + pstc->tooltip("Punch Stretch"); + pstc->box(FL_ROUND_UP_BOX); + pstc->color(FL_BACKGROUND_COLOR); + pstc->selection_color(FL_INACTIVE_COLOR); + pstc->labeltype(FL_NORMAL_LABEL); + pstc->labelfont(0); + pstc->labelsize(10); + pstc->labelcolor(FL_FOREGROUND_COLOR); + pstc->maximum(127); + pstc->step(1); + pstc->callback((Fl_Callback*)cb_pstc); + pstc->align(FL_ALIGN_TOP); + pstc->when(FL_WHEN_CHANGED); + o->value(pars->GlobalPar.PPunchStretch); + } // WidgetPDial* pstc + { WidgetPDial* o = pvel = new WidgetPDial(215, 227, 25, 25, "P.Vel."); + pvel->tooltip("Punch Velocity Sensing"); + pvel->box(FL_ROUND_UP_BOX); + pvel->color(FL_BACKGROUND_COLOR); + pvel->selection_color(FL_INACTIVE_COLOR); + pvel->labeltype(FL_NORMAL_LABEL); + pvel->labelfont(0); + pvel->labelsize(10); + pvel->labelcolor(FL_FOREGROUND_COLOR); + pvel->maximum(127); + pvel->step(1); + pvel->callback((Fl_Callback*)cb_pvel); + pvel->align(FL_ALIGN_TOP); + pvel->when(FL_WHEN_CHANGED); + o->value(pars->GlobalPar.PPunchVelocitySensing); + } // WidgetPDial* pvel + { EnvelopeUI* o = ampenv = new EnvelopeUI(10, 75, 205, 70, "ADSynth Global - Amplitude Envelope"); + ampenv->box(FL_FLAT_BOX); + ampenv->color((Fl_Color)51); + ampenv->selection_color(FL_BACKGROUND_COLOR); + ampenv->labeltype(FL_NORMAL_LABEL); + ampenv->labelfont(0); + ampenv->labelsize(14); + ampenv->labelcolor(FL_FOREGROUND_COLOR); + ampenv->align(FL_ALIGN_WRAP|FL_ALIGN_INSIDE); + ampenv->when(FL_WHEN_RELEASE); + o->init(pars->GlobalPar.AmpEnvelope); + ampenv->end(); + } // EnvelopeUI* ampenv + { LFOUI* o = amplfo = new LFOUI(10, 145, 230, 70, "Amplitude LFO "); + amplfo->box(FL_FLAT_BOX); + amplfo->color(FL_DARK1); + amplfo->selection_color(FL_BACKGROUND_COLOR); + amplfo->labeltype(FL_NORMAL_LABEL); + amplfo->labelfont(0); + amplfo->labelsize(14); + amplfo->labelcolor(FL_FOREGROUND_COLOR); + amplfo->align(FL_ALIGN_WRAP|FL_ALIGN_INSIDE); + amplfo->when(FL_WHEN_RELEASE); + o->init(pars->GlobalPar.AmpLfo); + amplfo->end(); + } // LFOUI* amplfo + { Fl_Check_Button* o = rndgrp = new Fl_Check_Button(70, 225, 40, 25, "Rnd Grp"); + rndgrp->tooltip("How the Harmonic Amplitude is applied to voices that use the same oscillator"); + rndgrp->down_box(FL_DOWN_BOX); + rndgrp->labelsize(10); + rndgrp->callback((Fl_Callback*)cb_rndgrp); + rndgrp->align(132|FL_ALIGN_INSIDE); + o->value(pars->GlobalPar.Hrandgrouping); + } // Fl_Check_Button* rndgrp + o->end(); + } // Fl_Group* o + { Fl_Group* o = new Fl_Group(245, 5, 285, 250, "FILTER"); + o->box(FL_THIN_UP_BOX); + o->labeltype(FL_EMBOSSED_LABEL); + o->labelfont(1); + o->labelsize(13); + o->align(FL_ALIGN_TOP|FL_ALIGN_INSIDE); + { EnvelopeUI* o = filterenv = new EnvelopeUI(250, 110, 275, 70, "ADSynth Global - Filter Envelope"); + filterenv->box(FL_FLAT_BOX); + filterenv->color((Fl_Color)51); + filterenv->selection_color(FL_BACKGROUND_COLOR); + filterenv->labeltype(FL_NORMAL_LABEL); + filterenv->labelfont(0); + filterenv->labelsize(14); + filterenv->labelcolor(FL_FOREGROUND_COLOR); + filterenv->align(FL_ALIGN_WRAP|FL_ALIGN_INSIDE); + filterenv->when(FL_WHEN_RELEASE); + o->init(pars->GlobalPar.FilterEnvelope); + filterenv->end(); + } // EnvelopeUI* filterenv + { LFOUI* o = filterlfo = new LFOUI(250, 180, 230, 70, "Filter LFO"); + filterlfo->box(FL_FLAT_BOX); + filterlfo->color(FL_DARK1); + filterlfo->selection_color(FL_BACKGROUND_COLOR); + filterlfo->labeltype(FL_NORMAL_LABEL); + filterlfo->labelfont(0); + filterlfo->labelsize(14); + filterlfo->labelcolor(FL_FOREGROUND_COLOR); + filterlfo->align(FL_ALIGN_WRAP|FL_ALIGN_INSIDE); + filterlfo->when(FL_WHEN_RELEASE); + o->init(pars->GlobalPar.FilterLfo); + filterlfo->end(); + } // LFOUI* filterlfo + { FilterUI* o = filterui = new FilterUI(250, 35, 275, 75, "ADsynth Global - Filter"); + filterui->box(FL_FLAT_BOX); + filterui->color(FL_LIGHT1); + filterui->selection_color(FL_BACKGROUND_COLOR); + filterui->labeltype(FL_NORMAL_LABEL); + filterui->labelfont(0); + filterui->labelsize(14); + filterui->labelcolor(FL_FOREGROUND_COLOR); + filterui->align(FL_ALIGN_WRAP|FL_ALIGN_INSIDE); + filterui->when(FL_WHEN_RELEASE); + o->init(pars->GlobalPar.GlobalFilter,&pars->GlobalPar.PFilterVelocityScale,&pars->GlobalPar.PFilterVelocityScaleFunction); + filterui->end(); + } // FilterUI* filterui + o->end(); + } // Fl_Group* o + { Fl_Check_Button* o = stereo = new Fl_Check_Button(5, 220, 65, 35, "Stereo"); + stereo->box(FL_ENGRAVED_BOX); + stereo->down_box(FL_DOWN_BOX); + stereo->labelfont(1); + stereo->labelsize(11); + stereo->callback((Fl_Callback*)cb_stereo); + o->value(pars->GlobalPar.PStereo); + } // Fl_Check_Button* stereo + { Fl_Button* o = new Fl_Button(180, 375, 125, 25, "Show Voice List"); + o->callback((Fl_Callback*)cb_Show); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(5, 375, 170, 25, "Show Voice Parameters"); + o->labelfont(1); + o->labelsize(12); + o->callback((Fl_Callback*)cb_Show1); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(470, 375, 60, 25, "Close"); + o->box(FL_THIN_UP_BOX); + o->callback((Fl_Callback*)cb_Close); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(309, 375, 86, 25, "Resonance"); + o->tooltip("Resonance"); + o->box(FL_THIN_UP_BOX); + o->callback((Fl_Callback*)cb_Resonance); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(405, 380, 25, 15, "C"); + o->box(FL_THIN_UP_BOX); + o->color((Fl_Color)179); + o->labelfont(1); + o->labelsize(11); + o->labelcolor(FL_BACKGROUND2_COLOR); + o->callback((Fl_Callback*)cb_C); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(435, 380, 25, 15, "P"); + o->box(FL_THIN_UP_BOX); + o->color((Fl_Color)179); + o->labelfont(1); + o->labelsize(11); + o->labelcolor(FL_BACKGROUND2_COLOR); + o->callback((Fl_Callback*)cb_P); + } // Fl_Button* o + ADnoteGlobalParameters->end(); + } // Fl_Double_Window* ADnoteGlobalParameters + { ADnoteVoice = new Fl_Double_Window(765, 560, "ADsynth Voice Parameters"); + ADnoteVoice->user_data((void*)(this)); + { ADvoiceUI* o = advoice = new ADvoiceUI(0, 0, 760, 525); + advoice->box(FL_BORDER_BOX); + advoice->color(FL_BACKGROUND_COLOR); + advoice->selection_color(FL_BACKGROUND_COLOR); + advoice->labeltype(FL_NORMAL_LABEL); + advoice->labelfont(0); + advoice->labelsize(14); + advoice->labelcolor(FL_FOREGROUND_COLOR); + advoice->align(FL_ALIGN_TOP); + advoice->when(FL_WHEN_RELEASE); + o->init(pars,nvoice,master); + o->show(); + advoice->end(); + } // ADvoiceUI* advoice + { Fl_Button* o = new Fl_Button(300, 530, 195, 25, "Close Window"); + o->box(FL_THIN_UP_BOX); + o->labelfont(1); + o->callback((Fl_Callback*)cb_Close1); + } // Fl_Button* o + { Fl_Counter* o = currentvoicecounter = new Fl_Counter(5, 530, 130, 25, "Current Voice"); + currentvoicecounter->type(1); + currentvoicecounter->labelfont(1); + currentvoicecounter->minimum(0); + currentvoicecounter->maximum(2); + currentvoicecounter->step(1); + currentvoicecounter->value(1); + currentvoicecounter->textfont(1); + currentvoicecounter->textsize(13); + currentvoicecounter->callback((Fl_Callback*)cb_currentvoicecounter); + currentvoicecounter->align(FL_ALIGN_RIGHT); + o->bounds(1,NUM_VOICES); + } // Fl_Counter* currentvoicecounter + { Fl_Button* o = new Fl_Button(700, 535, 25, 15, "C"); + o->box(FL_THIN_UP_BOX); + o->color((Fl_Color)179); + o->labelfont(1); + o->labelsize(11); + o->labelcolor(FL_BACKGROUND2_COLOR); + o->callback((Fl_Callback*)cb_C1); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(730, 535, 25, 15, "P"); + o->box(FL_THIN_UP_BOX); + o->color((Fl_Color)179); + o->labelfont(1); + o->labelsize(11); + o->labelcolor(FL_BACKGROUND2_COLOR); + o->callback((Fl_Callback*)cb_P1); + } // Fl_Button* o + ADnoteVoice->end(); + } // Fl_Double_Window* ADnoteVoice + { ADnoteVoiceList = new Fl_Double_Window(650, 260, "ADsynth Voices list"); + ADnoteVoiceList->user_data((void*)(this)); + { Fl_Text_Display* o = new Fl_Text_Display(10, 15, 30, 10, "No."); + o->box(FL_NO_BOX); + o->labelfont(1); + o->labelsize(11); + } // Fl_Text_Display* o + { Fl_Text_Display* o = new Fl_Text_Display(145, 15, 30, 10, "Vol"); + o->box(FL_NO_BOX); + o->labelfont(1); + o->labelsize(11); + } // Fl_Text_Display* o + { Fl_Text_Display* o = new Fl_Text_Display(384, 15, 25, 10, "Detune"); + o->box(FL_NO_BOX); + o->labelfont(1); + o->labelsize(11); + } // Fl_Text_Display* o + { Fl_Text_Display* o = new Fl_Text_Display(210, 15, 30, 10, "Pan"); + o->box(FL_NO_BOX); + o->labelfont(1); + o->labelsize(11); + } // Fl_Text_Display* o + { Fl_Text_Display* o = new Fl_Text_Display(560, 15, 30, 10, "Vib. Depth"); + o->box(FL_NO_BOX); + o->labelfont(1); + o->labelsize(11); + } // Fl_Text_Display* o + { Fl_Text_Display* o = new Fl_Text_Display(245, 15, 25, 10, "R."); + o->box(FL_NO_BOX); + o->labelfont(1); + o->labelsize(11); + } // Fl_Text_Display* o + { Fl_Button* o = new Fl_Button(255, 237, 125, 20, "Hide Voice List"); + o->callback((Fl_Callback*)cb_Hide); + } // Fl_Button* o + { Fl_Scroll* o = new Fl_Scroll(0, 15, 640, 220); + o->type(2); + o->box(FL_THIN_UP_BOX); + { Fl_Pack* o = new Fl_Pack(0, 20, 620, 210); + for (int i=0;iinit(pars,i,master);} + o->end(); + } // Fl_Pack* o + o->end(); + } // Fl_Scroll* o + ADnoteVoiceList->end(); + } // Fl_Double_Window* ADnoteVoiceList + return ADnoteVoiceList; +} + +ADnoteUI::ADnoteUI(ADnoteParameters *parameters,Master *master_) { + pars=parameters; +master=master_; +nvoice=0; +resui=new ResonanceUI(pars->GlobalPar.Reson); +make_window(); +} + +ADnoteUI::~ADnoteUI() { + ADnoteVoiceList->hide(); +ADnoteGlobalParameters->hide(); +ADnoteVoice->hide(); +delete(ADnoteVoiceList); +delete(ADnoteGlobalParameters); +delete(ADnoteVoice); +delete(resui); +} + +void ADnoteUI::refresh() { + volume->value(pars->GlobalPar.PVolume); +vsns->value(pars->GlobalPar.PAmpVelocityScaleFunction); +pan->value(pars->GlobalPar.PPanning); + +stereo->value(pars->GlobalPar.PStereo); +rndgrp->value(pars->GlobalPar.Hrandgrouping); + +pstr->value(pars->GlobalPar.PPunchStrength); +pt->value(pars->GlobalPar.PPunchTime); +pstc->value(pars->GlobalPar.PPunchStretch); +pvel->value(pars->GlobalPar.PPunchVelocitySensing); + +detunevalueoutput->value(getdetune(pars->GlobalPar.PDetuneType,0,pars->GlobalPar.PDetune)); +freq->value(pars->GlobalPar.PDetune-8192); + +int k=pars->GlobalPar.PCoarseDetune/1024;if (k>=8) k-=16; +octave->value(k); + +detunetype->value(pars->GlobalPar.PDetuneType-1); +k=pars->GlobalPar.PCoarseDetune%1024;if (k>=512) k-=1024; +coarsedet->value(k); +amplfo->refresh(); +freqlfo->refresh(); +filterlfo->refresh(); + +ampenv->refresh(); +freqenv->refresh(); +filterenv->refresh(); +filterui->refresh(); + +for (int i=0;irefreshlist(); + +resui->refresh(); +currentvoicecounter->do_callback(); +} diff --git a/plugins/zynaddsubfx/src/UI/ADnoteUI.fl b/plugins/zynaddsubfx/src/UI/ADnoteUI.fl new file mode 100644 index 000000000..4888eaea4 --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/ADnoteUI.fl @@ -0,0 +1,1108 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0107 +header_name {.h} +code_name {.cc} +decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} + +decl {//License: GNU GPL version 2 or later} {} + +decl {\#include "../Params/ADnoteParameters.h"} {public +} + +decl {\#include "../Misc/Util.h"} {public +} + +decl {\#include "../Misc/Master.h"} {public +} + +decl {\#include "ResonanceUI.h"} {public +} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include } {} + +decl {\#include } {} + +decl {\#include } {} + +decl {\#include } {} + +decl {\#include "WidgetPDial.h"} {public +} + +decl {\#include "EnvelopeUI.h"} {public +} + +decl {\#include "LFOUI.h"} {public +} + +decl {\#include "FilterUI.h"} {public +} + +decl {\#include "OscilGenUI.h"} {public +} + +decl {\#include "PresetsUI.h"} {public +} + +class ADvoicelistitem {: {public Fl_Group} +} { + Function {make_window()} {private + } { + Fl_Window ADnoteVoiceListItem { + private xywh {247 599 615 30} type Double hide + class Fl_Group + } { + Fl_Group voicelistitemgroup { + private xywh {50 0 570 25} box FLAT_BOX + code0 {if (pars->VoicePar[nvoice].Enabled==0) o->deactivate();} + } { + Fl_Value_Slider voicevolume { + callback {pars->VoicePar[nvoice].PVolume=(int)o->value();} + tooltip Volume xywh {90 5 115 20} type {Horz Knob} box FLAT_BOX labelsize 8 align 5 maximum 127 step 1 + code0 {o->value(pars->VoicePar[nvoice].PVolume);} + } + Fl_Check_Button voiceresonanceenabled { + callback {pars->VoicePar[nvoice].Presonance=(int)o->value();} + tooltip {Resonance On/Off} xywh {245 7 15 17} down_box DOWN_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 11 align 4 + code0 {o->value(pars->VoicePar[nvoice].Presonance);} + } + Fl_Value_Slider voicelfofreq { + callback {pars->VoicePar[nvoice].FreqLfo->Pintensity=(int)o->value();} + tooltip {Frequency LFO amount} xywh {500 5 115 20} type {Horz Knob} box FLAT_BOX labelsize 8 align 5 maximum 127 step 1 + code0 {o->value(pars->VoicePar[nvoice].FreqLfo->Pintensity);} + } + Fl_Dial voicepanning { + callback {pars->VoicePar[nvoice].PPanning=(int) o->value();} + tooltip {Panning (leftmost is Random)} xywh {215 5 20 20} box ROUND_UP_BOX labelsize 10 align 4 maximum 127 step 1 + code0 {o->value(pars->VoicePar[nvoice].PPanning);} + class WidgetPDial + } + Fl_Group voiceoscil {open + xywh {60 5 30 20} box THIN_DOWN_BOX color 32 selection_color 71 labelcolor 179 + code0 {osc=new Oscilloscope(o->x(),o->y(),o->w(),o->h(),"");} + code1 {osc->init(pars->VoicePar[nvoice].OscilSmp,0,pars->VoicePar[nvoice].Poscilphase,master);} + code2 {if (pars->VoicePar[nvoice].Pextoscil != -1) {osc->init(pars->VoicePar[pars->VoicePar[nvoice].Pextoscil].OscilSmp,master);}} + } {} + Fl_Value_Output detunevalueoutput { + callback {o->value(getdetune((pars->VoicePar[nvoice].PDetuneType==0)?(pars->GlobalPar.PDetuneType) : (pars->VoicePar[nvoice].PDetuneType),0,pars->VoicePar[nvoice].PDetune)*pars->getBandwidthDetuneMultiplier());} + xywh {265 5 45 20} labelsize 10 align 5 minimum -5000 maximum 5000 step 0.01 textfont 1 textsize 10 + code0 {o->value(getdetune(pars->VoicePar[nvoice].PDetuneType,0,pars->VoicePar[nvoice].PDetune)*pars->getBandwidthDetuneMultiplier());} + } + Fl_Slider voicedetune { + callback {pars->VoicePar[nvoice].PDetune=(int)o->value()+8192; +detunevalueoutput->do_callback();} + tooltip {Fine Detune (cents)} xywh {315 5 185 20} type {Horz Knob} box FLAT_BOX minimum -8192 maximum 8191 step 1 + code0 {o->value(pars->VoicePar[nvoice].PDetune-8192);} + } + Fl_Box noiselabel { + label N + callback {if (pars->VoicePar[nvoice].Type==0) { + o->hide(); + voiceresonanceenabled->activate(); + detunevalueoutput->activate(); + voicedetune->activate(); + voicelfofreq->activate(); + voiceoscil->activate(); +} else { + o->show(); + voiceresonanceenabled->deactivate(); + detunevalueoutput->deactivate(); + voicedetune->deactivate(); + voicelfofreq->deactivate(); + voiceoscil->deactivate(); +};} + xywh {65 5 20 20} labelfont 1 labelsize 13 labelcolor 7 + code0 {if (pars->VoicePar[nvoice].Type==0) o->hide();} + } + } + Fl_Check_Button voiceenabled { + label 01 + callback {pars->VoicePar[nvoice].Enabled=(int)o->value(); +if (o->value()==0) voicelistitemgroup->deactivate(); +else voicelistitemgroup->activate(); +o->redraw();} + private xywh {30 5 20 20} down_box DOWN_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 13 align 4 + code0 {char tmp[10];snprintf(tmp,10,"%d",nvoice+1);o->label(strdup(tmp));} + code1 {o->value(pars->VoicePar[nvoice].Enabled);} + } + } + } + Function {ADvoicelistitem(int x,int y, int w, int h, const char *label=0):Fl_Group(x,y,w,h,label)} {} { + code {nvoice=0; +pars=NULL;} {} + } + Function {init(ADnoteParameters *parameters,int nvoice_,Master *master_)} {} { + code {pars=parameters; +nvoice=nvoice_; +master=master_; +make_window(); +ADnoteVoiceListItem->show(); +end();} {} + } + Function {refreshlist()} {} { + code {voiceenabled->value(pars->VoicePar[nvoice].Enabled); +voiceresonanceenabled->value(pars->VoicePar[nvoice].Presonance); +voicevolume->value(pars->VoicePar[nvoice].PVolume); +voicedetune->value(pars->VoicePar[nvoice].PDetune-8192); +voicepanning->value(pars->VoicePar[nvoice].PPanning); +voicelfofreq->value(pars->VoicePar[nvoice].FreqLfo->Pintensity); +if (pars->VoicePar[nvoice].Pextoscil != -1) { + osc->init(pars->VoicePar[pars->VoicePar[nvoice].Pextoscil].OscilSmp,0,pars->VoicePar[nvoice].Poscilphase,master); +} else + osc->init(pars->VoicePar[nvoice].OscilSmp,0,pars->VoicePar[nvoice].Poscilphase,master); +if (pars->VoicePar[nvoice].Enabled==0) voicelistitemgroup->deactivate(); + else voicelistitemgroup->activate(); +detunevalueoutput->do_callback(); +noiselabel->do_callback(); +ADnoteVoiceListItem->redraw();} {} + } + Function {~ADvoicelistitem()} {} { + code {ADnoteVoiceListItem->hide(); +//delete(ADnoteVoiceListItem);} {} + } + decl {ADnoteParameters *pars;} {} + decl {int nvoice;} {} + decl {Oscilloscope *osc;} {} + decl {Master *master;} {} +} + +class ADvoiceUI {open : {public Fl_Group} +} { + Function {make_window()} {open + } { + Fl_Window ADnoteVoiceParameters { + label Voice + xywh {225 174 765 525} type Double hide + class Fl_Group + } { + Fl_Group voiceparametersgroup { + xywh {0 0 765 525} box THIN_UP_BOX color 48 + code0 {if (pars->VoicePar[nvoice].Enabled==0) o->deactivate();} + } { + Fl_Group voicemodegroup { + xywh {0 5 760 515} + } { + Fl_Group voiceFMparametersgroup { + label MODULATOR + xywh {530 5 230 515} box THIN_UP_FRAME color 48 labeltype EMBOSSED_LABEL labelfont 1 labelsize 13 align 17 + code0 {if (pars->VoicePar[nvoice].PFMEnabled==0) o->deactivate();} + } { + Fl_Group modfrequency { + label {Mod.FREQUENCY} + xywh {535 220 220 145} box THIN_UP_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 13 align 17 + } { + Fl_Group voiceFMfreqenvgroup { + label {ADSynth Modulator - Frequency Envelope} + xywh {540 290 205 70} box FLAT_BOX color 51 align 144 + code0 {o->init(pars->VoicePar[nvoice].FMFreqEnvelope);} + code1 {if (pars->VoicePar[nvoice].PFMFreqEnvelopeEnabled==0) o->deactivate();} + class EnvelopeUI + } {} + Fl_Check_Button {} { + label Enable + callback {pars->VoicePar[nvoice].PFMFreqEnvelopeEnabled=(int)o->value(); +if (o->value()==0) voiceFMfreqenvgroup->deactivate(); +else voiceFMfreqenvgroup->activate(); +o->redraw();} selected + tooltip {Forced Relase} xywh {545 295 50 10} down_box DOWN_BOX labelfont 1 labelsize 10 + code0 {o->value(pars->VoicePar[nvoice].PFMFreqEnvelopeEnabled);} + } + Fl_Counter {} { + label {Coarse Det.} + callback {int k=(int) o->value(); +if (k<0) k+=1024; +pars->VoicePar[nvoice].PFMCoarseDetune = k+ + (pars->VoicePar[nvoice].PFMCoarseDetune/1024)*1024;} + tooltip {Coarse Detune} xywh {685 270 60 15} labelsize 10 align 1 minimum -64 maximum 63 step 1 textfont 1 textsize 11 + code0 {int k=pars->VoicePar[nvoice].PFMCoarseDetune%1024;} + code1 {if (k>=512) k-=1024;} + code2 {o->value(k);} + code3 {o->lstep(10);} + } + Fl_Counter {} { + label Octave + callback {int k=(int) o->value(); +if (k<0) k+=16; +pars->VoicePar[nvoice].PFMCoarseDetune = k*1024+ + pars->VoicePar[nvoice].PFMCoarseDetune%1024;} + tooltip Octave xywh {625 270 45 15} type Simple labelsize 10 align 1 minimum -8 maximum 7 step 1 textfont 1 textsize 11 + code0 {int k=pars->VoicePar[nvoice].PFMCoarseDetune/1024;} + code1 {if (k>=8) k-=16;} + code2 {o->value(k);} + } + Fl_Slider {} { + callback {pars->VoicePar[nvoice].PFMDetune=(int)o->value()+8192; +fmdetunevalueoutput->do_callback();} + tooltip {Fine Detune (cents)} xywh {590 245 160 10} type {Horz Knob} box FLAT_BOX minimum -8192 maximum 8191 step 1 + code0 {o->value(pars->VoicePar[nvoice].PFMDetune-8192);} + } + Fl_Value_Output fmdetunevalueoutput { + label Detune + callback {o->value(getdetune((pars->VoicePar[nvoice].PFMDetuneType==0)?(pars->GlobalPar.PDetuneType) : (pars->VoicePar[nvoice].PFMDetuneType),0,pars->VoicePar[nvoice].PFMDetune));} + xywh {540 245 45 13} labelsize 8 align 5 minimum -5000 maximum 5000 step 0.01 textfont 1 textsize 8 + code0 {o->value(getdetune((pars->VoicePar[nvoice].PFMDetuneType==0)?(pars->GlobalPar.PDetuneType) : (pars->VoicePar[nvoice].PFMDetuneType),0,pars->VoicePar[nvoice].PFMDetune));} + code1 {//o->value(getdetune(pars->VoicePar[nvoice].PFMDetuneType,0,pars->VoicePar[nvoice].PFMDetune));} + } + Fl_Choice {} { + label {Detune Type} + callback {pars->VoicePar[nvoice].PFMDetuneType=(int) o->value(); +fmdetunevalueoutput->do_callback();} open + xywh {540 270 75 15} down_box BORDER_BOX labelsize 10 align 5 textfont 1 textsize 10 + code0 {o->add("Default");o->add("L35cents");o->add("L10cents");o->add("E100cents");o->add("E1200cents");} + code1 {o->value(pars->VoicePar[nvoice].PFMDetuneType);} + } {} + } + Fl_Group {} { + label {Mod.AMPLITUDE} + xywh {535 60 220 160} box THIN_UP_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 13 align 17 + } { + Fl_Value_Slider {} { + label Vol + callback {pars->VoicePar[nvoice].PFMVolume=(int)o->value();} + tooltip Volume xywh {540 80 160 15} type {Horz Knob} box FLAT_BOX labelsize 11 align 8 maximum 127 step 1 + code0 {o->value(pars->VoicePar[nvoice].PFMVolume);} + } + Fl_Value_Slider {} { + label {V.Sns} + callback {pars->VoicePar[nvoice].PFMVelocityScaleFunction=(int) o->value();} + tooltip {Velocity Sensing Function (rightmost to disable)} xywh {540 100 160 15} type {Horz Knob} box FLAT_BOX labelsize 11 align 8 maximum 127 step 1 + code0 {o->value(pars->VoicePar[nvoice].PFMVelocityScaleFunction);} + } + Fl_Group voiceFMampenvgroup { + label {ADSynth Modulator - Amplitude Envelope} open + xywh {540 145 205 70} box FLAT_BOX color 51 align 144 + code0 {o->init(pars->VoicePar[nvoice].FMAmpEnvelope);} + code1 {if (pars->VoicePar[nvoice].PFMAmpEnvelopeEnabled==0) o->deactivate();} + class EnvelopeUI + } {} + Fl_Check_Button {} { + label Enable + callback {pars->VoicePar[nvoice].PFMAmpEnvelopeEnabled=(int)o->value(); +if (o->value()==0) voiceFMampenvgroup->deactivate(); +else voiceFMampenvgroup->activate(); +o->redraw();} + tooltip {Forced Relase} xywh {545 150 50 10} down_box DOWN_BOX labelfont 1 labelsize 10 + code0 {o->value(pars->VoicePar[nvoice].PFMAmpEnvelopeEnabled);} + } + Fl_Value_Slider {} { + label {F.Damp} + callback {pars->VoicePar[nvoice].PFMVolumeDamp=(int) o->value()+64;} + tooltip {Modulator Damp at Higher frequency} xywh {540 120 160 15} type {Horz Knob} box FLAT_BOX labelsize 11 align 8 minimum -64 maximum 63 step 1 + code0 {o->value(pars->VoicePar[nvoice].PFMVolumeDamp-64);} + } + } + Fl_Group modoscil { + xywh {535 365 220 150} + } { + Fl_Group fmoscil {open + xywh {535 405 220 110} box THIN_DOWN_BOX color 32 selection_color 71 labelcolor 179 + code0 {oscFM=new Oscilloscope(o->x(),o->y(),o->w(),o->h(),"");} + code1 {int nv=nvoice; if (pars->VoicePar[nvoice].PextFMoscil>=0) nv=pars->VoicePar[nvoice].PextFMoscil;} + code2 {oscFM->init(pars->VoicePar[nv].FMSmp,0,pars->VoicePar[nvoice].PFMoscilphase,master);} + } {} + Fl_Box {} { + label {Mod.Oscillator} + xywh {535 365 155 20} labelfont 1 align 20 + } + Fl_Button changeFMoscilbutton { + label Change + callback {if (oscedit!=NULL) delete(oscedit); + +int nv=nvoice; +if (pars->VoicePar[nvoice].PextFMoscil>=0) nv=pars->VoicePar[nvoice].PextFMoscil; + +oscedit=new OscilEditor(pars->VoicePar[nv].FMSmp,fmoscil,NULL,NULL,master);} + xywh {700 370 55 15} box THIN_UP_BOX labelfont 1 labelsize 11 + code0 {if (pars->VoicePar[nvoice].PextFMoscil>=0) o->labelcolor(FL_BLUE);} + } + Fl_Slider {} { + label Phase + callback {pars->VoicePar[nvoice].PFMoscilphase=64-(int)o->value(); +oscFM->phase=64-(int) o->value(); +fmoscil->redraw();} + xywh {665 395 65 10} type {Horz Knob} box FLAT_BOX labelsize 10 align 5 minimum -64 maximum 63 step 1 + code0 {o->value(64-pars->VoicePar[nvoice].PFMoscilphase);} + } + Fl_Choice {} { + label Use + callback {pars->VoicePar[nvoice].PextFMoscil=(int)o->value()-1; +if ((int) o->value() != 0) { + oscFM->init(pars->VoicePar[(int) o->value()-1].FMSmp,master); + changeFMoscilbutton->labelcolor(FL_BLUE); +} else { + oscFM->init(pars->VoicePar[nvoice].FMSmp,master); + changeFMoscilbutton->labelcolor(FL_BLACK); +}; +voiceFMparametersgroup->redraw();} open + xywh {560 390 75 15} down_box BORDER_BOX labelsize 10 textfont 1 textsize 10 + code0 {o->add("Internal");} + code1 {char tmp[50]; for (int i=0;iadd(tmp);};} + code3 {o->value(pars->VoicePar[nvoice].PextFMoscil+1);} + } {} + } + Fl_Choice {} { + label {External Mod.} + callback {pars->VoicePar[nvoice].PFMVoice=(int)o->value()-1; +if ((int) o->value() != 0) { + modoscil->deactivate(); + modfrequency->deactivate(); +} else { + modoscil->activate(); + modfrequency->activate(); +}; +voiceFMparametersgroup->redraw();} open + xywh {635 40 85 20} down_box BORDER_BOX labelsize 10 align 5 textfont 1 textsize 10 + code0 {o->add("OFF");} + code1 {char tmp[50]; for (int i=0;iadd(tmp);};} + code2 {o->value(pars->VoicePar[nvoice].PFMVoice+1);} + code3 {if ((int) o->value() != 0) {modoscil->deactivate();modfrequency->deactivate();}} + } {} + } + Fl_Choice {} { + label {Type:} + callback {pars->VoicePar[nvoice].PFMEnabled=(int)o->value(); +if (o->value()==0) voiceFMparametersgroup->deactivate(); +else voiceFMparametersgroup->activate(); +o->redraw();} + xywh {535 40 80 20} down_box BORDER_BOX align 5 + code0 {o->value(pars->VoicePar[nvoice].PFMEnabled);} + } { + MenuItem {} { + label OFF + xywh {40 40 100 20} labelfont 1 + } + MenuItem {} { + label MORPH + xywh {50 50 100 20} labelfont 1 + } + MenuItem {} { + label RING + xywh {60 60 100 20} labelfont 1 + } + MenuItem {} { + label PM + xywh {70 70 100 20} labelfont 1 + } + MenuItem {} { + label FM + xywh {80 80 100 20} labelfont 1 + } + MenuItem {} { + label PITCH + xywh {90 90 100 20} labelfont 1 deactivate + } + } + Fl_Group {} { + label FREQUENCY + xywh {5 250 525 120} box THIN_UP_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 13 align 17 + } { + Fl_Group voicefreqenvgroup { + label {ADSynth Voice - Frequency Envelope} open + xywh {10 290 205 70} box FLAT_BOX color 51 align 144 + code0 {o->init(pars->VoicePar[nvoice].FreqEnvelope);} + code1 {if (pars->VoicePar[nvoice].PFreqEnvelopeEnabled==0) o->deactivate();} + class EnvelopeUI + } {} + Fl_Check_Button {} { + label Enable + callback {pars->VoicePar[nvoice].PFreqEnvelopeEnabled=(int)o->value(); +if (o->value()==0) voicefreqenvgroup->deactivate(); +else voicefreqenvgroup->activate(); +o->redraw();} + tooltip {Forced Relase} xywh {15 295 50 10} down_box DOWN_BOX labelfont 1 labelsize 10 + code0 {o->value(pars->VoicePar[nvoice].PFreqEnvelopeEnabled);} + } + Fl_Group voicefreqlfogroup { + label {Frequency LFO } open + xywh {215 290 230 70} box FLAT_BOX color 47 align 144 + code0 {o->init(pars->VoicePar[nvoice].FreqLfo);} + code1 {if (pars->VoicePar[nvoice].PFreqLfoEnabled==0) o->deactivate();} + class LFOUI + } {} + Fl_Check_Button {} { + label Enable + callback {pars->VoicePar[nvoice].PFreqLfoEnabled=(int)o->value(); +if (o->value()==0) voicefreqlfogroup->deactivate(); +else voicefreqlfogroup->activate(); +o->redraw();} + tooltip {Forced Relase} xywh {220 295 55 10} down_box DOWN_BOX labelfont 1 labelsize 10 + code0 {o->value(pars->VoicePar[nvoice].PFreqLfoEnabled);} + } + Fl_Counter {} { + label Octave + callback {int k=(int) o->value(); +if (k<0) k+=16; +pars->VoicePar[nvoice].PCoarseDetune = k*1024+ + pars->VoicePar[nvoice].PCoarseDetune%1024;} + tooltip Octave xywh {470 270 45 15} type Simple labelsize 10 align 1 minimum -8 maximum 7 step 1 textfont 1 textsize 11 + code0 {int k=pars->VoicePar[nvoice].PCoarseDetune/1024;} + code1 {if (k>=8) k-=16;} + code2 {o->value(k);} + } + Fl_Counter {} { + label {Coarse Det.} + callback {int k=(int) o->value(); +if (k<0) k+=1024; +pars->VoicePar[nvoice].PCoarseDetune = k+ + (pars->VoicePar[nvoice].PCoarseDetune/1024)*1024;} + tooltip {Coarse Detune} xywh {455 340 60 20} labelsize 10 align 1 minimum -64 maximum 63 step 1 textfont 1 textsize 11 + code0 {int k=pars->VoicePar[nvoice].PCoarseDetune%1024;} + code1 {if (k>=512) k-=1024;} + code2 {o->value(k);} + code3 {o->lstep(10);} + } + Fl_Slider {} { + callback {pars->VoicePar[nvoice].PDetune=(int)o->value()+8192; +detunevalueoutput->do_callback();} + tooltip {Fine Detune (cents)} xywh {58 272 392 13} type {Horz Knob} box FLAT_BOX minimum -8192 maximum 8191 step 1 + code0 {o->value(pars->VoicePar[nvoice].PDetune-8192);} + } + Fl_Value_Output detunevalueoutput { + label Detune + callback {o->value(getdetune((pars->VoicePar[nvoice].PDetuneType==0)?(pars->GlobalPar.PDetuneType) : (pars->VoicePar[nvoice].PDetuneType),0,pars->VoicePar[nvoice].PDetune)*pars->getBandwidthDetuneMultiplier());} + xywh {10 272 45 15} labelsize 10 align 5 minimum -5000 maximum 5000 step 0.01 textfont 1 textsize 10 + code0 {o->value(getdetune((pars->VoicePar[nvoice].PDetuneType==0)?(pars->GlobalPar.PDetuneType) : (pars->VoicePar[nvoice].PDetuneType),0,pars->VoicePar[nvoice].PDetune)*pars->getBandwidthDetuneMultiplier());} + } + Fl_Check_Button {} { + label 440Hz + callback {int x=(int) o->value(); +pars->VoicePar[nvoice].Pfixedfreq=x; +if (x==0) fixedfreqetdial->deactivate(); + else fixedfreqetdial->activate();} + tooltip {Set the voice base frequency to 440Hz} xywh {345 253 55 15} down_box DOWN_BOX labelfont 1 labelsize 11 + code0 {o->value(pars->VoicePar[nvoice].Pfixedfreq);} + } + Fl_Dial fixedfreqetdial { + label {Eq.T.} + callback {pars->VoicePar[nvoice].PfixedfreqET=(int) o->value();} + tooltip {How the frequency varies acording to the keyboard (leftmost for fixed frequency)} xywh {405 255 15 15} box ROUND_UP_BOX labelsize 10 align 8 maximum 127 step 1 + code0 {o->value(pars->VoicePar[nvoice].PfixedfreqET);} + code1 {if (pars->VoicePar[nvoice].Pfixedfreq==0) o->deactivate();} + class WidgetPDial + } + Fl_Choice {} { + label {Detune Type} + callback {pars->VoicePar[nvoice].PDetuneType=(int) o->value(); +detunevalueoutput->do_callback();} open + xywh {450 305 75 15} down_box BORDER_BOX labelsize 10 align 5 textfont 1 textsize 10 + code0 {o->add("Default");o->add("L35cents");o->add("L10cents");o->add("E100cents");o->add("E1200cents");} + code1 {o->value(pars->VoicePar[nvoice].PDetuneType);} + } {} + } + Fl_Group voiceoscil { + xywh {80 375 445 145} box THIN_DOWN_BOX color 32 selection_color 71 labelcolor 179 + code0 {osc=new Oscilloscope(o->x(),o->y(),o->w(),o->h(),"");} + code1 {int nv=nvoice; if (pars->VoicePar[nvoice].Pextoscil>=0) nv=pars->VoicePar[nvoice].Pextoscil;} + code2 {osc->init(pars->VoicePar[nv].OscilSmp,0,pars->VoicePar[nvoice].Poscilphase,master);} + } {} + Fl_Button changevoiceoscilbutton { + label Change + callback {if (oscedit!=NULL) delete(oscedit); + +int nv=nvoice; +if (pars->VoicePar[nvoice].Pextoscil>=0) nv=pars->VoicePar[nvoice].Pextoscil; + +oscedit=new OscilEditor(pars->VoicePar[nv].OscilSmp,voiceoscil,NULL,NULL,master);} + xywh {5 475 65 20} box THIN_UP_BOX labelfont 1 labelsize 11 + code0 {if (pars->VoicePar[nvoice].Pextoscil>=0) o->labelcolor(FL_BLUE);} + } + Fl_Box {} { + label {Voice Oscillator} + xywh {5 375 75 35} labelfont 1 labelsize 12 align 128 + } + Fl_Slider {} { + label Phase + callback {pars->VoicePar[nvoice].Poscilphase=64-(int)o->value(); +osc->phase=64-(int) o->value(); +voiceoscil->redraw();} + xywh {10 420 65 10} type {Horz Knob} box FLAT_BOX labelsize 10 align 5 minimum -64 maximum 63 step 1 + code0 {o->value(64-pars->VoicePar[nvoice].Poscilphase);} + } + Fl_Check_Button {} { + label {R.} + callback {pars->VoicePar[nvoice].Presonance=(int) o->value();} + tooltip {Resonance On/Off} xywh {210 5 35 35} box THIN_UP_BOX down_box DOWN_BOX labelfont 1 labelsize 11 + code0 {o->value(pars->VoicePar[nvoice].Presonance);} + } + Fl_Choice {} { + label {Use Oscil.} + callback {pars->VoicePar[nvoice].Pextoscil=(int)o->value()-1; +if ((int) o->value() != 0) { + osc->init(pars->VoicePar[(int) o->value()-1].OscilSmp,master); + changevoiceoscilbutton->labelcolor(FL_BLUE); +} else { + osc->init(pars->VoicePar[nvoice].OscilSmp,master); + changevoiceoscilbutton->labelcolor(FL_BLACK); +}; + +voiceparametersgroup->redraw(); +voiceonbutton->redraw();} open + xywh {5 455 65 15} down_box BORDER_BOX labelsize 10 align 5 textfont 1 textsize 10 + code0 {o->add("Internal");} + code1 {char tmp[50]; for (int i=0;iadd(tmp);};} + code3 {o->value(pars->VoicePar[nvoice].Pextoscil+1);} + } {} + } + Fl_Group {} { + label AMPLITUDE + xywh {5 40 240 210} box THIN_UP_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 13 align 17 + } { + Fl_Value_Slider {} { + label Vol + callback {pars->VoicePar[nvoice].PVolume=(int)o->value();} + tooltip Volume xywh {10 60 160 15} type {Horz Knob} box FLAT_BOX labelsize 11 align 8 maximum 127 step 1 + code0 {o->value(pars->VoicePar[nvoice].PVolume);} + } + Fl_Value_Slider {} { + label {V.Sns} + callback {pars->VoicePar[nvoice].PAmpVelocityScaleFunction=(int) o->value();} + tooltip {Velocity Sensing Function (rightmost to disable)} xywh {10 80 160 15} type {Horz Knob} box FLAT_BOX labelsize 11 align 8 maximum 127 step 1 + code0 {o->value(pars->VoicePar[nvoice].PAmpVelocityScaleFunction);} + } + Fl_Group voiceampenvgroup { + label {ADSynth Voice - Amplitude Envelope} open + xywh {10 105 205 70} box FLAT_BOX color 51 align 144 + code0 {o->init(pars->VoicePar[nvoice].AmpEnvelope);} + code1 {if (pars->VoicePar[nvoice].PAmpEnvelopeEnabled==0) o->deactivate();} + class EnvelopeUI + } {} + Fl_Dial {} { + label Pan + callback {pars->VoicePar[nvoice].PPanning=(int) o->value();} + tooltip {Panning (leftmost is Random)} xywh {210 60 30 30} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + code0 {o->value(pars->VoicePar[nvoice].PPanning);} + class WidgetPDial + } + Fl_Check_Button {} { + label Enable + callback {pars->VoicePar[nvoice].PAmpEnvelopeEnabled=(int)o->value(); +if (o->value()==0) voiceampenvgroup->deactivate(); +else voiceampenvgroup->activate(); +o->redraw();} + tooltip {Forced Relase} xywh {15 110 50 10} down_box DOWN_BOX labelfont 1 labelsize 10 + code0 {o->value(pars->VoicePar[nvoice].PAmpEnvelopeEnabled);} + } + Fl_Group voiceamplfogroup { + label {Amplitude LFO } open + xywh {10 175 230 70} box FLAT_BOX color 47 align 144 + code0 {o->init(pars->VoicePar[nvoice].AmpLfo);} + code1 {if (pars->VoicePar[nvoice].PAmpLfoEnabled==0) o->deactivate();} + class LFOUI + } {} + Fl_Check_Button {} { + label Enable + callback {pars->VoicePar[nvoice].PAmpLfoEnabled=(int)o->value(); +if (o->value()==0) voiceamplfogroup->deactivate(); +else voiceamplfogroup->activate(); +o->redraw();} + tooltip {Forced Relase} xywh {15 180 55 10} down_box DOWN_BOX labelfont 1 labelsize 10 + code0 {o->value(pars->VoicePar[nvoice].PAmpLfoEnabled);} + } + Fl_Check_Button {} { + label Minus + callback {pars->VoicePar[nvoice].PVolumeminus=(int)o->value();} + xywh {10 45 50 10} down_box DOWN_BOX labelfont 1 labelsize 10 + code0 {o->value(pars->VoicePar[nvoice].PVolumeminus);} + } + } + Fl_Group voicefiltergroup { + label FILTER + xywh {245 5 285 245} box THIN_UP_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 13 align 17 + code0 {if (pars->VoicePar[nvoice].PFilterEnabled==0) o->deactivate();} + } { + Fl_Group {} { + label {ADsynth Voice - Filter} open + xywh {250 30 275 75} box FLAT_BOX color 50 align 144 + code0 {o->init(pars->VoicePar[nvoice].VoiceFilter,NULL,NULL);} + class FilterUI + } {} + Fl_Group voicefilterenvgroup { + label {ADSynth Voice - Filter Envelope} open + xywh {250 105 275 70} box FLAT_BOX color 51 align 144 + code0 {o->init(pars->VoicePar[nvoice].FilterEnvelope);} + code1 {if (pars->VoicePar[nvoice].PFilterEnvelopeEnabled==0) o->deactivate();} + class EnvelopeUI + } {} + Fl_Check_Button {} { + label Enable + callback {pars->VoicePar[nvoice].PFilterEnvelopeEnabled=(int)o->value(); +if (o->value()==0) voicefilterenvgroup->deactivate(); +else voicefilterenvgroup->activate(); +o->redraw();} + tooltip {Forced Relase} xywh {255 110 55 10} down_box DOWN_BOX labelfont 1 labelsize 10 + code0 {o->value(pars->VoicePar[nvoice].PFilterEnvelopeEnabled);} + } + Fl_Group voicefilterlfogroup { + label {Filter LFO } open + xywh {250 175 230 70} box FLAT_BOX color 47 align 144 + code0 {o->init(pars->VoicePar[nvoice].FilterLfo);} + code1 {if (pars->VoicePar[nvoice].PFilterLfoEnabled==0) o->deactivate();} + class LFOUI + } {} + Fl_Check_Button {} { + label Enable + callback {pars->VoicePar[nvoice].PFilterLfoEnabled=(int)o->value(); +if (o->value()==0) voicefilterlfogroup->deactivate(); +else voicefilterlfogroup->activate(); +o->redraw();} + tooltip {Forced Relase} xywh {255 180 55 10} down_box DOWN_BOX labelfont 1 labelsize 10 + code0 {o->value(pars->VoicePar[nvoice].PFilterLfoEnabled);} + } + } + Fl_Group {} { + label 01 + xywh {5 5 55 35} box THIN_UP_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 22 align 16 + code0 {char tmp[10];snprintf(tmp,10,"%d",nvoice+1);o->label(strdup(tmp));} + } {} + Fl_Choice {} { + callback {int x=(int) o->value(); +pars->VoicePar[nvoice].Type=x; +if (x==0) voicemodegroup->activate(); + else voicemodegroup->deactivate(); +noiselabel->do_callback();} + tooltip {Oscillator Type (sound/noise)} xywh {5 500 65 20} down_box BORDER_BOX labelsize 10 textfont 1 textsize 10 + code0 {o->value(pars->VoicePar[nvoice].Type);} + code1 {if (pars->VoicePar[nvoice].Type!=0) voicemodegroup->deactivate();} + } { + MenuItem {} { + label Sound + xywh {5 5 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label NOISE + xywh {15 15 100 20} labelfont 1 labelsize 11 labelcolor 1 + } + } + Fl_Check_Button bypassfiltercheckbutton { + label {Bypass Global F.} + callback {pars->VoicePar[nvoice].Pfilterbypass=(int)o->value();} + xywh {425 10 100 20} down_box DOWN_BOX labelfont 1 labelsize 10 align 148 + code0 {o->value(pars->VoicePar[nvoice].Pfilterbypass);} + } + Fl_Group {} { + xywh {115 5 95 35} box THIN_UP_BOX + } { + Fl_Value_Slider {} { + label Delay + callback {pars->VoicePar[nvoice].PDelay=(int)o->value();} + tooltip Volume xywh {120 21 84 12} type {Horz Knob} box FLAT_BOX labelsize 11 align 5 maximum 127 step 1 + code0 {o->value(pars->VoicePar[nvoice].PDelay);} + } + } + Fl_Check_Button {} { + label Enable + callback {pars->VoicePar[nvoice].PFilterEnabled=(int)o->value(); +if (o->value()==0) voicefiltergroup->deactivate(); +else voicefiltergroup->activate(); +o->redraw(); +bypassfiltercheckbutton->redraw();} + tooltip {Enable Filter} xywh {250 15 60 15} down_box DOWN_BOX labelfont 1 labelsize 10 + code0 {o->value(pars->VoicePar[nvoice].PFilterEnabled);} + } + Fl_Box noiselabel { + label {White Noise} + callback {if (pars->VoicePar[nvoice].Type==0) o->hide(); else o->show();} + xywh {150 415 300 65} labelfont 1 labelsize 50 labelcolor 7 + code0 {if (pars->VoicePar[nvoice].Type==0) o->hide(); else o->show();} + } + } + Fl_Check_Button voiceonbutton { + label On + callback {pars->VoicePar[nvoice].Enabled=(int)o->value(); +if (o->value()==0) voiceparametersgroup->deactivate(); +else voiceparametersgroup->activate(); +o->redraw();} + xywh {60 5 55 35} box THIN_UP_BOX down_box DOWN_BOX labelfont 1 labelsize 13 + code0 {o->value(pars->VoicePar[nvoice].Enabled);} + } + } + } + Function {ADvoiceUI(int x,int y, int w, int h, const char *label=0):Fl_Group(x,y,w,h,label)} {} { + code {nvoice=0; +pars=NULL; +oscedit=NULL;} {} + } + Function {init(ADnoteParameters *parameters,int nvoice_,Master *master_)} {} { + code {pars=parameters; +nvoice=nvoice_; +master=master_; +make_window(); +end(); +ADnoteVoiceParameters->show();} {} + } + Function {~ADvoiceUI()} {} { + code {ADnoteVoiceParameters->hide(); +hide(); +if (oscedit!=NULL) { + delete(oscedit); +}; +//delete (ADnoteVoiceParameters);} {} + } + decl {int nvoice;} {} + decl {ADnoteParameters *pars;} {} + decl {OscilEditor *oscedit;} {} + decl {Oscilloscope *osc;} {} + decl {Oscilloscope *oscFM;} {} + decl {Master *master;} {} +} + +class ADnoteUI {: {public PresetsUI_} +} { + Function {make_window()} {open private + } { + Fl_Window ADnoteGlobalParameters { + label {ADsynth Global Parameters of the Instrument} + xywh {462 186 535 405} type Double hide + } { + Fl_Group {} { + label FREQUENCY + xywh {5 255 525 115} box THIN_UP_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 13 align 17 + } { + Fl_Group freqenv { + label {ADSynth Global - Frequency Envelope} open + xywh {10 295 205 70} box FLAT_BOX color 51 align 144 + code0 {o->init(pars->GlobalPar.FreqEnvelope);} + class EnvelopeUI + } {} + Fl_Counter octave { + label Octave + callback {int k=(int) o->value(); +if (k<0) k+=16; +pars->GlobalPar.PCoarseDetune = k*1024+ + pars->GlobalPar.PCoarseDetune%1024;} + tooltip Octave xywh {450 275 45 15} type Simple labelsize 10 align 1 minimum -8 maximum 7 step 1 textfont 1 textsize 11 + code0 {int k=pars->GlobalPar.PCoarseDetune/1024;if (k>=8) k-=16;} + code2 {o->value(k);} + } + Fl_Counter coarsedet { + label {Coarse det.} + callback {int k=(int) o->value(); +if (k<0) k+=1024; +pars->GlobalPar.PCoarseDetune = k+ + (pars->GlobalPar.PCoarseDetune/1024)*1024;} + tooltip {Coarse Detune} xywh {455 345 60 20} labelsize 10 align 5 minimum -64 maximum 63 step 1 textfont 1 textsize 11 + code0 {int k=pars->GlobalPar.PCoarseDetune%1024;if (k>=512) k-=1024;} + code2 {o->value(k);} + code3 {o->lstep(10);} + } + Fl_Group freqlfo { + label {Frequency LFO } open + xywh {215 295 230 70} box FLAT_BOX color 47 align 144 + code0 {o->init(pars->GlobalPar.FreqLfo);} + class LFOUI + } {} + Fl_Slider freq { + callback {pars->GlobalPar.PDetune=(int)o->value()+8192; +detunevalueoutput->do_callback();} + tooltip {Fine Detune (cents)} xywh {60 275 385 15} type {Horz Knob} box FLAT_BOX minimum -8192 maximum 8191 step 1 + code0 {o->value(pars->GlobalPar.PDetune-8192);} + } + Fl_Value_Output detunevalueoutput { + label Detune + callback {o->value(getdetune(pars->GlobalPar.PDetuneType,0,pars->GlobalPar.PDetune));} + xywh {12 275 45 15} labelsize 10 align 5 minimum -5000 maximum 5000 step 0.01 textfont 1 textsize 10 + code0 {o->value(getdetune(pars->GlobalPar.PDetuneType,0,pars->GlobalPar.PDetune));} + } + Fl_Choice detunetype { + label {Detune Type} + callback {pars->GlobalPar.PDetuneType=(int) o->value()+1; +detunevalueoutput->do_callback();} open + xywh {450 315 75 15} down_box BORDER_BOX labelsize 10 align 5 textfont 1 textsize 10 + code0 {o->add("L35cents");o->add("L10cents");o->add("E100cents");o->add("E1200cents");} + code1 {o->value(pars->GlobalPar.PDetuneType-1);} + } {} + Fl_Dial {} { + label relBW + callback {pars->GlobalPar.PBandwidth=(int) o->value(); + +pars->getBandwidthDetuneMultiplier(); + +for (int i=0;irefreshlist(); +};} + tooltip {Bandwidth - how the relative fine detune of the voice are changed} xywh {500 270 25 25} box ROUND_UP_BOX labelsize 10 align 1 maximum 127 step 1 + code0 {o->value(pars->GlobalPar.PBandwidth);} + class WidgetPDial + } + } + Fl_Group {} { + label AMPLITUDE + xywh {5 5 240 250} box THIN_UP_FRAME labeltype EMBOSSED_LABEL labelfont 1 labelsize 13 align 17 + } { + Fl_Value_Slider volume { + label Vol + callback {pars->GlobalPar.PVolume=(int)o->value();} + tooltip Volume xywh {10 30 160 15} type {Horz Knob} box FLAT_BOX labelsize 11 align 8 maximum 127 step 1 + code0 {o->value(pars->GlobalPar.PVolume);} + } + Fl_Value_Slider vsns { + label {V.Sns} + callback {pars->GlobalPar.PAmpVelocityScaleFunction=(int) o->value();} + tooltip {Velocity Sensing Function (rightmost to disable)} xywh {10 50 160 15} type {Horz Knob} box FLAT_BOX labelsize 11 align 8 maximum 127 step 1 + code0 {o->value(pars->GlobalPar.PAmpVelocityScaleFunction);} + } + Fl_Dial pan { + label Pan + callback {pars->GlobalPar.PPanning=(int) o->value();} + tooltip {Panning (leftmost is Random)} xywh {210 25 30 30} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + code0 {o->value(pars->GlobalPar.PPanning);} + class WidgetPDial + } + Fl_Dial pstr { + label {P.Str.} + callback {pars->GlobalPar.PPunchStrength=(int) o->value();} + tooltip {Punch Strength} xywh {125 227 25 25} box ROUND_UP_BOX labelsize 10 align 1 maximum 127 step 1 + code0 {o->value(pars->GlobalPar.PPunchStrength);} + class WidgetPDial + } + Fl_Dial pt { + label {P.t.} + callback {pars->GlobalPar.PPunchTime=(int) o->value();} + tooltip {Punch Time (duration)} xywh {155 227 25 25} box ROUND_UP_BOX labelsize 10 align 1 maximum 127 step 1 + code0 {o->value(pars->GlobalPar.PPunchTime);} + class WidgetPDial + } + Fl_Dial pstc { + label {P.Stc.} + callback {pars->GlobalPar.PPunchStretch=(int) o->value();} + tooltip {Punch Stretch} xywh {185 227 25 25} box ROUND_UP_BOX labelsize 10 align 1 maximum 127 step 1 + code0 {o->value(pars->GlobalPar.PPunchStretch);} + class WidgetPDial + } + Fl_Dial pvel { + label {P.Vel.} + callback {pars->GlobalPar.PPunchVelocitySensing=(int) o->value();} + tooltip {Punch Velocity Sensing} xywh {215 227 25 25} box ROUND_UP_BOX labelsize 10 align 1 maximum 127 step 1 + code0 {o->value(pars->GlobalPar.PPunchVelocitySensing);} + class WidgetPDial + } + Fl_Group ampenv { + label {ADSynth Global - Amplitude Envelope} open + xywh {10 75 205 70} box FLAT_BOX color 51 align 144 + code0 {o->init(pars->GlobalPar.AmpEnvelope);} + class EnvelopeUI + } {} + Fl_Group amplfo { + label {Amplitude LFO } open + xywh {10 145 230 70} box FLAT_BOX color 47 align 144 + code0 {o->init(pars->GlobalPar.AmpLfo);} + class LFOUI + } {} + Fl_Check_Button rndgrp { + label {Rnd Grp} + callback {pars->GlobalPar.Hrandgrouping=(int) o->value();} + tooltip {How the Harmonic Amplitude is applied to voices that use the same oscillator} xywh {70 225 40 25} down_box DOWN_BOX labelsize 10 align 148 + code0 {o->value(pars->GlobalPar.Hrandgrouping);} + } + } + Fl_Group {} { + label FILTER + xywh {245 5 285 250} box THIN_UP_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 13 align 17 + } { + Fl_Group filterenv { + label {ADSynth Global - Filter Envelope} open + xywh {250 110 275 70} box FLAT_BOX color 51 align 144 + code0 {o->init(pars->GlobalPar.FilterEnvelope);} + class EnvelopeUI + } {} + Fl_Group filterlfo { + label {Filter LFO} open + xywh {250 180 230 70} box FLAT_BOX color 47 align 144 + code0 {o->init(pars->GlobalPar.FilterLfo);} + class LFOUI + } {} + Fl_Group filterui { + label {ADsynth Global - Filter} open + xywh {250 35 275 75} box FLAT_BOX color 50 align 144 + code0 {o->init(pars->GlobalPar.GlobalFilter,&pars->GlobalPar.PFilterVelocityScale,&pars->GlobalPar.PFilterVelocityScaleFunction);} + class FilterUI + } {} + } + Fl_Check_Button stereo { + label Stereo + callback {pars->GlobalPar.PStereo=(int) o->value();} + xywh {5 220 65 35} box ENGRAVED_BOX down_box DOWN_BOX labelfont 1 labelsize 11 + code0 {o->value(pars->GlobalPar.PStereo);} + } + Fl_Button {} { + label {Show Voice List} + callback {for (int i=0;irefreshlist(); +} +ADnoteVoiceList->show();} + xywh {180 375 125 25} + } + Fl_Button {} { + label {Show Voice Parameters} + callback {ADnoteVoice->show();} + xywh {5 375 170 25} labelfont 1 labelsize 12 + } + Fl_Button {} { + label Close + callback {ADnoteGlobalParameters->hide();} + xywh {470 375 60 25} box THIN_UP_BOX + } + Fl_Button {} { + label Resonance + callback {resui->resonancewindow->redraw(); +resui->resonancewindow->show();} + tooltip Resonance xywh {309 375 86 25} box THIN_UP_BOX + } + Fl_Button {} { + label C + callback {presetsui->copy(pars);} + xywh {405 380 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 11 labelcolor 7 + } + Fl_Button {} { + label P + callback {presetsui->paste(pars,this);} + xywh {435 380 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 11 labelcolor 7 + } + } + Fl_Window ADnoteVoice { + label {ADsynth Voice Parameters} + xywh {53 58 765 560} type Double hide + } { + Fl_Group advoice { + xywh {0 0 760 525} box BORDER_BOX + code0 {o->init(pars,nvoice,master);} + code1 {o->show();} + class ADvoiceUI + } {} + Fl_Button {} { + label {Close Window} + callback {ADnoteVoice->hide();} + xywh {300 530 195 25} box THIN_UP_BOX labelfont 1 + } + Fl_Counter currentvoicecounter { + label {Current Voice} + callback {nvoice=(int)o->value()-1; +advoice->hide(); +ADnoteVoice->remove(advoice); +delete advoice; +advoice=new ADvoiceUI(0,0,765,525); +ADnoteVoice->add(advoice); +advoice->init(pars,nvoice,master); +advoice->show(); +ADnoteVoice->redraw();} + xywh {5 530 130 25} type Simple labelfont 1 align 8 minimum 0 maximum 2 step 1 value 1 textfont 1 textsize 13 + code0 {o->bounds(1,NUM_VOICES);} + } + Fl_Button {} { + label C + callback {presetsui->copy(pars,nvoice);} + xywh {700 535 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 11 labelcolor 7 + } + Fl_Button {} { + label P + callback {presetsui->paste(pars,this,nvoice);} + xywh {730 535 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 11 labelcolor 7 + } + } + Fl_Window ADnoteVoiceList { + label {ADsynth Voices list} + xywh {32 266 650 260} type Double hide + } { + Fl_Text_Display {} { + label {No.} + xywh {10 15 30 10} box NO_BOX labelfont 1 labelsize 11 + } + Fl_Text_Display {} { + label Vol + xywh {145 15 30 10} box NO_BOX labelfont 1 labelsize 11 + } + Fl_Text_Display {} { + label Detune + xywh {384 15 25 10} box NO_BOX labelfont 1 labelsize 11 + } + Fl_Text_Display {} { + label Pan + xywh {210 15 30 10} box NO_BOX labelfont 1 labelsize 11 + } + Fl_Text_Display {} { + label {Vib. Depth} + xywh {560 15 30 10} box NO_BOX labelfont 1 labelsize 11 + } + Fl_Text_Display {} { + label {R.} + xywh {245 15 25 10} box NO_BOX labelfont 1 labelsize 11 + } + Fl_Button {} { + label {Hide Voice List} + callback {ADnoteVoiceList->hide();} + xywh {255 237 125 20} + } + Fl_Scroll {} {open + xywh {0 15 640 220} type VERTICAL box THIN_UP_BOX + } { + Fl_Pack {} {open + xywh {0 20 620 210} + code0 {for (int i=0;iinit(pars,i,master);}} + } {} + } + } + } + Function {ADnoteUI(ADnoteParameters *parameters,Master *master_)} {} { + code {pars=parameters; +master=master_; +nvoice=0; +resui=new ResonanceUI(pars->GlobalPar.Reson); +make_window();} {} + } + Function {~ADnoteUI()} {} { + code {ADnoteVoiceList->hide(); +ADnoteGlobalParameters->hide(); +ADnoteVoice->hide(); +delete(ADnoteVoiceList); +delete(ADnoteGlobalParameters); +delete(ADnoteVoice); +delete(resui);} {} + } + Function {refresh()} {} { + code {volume->value(pars->GlobalPar.PVolume); +vsns->value(pars->GlobalPar.PAmpVelocityScaleFunction); +pan->value(pars->GlobalPar.PPanning); + +stereo->value(pars->GlobalPar.PStereo); +rndgrp->value(pars->GlobalPar.Hrandgrouping); + +pstr->value(pars->GlobalPar.PPunchStrength); +pt->value(pars->GlobalPar.PPunchTime); +pstc->value(pars->GlobalPar.PPunchStretch); +pvel->value(pars->GlobalPar.PPunchVelocitySensing); + +detunevalueoutput->value(getdetune(pars->GlobalPar.PDetuneType,0,pars->GlobalPar.PDetune)); +freq->value(pars->GlobalPar.PDetune-8192); + +int k=pars->GlobalPar.PCoarseDetune/1024;if (k>=8) k-=16; +octave->value(k); + +detunetype->value(pars->GlobalPar.PDetuneType-1); +k=pars->GlobalPar.PCoarseDetune%1024;if (k>=512) k-=1024; +coarsedet->value(k); +amplfo->refresh(); +freqlfo->refresh(); +filterlfo->refresh(); + +ampenv->refresh(); +freqenv->refresh(); +filterenv->refresh(); +filterui->refresh(); + +for (int i=0;irefreshlist(); + +resui->refresh(); +currentvoicecounter->do_callback();} {} + } + decl {ADnoteParameters *pars;} {} + decl {ResonanceUI *resui;} {} + decl {Master *master;} {} + decl {int nvoice;} {} + decl {ADvoicelistitem *voicelistitem[NUM_VOICES];} {} +} diff --git a/plugins/zynaddsubfx/src/UI/ADnoteUI.h b/plugins/zynaddsubfx/src/UI/ADnoteUI.h new file mode 100644 index 000000000..f41d8ad82 --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/ADnoteUI.h @@ -0,0 +1,370 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0109 + +#ifndef ADnoteUI_h +#define ADnoteUI_h +#include +#include "../Params/ADnoteParameters.h" +#include "../Misc/Util.h" +#include "../Misc/Master.h" +#include "ResonanceUI.h" +#include +#include +#include "WidgetPDial.h" +#include "EnvelopeUI.h" +#include "LFOUI.h" +#include "FilterUI.h" +#include "OscilGenUI.h" +#include "PresetsUI.h" +#include +#include +#include +#include +#include +#include + +class ADvoicelistitem : public Fl_Group { + Fl_Group* make_window(); + Fl_Group *ADnoteVoiceListItem; + Fl_Group *voicelistitemgroup; +public: + Fl_Value_Slider *voicevolume; +private: + void cb_voicevolume_i(Fl_Value_Slider*, void*); + static void cb_voicevolume(Fl_Value_Slider*, void*); +public: + Fl_Check_Button *voiceresonanceenabled; +private: + void cb_voiceresonanceenabled_i(Fl_Check_Button*, void*); + static void cb_voiceresonanceenabled(Fl_Check_Button*, void*); +public: + Fl_Value_Slider *voicelfofreq; +private: + void cb_voicelfofreq_i(Fl_Value_Slider*, void*); + static void cb_voicelfofreq(Fl_Value_Slider*, void*); +public: + WidgetPDial *voicepanning; +private: + void cb_voicepanning_i(WidgetPDial*, void*); + static void cb_voicepanning(WidgetPDial*, void*); +public: + Fl_Group *voiceoscil; + Fl_Value_Output *detunevalueoutput; +private: + void cb_detunevalueoutput_i(Fl_Value_Output*, void*); + static void cb_detunevalueoutput(Fl_Value_Output*, void*); +public: + Fl_Slider *voicedetune; +private: + void cb_voicedetune_i(Fl_Slider*, void*); + static void cb_voicedetune(Fl_Slider*, void*); +public: + Fl_Box *noiselabel; +private: + void cb_noiselabel_i(Fl_Box*, void*); + static void cb_noiselabel(Fl_Box*, void*); + Fl_Check_Button *voiceenabled; + void cb_voiceenabled_i(Fl_Check_Button*, void*); + static void cb_voiceenabled(Fl_Check_Button*, void*); +public: + ADvoicelistitem(int x,int y, int w, int h, const char *label=0); + void init(ADnoteParameters *parameters,int nvoice_,Master *master_); + void refreshlist(); + ~ADvoicelistitem(); +private: + ADnoteParameters *pars; + int nvoice; + Oscilloscope *osc; + Master *master; +}; +#include +#include +#include + +class ADvoiceUI : public Fl_Group { +public: + Fl_Group* make_window(); + Fl_Group *ADnoteVoiceParameters; + Fl_Group *voiceparametersgroup; + Fl_Group *voicemodegroup; + Fl_Group *voiceFMparametersgroup; + Fl_Group *modfrequency; + EnvelopeUI *voiceFMfreqenvgroup; +private: + void cb_Enable_i(Fl_Check_Button*, void*); + static void cb_Enable(Fl_Check_Button*, void*); + void cb_Coarse_i(Fl_Counter*, void*); + static void cb_Coarse(Fl_Counter*, void*); + void cb_Octave_i(Fl_Counter*, void*); + static void cb_Octave(Fl_Counter*, void*); + void cb__i(Fl_Slider*, void*); + static void cb_(Fl_Slider*, void*); +public: + Fl_Value_Output *fmdetunevalueoutput; +private: + void cb_fmdetunevalueoutput_i(Fl_Value_Output*, void*); + static void cb_fmdetunevalueoutput(Fl_Value_Output*, void*); + void cb_Detune_i(Fl_Choice*, void*); + static void cb_Detune(Fl_Choice*, void*); + void cb_Vol_i(Fl_Value_Slider*, void*); + static void cb_Vol(Fl_Value_Slider*, void*); + void cb_V_i(Fl_Value_Slider*, void*); + static void cb_V(Fl_Value_Slider*, void*); +public: + EnvelopeUI *voiceFMampenvgroup; +private: + void cb_Enable1_i(Fl_Check_Button*, void*); + static void cb_Enable1(Fl_Check_Button*, void*); + void cb_F_i(Fl_Value_Slider*, void*); + static void cb_F(Fl_Value_Slider*, void*); +public: + Fl_Group *modoscil; + Fl_Group *fmoscil; + Fl_Button *changeFMoscilbutton; +private: + void cb_changeFMoscilbutton_i(Fl_Button*, void*); + static void cb_changeFMoscilbutton(Fl_Button*, void*); + void cb_Phase_i(Fl_Slider*, void*); + static void cb_Phase(Fl_Slider*, void*); + void cb_Use_i(Fl_Choice*, void*); + static void cb_Use(Fl_Choice*, void*); + void cb_External_i(Fl_Choice*, void*); + static void cb_External(Fl_Choice*, void*); + void cb_Type_i(Fl_Choice*, void*); + static void cb_Type(Fl_Choice*, void*); + static Fl_Menu_Item menu_Type[]; +public: + EnvelopeUI *voicefreqenvgroup; +private: + void cb_Enable2_i(Fl_Check_Button*, void*); + static void cb_Enable2(Fl_Check_Button*, void*); +public: + LFOUI *voicefreqlfogroup; +private: + void cb_Enable3_i(Fl_Check_Button*, void*); + static void cb_Enable3(Fl_Check_Button*, void*); + void cb_Octave1_i(Fl_Counter*, void*); + static void cb_Octave1(Fl_Counter*, void*); + void cb_Coarse1_i(Fl_Counter*, void*); + static void cb_Coarse1(Fl_Counter*, void*); + void cb_1_i(Fl_Slider*, void*); + static void cb_1(Fl_Slider*, void*); +public: + Fl_Value_Output *detunevalueoutput; +private: + void cb_detunevalueoutput1_i(Fl_Value_Output*, void*); + static void cb_detunevalueoutput1(Fl_Value_Output*, void*); + void cb_440Hz_i(Fl_Check_Button*, void*); + static void cb_440Hz(Fl_Check_Button*, void*); +public: + WidgetPDial *fixedfreqetdial; +private: + void cb_fixedfreqetdial_i(WidgetPDial*, void*); + static void cb_fixedfreqetdial(WidgetPDial*, void*); + void cb_Detune1_i(Fl_Choice*, void*); + static void cb_Detune1(Fl_Choice*, void*); +public: + Fl_Group *voiceoscil; + Fl_Button *changevoiceoscilbutton; +private: + void cb_changevoiceoscilbutton_i(Fl_Button*, void*); + static void cb_changevoiceoscilbutton(Fl_Button*, void*); + void cb_Phase1_i(Fl_Slider*, void*); + static void cb_Phase1(Fl_Slider*, void*); + void cb_R_i(Fl_Check_Button*, void*); + static void cb_R(Fl_Check_Button*, void*); + void cb_Use1_i(Fl_Choice*, void*); + static void cb_Use1(Fl_Choice*, void*); + void cb_Vol1_i(Fl_Value_Slider*, void*); + static void cb_Vol1(Fl_Value_Slider*, void*); + void cb_V1_i(Fl_Value_Slider*, void*); + static void cb_V1(Fl_Value_Slider*, void*); +public: + EnvelopeUI *voiceampenvgroup; +private: + void cb_Pan_i(WidgetPDial*, void*); + static void cb_Pan(WidgetPDial*, void*); + void cb_Enable4_i(Fl_Check_Button*, void*); + static void cb_Enable4(Fl_Check_Button*, void*); +public: + LFOUI *voiceamplfogroup; +private: + void cb_Enable5_i(Fl_Check_Button*, void*); + static void cb_Enable5(Fl_Check_Button*, void*); + void cb_Minus_i(Fl_Check_Button*, void*); + static void cb_Minus(Fl_Check_Button*, void*); +public: + Fl_Group *voicefiltergroup; + EnvelopeUI *voicefilterenvgroup; +private: + void cb_Enable6_i(Fl_Check_Button*, void*); + static void cb_Enable6(Fl_Check_Button*, void*); +public: + LFOUI *voicefilterlfogroup; +private: + void cb_Enable7_i(Fl_Check_Button*, void*); + static void cb_Enable7(Fl_Check_Button*, void*); + void cb_2_i(Fl_Choice*, void*); + static void cb_2(Fl_Choice*, void*); + static Fl_Menu_Item menu_[]; +public: + Fl_Check_Button *bypassfiltercheckbutton; +private: + void cb_bypassfiltercheckbutton_i(Fl_Check_Button*, void*); + static void cb_bypassfiltercheckbutton(Fl_Check_Button*, void*); + void cb_Delay_i(Fl_Value_Slider*, void*); + static void cb_Delay(Fl_Value_Slider*, void*); + void cb_Enable8_i(Fl_Check_Button*, void*); + static void cb_Enable8(Fl_Check_Button*, void*); +public: + Fl_Box *noiselabel; +private: + void cb_noiselabel1_i(Fl_Box*, void*); + static void cb_noiselabel1(Fl_Box*, void*); +public: + Fl_Check_Button *voiceonbutton; +private: + void cb_voiceonbutton_i(Fl_Check_Button*, void*); + static void cb_voiceonbutton(Fl_Check_Button*, void*); +public: + ADvoiceUI(int x,int y, int w, int h, const char *label=0); + void init(ADnoteParameters *parameters,int nvoice_,Master *master_); + ~ADvoiceUI(); +private: + int nvoice; + ADnoteParameters *pars; + OscilEditor *oscedit; + Oscilloscope *osc; + Oscilloscope *oscFM; + Master *master; +}; +#include +#include +#include +#include + +class ADnoteUI : public PresetsUI_ { + Fl_Double_Window* make_window(); +public: + Fl_Double_Window *ADnoteGlobalParameters; + EnvelopeUI *freqenv; + Fl_Counter *octave; +private: + void cb_octave_i(Fl_Counter*, void*); + static void cb_octave(Fl_Counter*, void*); +public: + Fl_Counter *coarsedet; +private: + void cb_coarsedet_i(Fl_Counter*, void*); + static void cb_coarsedet(Fl_Counter*, void*); +public: + LFOUI *freqlfo; + Fl_Slider *freq; +private: + void cb_freq_i(Fl_Slider*, void*); + static void cb_freq(Fl_Slider*, void*); +public: + Fl_Value_Output *detunevalueoutput; +private: + void cb_detunevalueoutput2_i(Fl_Value_Output*, void*); + static void cb_detunevalueoutput2(Fl_Value_Output*, void*); +public: + Fl_Choice *detunetype; +private: + void cb_detunetype_i(Fl_Choice*, void*); + static void cb_detunetype(Fl_Choice*, void*); + void cb_relBW_i(WidgetPDial*, void*); + static void cb_relBW(WidgetPDial*, void*); +public: + Fl_Value_Slider *volume; +private: + void cb_volume_i(Fl_Value_Slider*, void*); + static void cb_volume(Fl_Value_Slider*, void*); +public: + Fl_Value_Slider *vsns; +private: + void cb_vsns_i(Fl_Value_Slider*, void*); + static void cb_vsns(Fl_Value_Slider*, void*); +public: + WidgetPDial *pan; +private: + void cb_pan_i(WidgetPDial*, void*); + static void cb_pan(WidgetPDial*, void*); +public: + WidgetPDial *pstr; +private: + void cb_pstr_i(WidgetPDial*, void*); + static void cb_pstr(WidgetPDial*, void*); +public: + WidgetPDial *pt; +private: + void cb_pt_i(WidgetPDial*, void*); + static void cb_pt(WidgetPDial*, void*); +public: + WidgetPDial *pstc; +private: + void cb_pstc_i(WidgetPDial*, void*); + static void cb_pstc(WidgetPDial*, void*); +public: + WidgetPDial *pvel; +private: + void cb_pvel_i(WidgetPDial*, void*); + static void cb_pvel(WidgetPDial*, void*); +public: + EnvelopeUI *ampenv; + LFOUI *amplfo; + Fl_Check_Button *rndgrp; +private: + void cb_rndgrp_i(Fl_Check_Button*, void*); + static void cb_rndgrp(Fl_Check_Button*, void*); +public: + EnvelopeUI *filterenv; + LFOUI *filterlfo; + FilterUI *filterui; + Fl_Check_Button *stereo; +private: + void cb_stereo_i(Fl_Check_Button*, void*); + static void cb_stereo(Fl_Check_Button*, void*); + void cb_Show_i(Fl_Button*, void*); + static void cb_Show(Fl_Button*, void*); + void cb_Show1_i(Fl_Button*, void*); + static void cb_Show1(Fl_Button*, void*); + void cb_Close_i(Fl_Button*, void*); + static void cb_Close(Fl_Button*, void*); + void cb_Resonance_i(Fl_Button*, void*); + static void cb_Resonance(Fl_Button*, void*); + void cb_C_i(Fl_Button*, void*); + static void cb_C(Fl_Button*, void*); + void cb_P_i(Fl_Button*, void*); + static void cb_P(Fl_Button*, void*); +public: + Fl_Double_Window *ADnoteVoice; + ADvoiceUI *advoice; +private: + void cb_Close1_i(Fl_Button*, void*); + static void cb_Close1(Fl_Button*, void*); +public: + Fl_Counter *currentvoicecounter; +private: + void cb_currentvoicecounter_i(Fl_Counter*, void*); + static void cb_currentvoicecounter(Fl_Counter*, void*); + void cb_C1_i(Fl_Button*, void*); + static void cb_C1(Fl_Button*, void*); + void cb_P1_i(Fl_Button*, void*); + static void cb_P1(Fl_Button*, void*); +public: + Fl_Double_Window *ADnoteVoiceList; +private: + void cb_Hide_i(Fl_Button*, void*); + static void cb_Hide(Fl_Button*, void*); +public: + ADnoteUI(ADnoteParameters *parameters,Master *master_); + ~ADnoteUI(); + void refresh(); +private: + ADnoteParameters *pars; + ResonanceUI *resui; + Master *master; + int nvoice; + ADvoicelistitem *voicelistitem[NUM_VOICES]; +}; +#endif diff --git a/plugins/zynaddsubfx/src/UI/BankUI.cc b/plugins/zynaddsubfx/src/UI/BankUI.cc new file mode 100644 index 000000000..40306238a --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/BankUI.cc @@ -0,0 +1,420 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0109 + +#include "BankUI.h" +//Copyright (c) 2002-2005 Nasca Octavian Paul +//License: GNU GPL version 2 or later + +void BankProcess_::process() { +} + +BankSlot::BankSlot(int x,int y, int w, int h, const char *label):Fl_Button(x,y,w,h,label) { + what=NULL; +whatslot=NULL; +nslot=0; +nselected=NULL; +} + +int BankSlot::handle(int event) { + if (what==NULL) return(0); +if (Fl::event_inside(this)){ + *what=0;*whatslot=nslot; + if ((event==FL_RELEASE)&&(Fl::event_button()==1))*what=1; + if ((event==FL_RELEASE)&&(Fl::event_button()==3))*what=2; + if (event==FL_PUSH) highlight=1; +}else highlight=0; + +int tmp=Fl_Button::handle(event); +if ((*what!=0) && Fl::event_inside(this)) (bp->*fnc)(); +return(tmp); +} + +void BankSlot::init(int nslot_, int *what_, int *whatslot_,void (BankProcess_:: *fnc_)(void),BankProcess_ *bp_,Bank *bank_,int *nselected_) { + nslot=nslot_; +what=what_; +whatslot=whatslot_; +fnc=fnc_; +bp=bp_; +bank=bank_; +nselected=nselected_; +box(FL_THIN_UP_BOX); +labelfont(0); +labelsize(13); +align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE|FL_ALIGN_CLIP); + +highlight=0; +refresh(); +} + +void BankSlot::refresh() { + if (bank->emptyslot(nslot)) { + color(46); +} else { + if (bank->isPADsynth_used(nslot)) color(26); + else color(51); +}; + +if (*nselected==nslot) color(6); + + +label(bank->getnamenumbered(nslot)); +} + +void BankUI::cb_Close_i(Fl_Button*, void*) { + bankuiwindow->hide(); +} +void BankUI::cb_Close(Fl_Button* o, void* v) { + ((BankUI*)(o->parent()->user_data()))->cb_Close_i(o,v); +} + +void BankUI::cb_writebutton_i(Fl_Light_Button* o, void*) { + if (o->value()>0.5) mode=2; +removeselection(); +} +void BankUI::cb_writebutton(Fl_Light_Button* o, void* v) { + ((BankUI*)(o->parent()->parent()->user_data()))->cb_writebutton_i(o,v); +} + +void BankUI::cb_readbutton_i(Fl_Light_Button* o, void*) { + if (o->value()>0.5) mode=1; +removeselection(); +} +void BankUI::cb_readbutton(Fl_Light_Button* o, void* v) { + ((BankUI*)(o->parent()->parent()->user_data()))->cb_readbutton_i(o,v); +} + +void BankUI::cb_clearbutton_i(Fl_Light_Button* o, void*) { + if (o->value()>0.5) mode=3; +removeselection(); +} +void BankUI::cb_clearbutton(Fl_Light_Button* o, void* v) { + ((BankUI*)(o->parent()->parent()->user_data()))->cb_clearbutton_i(o,v); +} + +void BankUI::cb_swapbutton_i(Fl_Light_Button* o, void*) { + if (o->value()>0.5) mode=4; +removeselection(); +} +void BankUI::cb_swapbutton(Fl_Light_Button* o, void* v) { + ((BankUI*)(o->parent()->parent()->user_data()))->cb_swapbutton_i(o,v); +} + +void BankUI::cb_New_i(Fl_Button*, void*) { + const char *dirname; + +dirname=fl_input("New empty Bank:"); +if (dirname==NULL) return; + + +int result=bank->newbank(dirname); + +if (result!=0) fl_alert("Error: Could not make a new bank (directory).."); + +refreshmainwindow(); +} +void BankUI::cb_New(Fl_Button* o, void* v) { + ((BankUI*)(o->parent()->user_data()))->cb_New_i(o,v); +} + +void BankUI::cb_auto_i(Fl_Check_Button* o, void*) { + config.cfg.BankUIAutoClose=(int) o->value(); +} +void BankUI::cb_auto(Fl_Check_Button* o, void* v) { + ((BankUI*)(o->parent()->user_data()))->cb_auto_i(o,v); +} + +void BankUI::cb_banklist_i(Fl_Choice* o, void*) { + int n=o->value(); +char *dirname=bank->banks[n].dir; +if (dirname==NULL) return; + +if (bank->loadbank(dirname)==2) + fl_alert("Error: Could not load the bank from the directory\n%s.",dirname); +for (int i=0;irefresh(); +refreshmainwindow(); +} +void BankUI::cb_banklist(Fl_Choice* o, void* v) { + ((BankUI*)(o->parent()->user_data()))->cb_banklist_i(o,v); +} + +void BankUI::cb_Refresh_i(Fl_Button*, void*) { + rescan_for_banks(); +banklist->value(0); +} +void BankUI::cb_Refresh(Fl_Button* o, void* v) { + ((BankUI*)(o->parent()->user_data()))->cb_Refresh_i(o,v); +} + +void BankUI::cb_Show_i(Fl_Check_Button* o, void*) { + config.cfg.CheckPADsynth=(int) o->value(); +refreshmainwindow(); +} +void BankUI::cb_Show(Fl_Check_Button* o, void* v) { + ((BankUI*)(o->parent()->user_data()))->cb_Show_i(o,v); +} + +Fl_Double_Window* BankUI::make_window() { + { Fl_Double_Window* o = bankuiwindow = new Fl_Double_Window(785, 575, "Bank"); + bankuiwindow->user_data((void*)(this)); + { Fl_Button* o = new Fl_Button(705, 546, 70, 24, "Close"); + o->box(FL_THIN_UP_BOX); + o->callback((Fl_Callback*)cb_Close); + } // Fl_Button* o + { Fl_Group* o = new Fl_Group(5, 34, 772, 491); + o->box(FL_ENGRAVED_FRAME); + { Fl_Pack* o = new Fl_Pack(10, 39, 150, 481); + o->box(FL_BORDER_BOX); + o->box(FL_NO_BOX); + for (int i=0;i<32;i++){bs[i]=new BankSlot (0,0,o->w(),15," ");bs[i]->init(i,&what,&slot,&BankProcess_::process,(BankProcess_ *)this,bank,&nselected);}; + o->end(); + } // Fl_Pack* o + { Fl_Pack* o = new Fl_Pack(163, 39, 150, 481); + o->box(FL_BORDER_BOX); + o->box(FL_NO_BOX); + for (int i=32;i<64;i++){bs[i]=new BankSlot (0,0,o->w(),15," ");bs[i]->init(i,&what,&slot,&BankProcess_::process,(BankProcess_ *)this,bank,&nselected);}; + o->end(); + } // Fl_Pack* o + { Fl_Pack* o = new Fl_Pack(316, 39, 150, 481); + o->box(FL_BORDER_BOX); + o->box(FL_NO_BOX); + for (int i=64;i<96;i++){bs[i]=new BankSlot (0,0,o->w(),15," ");bs[i]->init(i,&what,&slot,&BankProcess_::process,(BankProcess_ *)this,bank,&nselected);}; + o->end(); + } // Fl_Pack* o + { Fl_Pack* o = new Fl_Pack(469, 39, 150, 481); + o->box(FL_BORDER_BOX); + o->box(FL_NO_BOX); + for (int i=96;i<128;i++){bs[i]=new BankSlot (0,0,o->w(),15," ");bs[i]->init(i,&what,&slot,&BankProcess_::process,(BankProcess_ *)this,bank,&nselected);}; + o->end(); + } // Fl_Pack* o + { Fl_Pack* o = new Fl_Pack(622, 39, 150, 481); + o->box(FL_BORDER_BOX); + o->box(FL_NO_BOX); + for (int i=128;i<160;i++){bs[i]=new BankSlot (0,0,o->w(),15," ");bs[i]->init(i,&what,&slot,&BankProcess_::process,(BankProcess_ *)this,bank,&nselected);}; + o->end(); + } // Fl_Pack* o + o->end(); + } // Fl_Group* o + { modeselect = new Fl_Group(5, 528, 425, 42); + modeselect->box(FL_ENGRAVED_BOX); + { Fl_Light_Button* o = writebutton = new Fl_Light_Button(116, 534, 99, 30, "WRITE"); + writebutton->type(102); + writebutton->box(FL_PLASTIC_UP_BOX); + writebutton->down_box(FL_THIN_DOWN_BOX); + writebutton->selection_color((Fl_Color)1); + writebutton->labeltype(FL_ENGRAVED_LABEL); + writebutton->labelfont(1); + writebutton->labelsize(13); + writebutton->callback((Fl_Callback*)cb_writebutton); + if (bank->locked()) o->deactivate(); + } // Fl_Light_Button* writebutton + { Fl_Light_Button* o = readbutton = new Fl_Light_Button(11, 534, 99, 30, "READ"); + readbutton->type(102); + readbutton->box(FL_PLASTIC_UP_BOX); + readbutton->down_box(FL_THIN_DOWN_BOX); + readbutton->selection_color((Fl_Color)101); + readbutton->labeltype(FL_ENGRAVED_LABEL); + readbutton->labelfont(1); + readbutton->labelsize(13); + readbutton->callback((Fl_Callback*)cb_readbutton); + o->value(1); + } // Fl_Light_Button* readbutton + { Fl_Light_Button* o = clearbutton = new Fl_Light_Button(221, 534, 99, 30, "CLEAR"); + clearbutton->type(102); + clearbutton->box(FL_PLASTIC_UP_BOX); + clearbutton->down_box(FL_THIN_DOWN_BOX); + clearbutton->selection_color(FL_FOREGROUND_COLOR); + clearbutton->labeltype(FL_ENGRAVED_LABEL); + clearbutton->labelfont(1); + clearbutton->labelsize(13); + clearbutton->callback((Fl_Callback*)cb_clearbutton); + if (bank->locked()) o->deactivate(); + } // Fl_Light_Button* clearbutton + { Fl_Light_Button* o = swapbutton = new Fl_Light_Button(325, 534, 99, 30, "SWAP"); + swapbutton->type(102); + swapbutton->box(FL_PLASTIC_UP_BOX); + swapbutton->down_box(FL_THIN_DOWN_BOX); + swapbutton->selection_color((Fl_Color)227); + swapbutton->labeltype(FL_ENGRAVED_LABEL); + swapbutton->labelfont(1); + swapbutton->labelsize(13); + swapbutton->callback((Fl_Callback*)cb_swapbutton); + if (bank->locked()) o->deactivate(); + } // Fl_Light_Button* swapbutton + modeselect->end(); + } // Fl_Group* modeselect + { Fl_Button* o = new Fl_Button(685, 5, 93, 25, "New Bank..."); + o->box(FL_PLASTIC_UP_BOX); + o->labelfont(1); + o->labelsize(11); + o->callback((Fl_Callback*)cb_New); + o->align(FL_ALIGN_WRAP); + } // Fl_Button* o + { Fl_Check_Button* o = new Fl_Check_Button(705, 529, 60, 15, "auto close"); + o->tooltip("automatically close the bank window if the instrument is loaded"); + o->down_box(FL_DOWN_BOX); + o->labelsize(10); + o->callback((Fl_Callback*)cb_auto); + o->value(config.cfg.BankUIAutoClose); + } // Fl_Check_Button* o + { banklist = new Fl_Choice(5, 8, 220, 20); + banklist->down_box(FL_BORDER_BOX); + banklist->labelfont(1); + banklist->textfont(1); + banklist->textsize(11); + banklist->callback((Fl_Callback*)cb_banklist); + banklist->align(FL_ALIGN_CENTER); + } // Fl_Choice* banklist + { Fl_Button* o = new Fl_Button(230, 8, 105, 20, "Refresh bank list"); + o->tooltip("Refresh the bank list (rescan)"); + o->box(FL_THIN_UP_BOX); + o->color(FL_LIGHT1); + o->labelsize(11); + o->callback((Fl_Callback*)cb_Refresh); + } // Fl_Button* o + { Fl_Check_Button* o = new Fl_Check_Button(435, 530, 150, 15, "Show PADsynth status"); + o->down_box(FL_DOWN_BOX); + o->labelsize(11); + o->callback((Fl_Callback*)cb_Show); + o->value(config.cfg.CheckPADsynth); + } // Fl_Check_Button* o + o->label(bank->bankfiletitle); + if (bank->bankfiletitle==NULL) o->label ("Choose a bank from the bank list on the left (or go to settings if to configure the bank location) or choose 'New Bank...' to make a new bank."); + bankuiwindow->end(); + } // Fl_Double_Window* bankuiwindow + return bankuiwindow; +} + +BankUI::BankUI(Master *master_,int *npart_) { + fnc=&BankProcess_::process; +master=master_; +npart=npart_; +bank=&master_->bank; +what=0; +nselected=-1; +make_window(); +mode=1; +} + +BankUI::~BankUI() { + bankuiwindow->hide(); +delete(bankuiwindow); +} + +void BankUI::show() { + bankuiwindow->show(); +simplesetmode(config.cfg.UserInterfaceMode==2); +} + +void BankUI::hide() { + bankuiwindow->hide(); +} + +void BankUI::init(Fl_Valuator *cbwig_) { + cbwig=cbwig_; +rescan_for_banks(); +} + +void BankUI::process() { + int slot=this->slot; + +if ((what==2)&&(bank->emptyslot(slot)==0)&&(mode!=4)) {//Rename slot + const char *tmp=fl_input("Slot (instrument) name:",(const char *)bank->getname(slot)); + if (tmp!=NULL) bank->setname(slot,tmp,-1); + bs[slot]->refresh(); +}; + +if ((what==1)&&(mode==1)&&(!bank->emptyslot(slot))){//Reads from slot + pthread_mutex_lock(&master->mutex); + bank->loadfromslot(slot,master->part[*npart]); + pthread_mutex_unlock(&master->mutex); + master->part[*npart]->applyparameters(); + snprintf((char *)master->part[*npart]->Pname,PART_MAX_NAME_LEN,"%s",bank->getname(slot)); + cbwig->do_callback(); + + if (config.cfg.BankUIAutoClose!=0) + bankuiwindow->hide(); + +}; + +if ((what==1)&&(mode==2)){//save(write) to slot + if (!bank->emptyslot(slot)){ + if (!fl_choice("Overwrite the slot no. %d ?","No","Yes",NULL,slot+1)) goto nooverwriteslot; + }; + pthread_mutex_lock(&master->mutex); + bank->savetoslot(slot,master->part[*npart]); + pthread_mutex_unlock(&master->mutex); + + bs[slot]->refresh(); + mode=1;readbutton->value(1);writebutton->value(0); + nooverwriteslot:; +}; + + + +if ((what==1)&&(mode==3)&&(!bank->emptyslot(slot))){//Clears the slot + if (fl_choice("Clear the slot no. %d ?","No","Yes",NULL,slot+1)){ + bank->clearslot(slot); + bs[slot]->refresh(); + }; +}; + +if (mode==4){//swap + bool done=false; + if ((what==1)&&(nselected>=0)){ + bank->swapslot(nselected,slot); + int ns=nselected; + nselected=-1; + bs[slot]->refresh(); + bs[ns]->refresh(); + done=true; + }; + if (((nselected<0)||(what==2))&&(!done)){ + int ns=nselected; + nselected=slot; + if (ns>0) bs[ns]->refresh(); + bs[slot]->refresh(); + }; +}; +if (mode!=4) refreshmainwindow(); +} + +void BankUI::refreshmainwindow() { + bankuiwindow->label(bank->bankfiletitle); +mode=1;readbutton->value(1);writebutton->value(0);clearbutton->value(0);swapbutton->value(0); +nselected=-1; +if (bank->locked()){ + writebutton->deactivate(); + clearbutton->deactivate(); + swapbutton->deactivate(); +} else { + writebutton->activate(); + clearbutton->activate(); + swapbutton->activate(); +}; +for (int i=0;irefresh(); +} + +void BankUI::removeselection() { + if (nselected>=0) { + int ns=nselected; + nselected=-1; + bs[ns]->refresh(); +}; +} + +void BankUI::rescan_for_banks() { + banklist->clear(); +banklist->add(" "); +bank->rescanforbanks(); + +for (int i=1;ibanks[i].name!=NULL) banklist->add(bank->banks[i].name); +}; +} + +void BankUI::simplesetmode(bool beginnerui) { + readbutton->value(1); +mode=1; +removeselection(); +if (beginnerui) modeselect->hide(); + else modeselect->show(); +} diff --git a/plugins/zynaddsubfx/src/UI/BankUI.fl b/plugins/zynaddsubfx/src/UI/BankUI.fl new file mode 100644 index 000000000..7aa8e7e10 --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/BankUI.fl @@ -0,0 +1,355 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0107 +header_name {.h} +code_name {.cc} +decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} + +decl {//License: GNU GPL version 2 or later} {} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include "../Misc/Master.h"} {public +} + +decl {\#include "../Misc/Bank.h"} {public +} + +decl {\#include "../Misc/Config.h"} {public +} + +class BankProcess_ {} { + Function {process()} {open return_type {virtual void} + } {} + decl {Bank *bank;} {public + } +} + +class BankSlot {open : {public Fl_Button,BankProcess_} +} { + Function {BankSlot(int x,int y, int w, int h, const char *label=0):Fl_Button(x,y,w,h,label)} {} { + code {what=NULL; +whatslot=NULL; +nslot=0; +nselected=NULL;} {} + } + Function {handle(int event)} {return_type int + } { + code {if (what==NULL) return(0); +if (Fl::event_inside(this)){ + *what=0;*whatslot=nslot; + if ((event==FL_RELEASE)&&(Fl::event_button()==1))*what=1; + if ((event==FL_RELEASE)&&(Fl::event_button()==3))*what=2; + if (event==FL_PUSH) highlight=1; +}else highlight=0; + +int tmp=Fl_Button::handle(event); +if ((*what!=0) && Fl::event_inside(this)) (bp->*fnc)(); +return(tmp);} {} + } + Function {init(int nslot_, int *what_, int *whatslot_,void (BankProcess_:: *fnc_)(void),BankProcess_ *bp_,Bank *bank_,int *nselected_)} {open + } { + code {nslot=nslot_; +what=what_; +whatslot=whatslot_; +fnc=fnc_; +bp=bp_; +bank=bank_; +nselected=nselected_; +box(FL_THIN_UP_BOX); +labelfont(0); +labelsize(13); +align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE|FL_ALIGN_CLIP); + +highlight=0; +refresh();} {selected + } + } + Function {refresh()} {} { + code {if (bank->emptyslot(nslot)) { + color(46); +} else { + if (bank->isPADsynth_used(nslot)) color(26); + else color(51); +}; + +if (*nselected==nslot) color(6); + + +label(bank->getnamenumbered(nslot));} {} + } + decl {int *what,*whatslot,nslot,highlight, *nselected;} {} + decl {void (BankProcess_:: *fnc)(void);} {} + decl {BankProcess_ *bp;} {} +} + +class BankUI {: {public BankProcess_} +} { + Function {make_window()} {} { + Fl_Window bankuiwindow { + label Bank + xywh {4 64 785 575} type Double hide + code0 {o->label(bank->bankfiletitle);} + code1 {if (bank->bankfiletitle==NULL) o->label ("Choose a bank from the bank list on the left (or go to settings if to configure the bank location) or choose 'New Bank...' to make a new bank.");} + } { + Fl_Button {} { + label Close + callback {bankuiwindow->hide();} + xywh {705 546 70 24} box THIN_UP_BOX + } + Fl_Group {} { + xywh {5 34 772 491} box ENGRAVED_FRAME + } { + Fl_Pack {} { + xywh {10 39 150 481} box BORDER_BOX + code0 {o->box(FL_NO_BOX);} + code1 {for (int i=0;i<32;i++){bs[i]=new BankSlot (0,0,o->w(),15," ");bs[i]->init(i,&what,&slot,&BankProcess_::process,(BankProcess_ *)this,bank,&nselected);};} + } {} + Fl_Pack {} { + xywh {163 39 150 481} box BORDER_BOX + code0 {o->box(FL_NO_BOX);} + code1 {for (int i=32;i<64;i++){bs[i]=new BankSlot (0,0,o->w(),15," ");bs[i]->init(i,&what,&slot,&BankProcess_::process,(BankProcess_ *)this,bank,&nselected);};} + } {} + Fl_Pack {} { + xywh {316 39 150 481} box BORDER_BOX + code0 {o->box(FL_NO_BOX);} + code1 {for (int i=64;i<96;i++){bs[i]=new BankSlot (0,0,o->w(),15," ");bs[i]->init(i,&what,&slot,&BankProcess_::process,(BankProcess_ *)this,bank,&nselected);};} + } {} + Fl_Pack {} { + xywh {469 39 150 481} box BORDER_BOX + code0 {o->box(FL_NO_BOX);} + code1 {for (int i=96;i<128;i++){bs[i]=new BankSlot (0,0,o->w(),15," ");bs[i]->init(i,&what,&slot,&BankProcess_::process,(BankProcess_ *)this,bank,&nselected);};} + } {} + Fl_Pack {} { + xywh {622 39 150 481} box BORDER_BOX + code0 {o->box(FL_NO_BOX);} + code1 {for (int i=128;i<160;i++){bs[i]=new BankSlot (0,0,o->w(),15," ");bs[i]->init(i,&what,&slot,&BankProcess_::process,(BankProcess_ *)this,bank,&nselected);};} + } {} + } + Fl_Group modeselect { + xywh {5 528 425 42} box ENGRAVED_BOX + } { + Fl_Light_Button writebutton { + label WRITE + callback {if (o->value()>0.5) mode=2; +removeselection();} + xywh {116 534 99 30} type Radio box PLASTIC_UP_BOX down_box THIN_DOWN_BOX selection_color 1 labeltype ENGRAVED_LABEL labelfont 1 labelsize 13 + code0 {if (bank->locked()) o->deactivate();} + } + Fl_Light_Button readbutton { + label READ + callback {if (o->value()>0.5) mode=1; +removeselection();} + xywh {11 534 99 30} type Radio box PLASTIC_UP_BOX down_box THIN_DOWN_BOX selection_color 101 labeltype ENGRAVED_LABEL labelfont 1 labelsize 13 + code0 {o->value(1);} + } + Fl_Light_Button clearbutton { + label CLEAR + callback {if (o->value()>0.5) mode=3; +removeselection();} + xywh {221 534 99 30} type Radio box PLASTIC_UP_BOX down_box THIN_DOWN_BOX selection_color 0 labeltype ENGRAVED_LABEL labelfont 1 labelsize 13 + code0 {if (bank->locked()) o->deactivate();} + } + Fl_Light_Button swapbutton { + label SWAP + callback {if (o->value()>0.5) mode=4; +removeselection();} + xywh {325 534 99 30} type Radio box PLASTIC_UP_BOX down_box THIN_DOWN_BOX selection_color 227 labeltype ENGRAVED_LABEL labelfont 1 labelsize 13 + code0 {if (bank->locked()) o->deactivate();} + } + } + Fl_Button {} { + label {New Bank...} + callback {const char *dirname; + +dirname=fl_input("New empty Bank:"); +if (dirname==NULL) return; + + +int result=bank->newbank(dirname); + +if (result!=0) fl_alert("Error: Could not make a new bank (directory).."); + +refreshmainwindow();} + xywh {685 5 93 25} box PLASTIC_UP_BOX labelfont 1 labelsize 11 align 128 + } + Fl_Check_Button {} { + label {auto close} + callback {config.cfg.BankUIAutoClose=(int) o->value();} + tooltip {automatically close the bank window if the instrument is loaded} xywh {705 529 60 15} down_box DOWN_BOX labelsize 10 + code0 {o->value(config.cfg.BankUIAutoClose);} + } + Fl_Choice banklist { + callback {int n=o->value(); +char *dirname=bank->banks[n].dir; +if (dirname==NULL) return; + +if (bank->loadbank(dirname)==2) + fl_alert("Error: Could not load the bank from the directory\\n%s.",dirname); +for (int i=0;irefresh(); +refreshmainwindow();} open + xywh {5 8 220 20} down_box BORDER_BOX labelfont 1 align 0 textfont 1 textsize 11 + } {} + Fl_Button {} { + label {Refresh bank list} + callback {rescan_for_banks(); +banklist->value(0);} + tooltip {Refresh the bank list (rescan)} xywh {230 8 105 20} box THIN_UP_BOX color 50 labelsize 11 + } + Fl_Check_Button {} { + label {Show PADsynth status} + callback {config.cfg.CheckPADsynth=(int) o->value(); +refreshmainwindow();} + xywh {435 530 150 15} down_box DOWN_BOX labelsize 11 + code0 {o->value(config.cfg.CheckPADsynth);} + } + } + } + Function {BankUI(Master *master_,int *npart_)} {} { + code {fnc=&BankProcess_::process; +master=master_; +npart=npart_; +bank=&master_->bank; +what=0; +nselected=-1; +make_window(); +mode=1;} {} + } + Function {~BankUI()} {return_type virtual + } { + code {bankuiwindow->hide(); +delete(bankuiwindow);} {} + } + Function {show()} {} { + code {bankuiwindow->show(); +simplesetmode(config.cfg.UserInterfaceMode==2);} {} + } + Function {hide()} {} { + code {bankuiwindow->hide();} {} + } + Function {init(Fl_Valuator *cbwig_)} {} { + code {cbwig=cbwig_; +rescan_for_banks();} {} + } + Function {process()} {return_type void + } { + code {int slot=this->slot; + +if ((what==2)&&(bank->emptyslot(slot)==0)&&(mode!=4)) {//Rename slot + const char *tmp=fl_input("Slot (instrument) name:",(const char *)bank->getname(slot)); + if (tmp!=NULL) bank->setname(slot,tmp,-1); + bs[slot]->refresh(); +}; + +if ((what==1)&&(mode==1)&&(!bank->emptyslot(slot))){//Reads from slot + pthread_mutex_lock(&master->mutex); + bank->loadfromslot(slot,master->part[*npart]); + pthread_mutex_unlock(&master->mutex); + master->part[*npart]->applyparameters(); + snprintf((char *)master->part[*npart]->Pname,PART_MAX_NAME_LEN,"%s",bank->getname(slot)); + cbwig->do_callback(); + + if (config.cfg.BankUIAutoClose!=0) + bankuiwindow->hide(); + +}; + +if ((what==1)&&(mode==2)){//save(write) to slot + if (!bank->emptyslot(slot)){ + if (!fl_choice("Overwrite the slot no. %d ?","No","Yes",NULL,slot+1)) goto nooverwriteslot; + }; + pthread_mutex_lock(&master->mutex); + bank->savetoslot(slot,master->part[*npart]); + pthread_mutex_unlock(&master->mutex); + + bs[slot]->refresh(); + mode=1;readbutton->value(1);writebutton->value(0); + nooverwriteslot:; +}; + + + +if ((what==1)&&(mode==3)&&(!bank->emptyslot(slot))){//Clears the slot + if (fl_choice("Clear the slot no. %d ?","No","Yes",NULL,slot+1)){ + bank->clearslot(slot); + bs[slot]->refresh(); + }; +}; + +if (mode==4){//swap + bool done=false; + if ((what==1)&&(nselected>=0)){ + bank->swapslot(nselected,slot); + int ns=nselected; + nselected=-1; + bs[slot]->refresh(); + bs[ns]->refresh(); + done=true; + }; + if (((nselected<0)||(what==2))&&(!done)){ + int ns=nselected; + nselected=slot; + if (ns>0) bs[ns]->refresh(); + bs[slot]->refresh(); + }; +}; +if (mode!=4) refreshmainwindow();} {} + } + Function {refreshmainwindow()} {} { + code {bankuiwindow->label(bank->bankfiletitle); +mode=1;readbutton->value(1);writebutton->value(0);clearbutton->value(0);swapbutton->value(0); +nselected=-1; +if (bank->locked()){ + writebutton->deactivate(); + clearbutton->deactivate(); + swapbutton->deactivate(); +} else { + writebutton->activate(); + clearbutton->activate(); + swapbutton->activate(); +}; +for (int i=0;irefresh();} {} + } + Function {removeselection()} {} { + code {if (nselected>=0) { + int ns=nselected; + nselected=-1; + bs[ns]->refresh(); +};} {} + } + Function {rescan_for_banks()} {} { + code {banklist->clear(); +banklist->add(" "); +bank->rescanforbanks(); + +for (int i=1;ibanks[i].name!=NULL) banklist->add(bank->banks[i].name); +};} {} + } + Function {simplesetmode(bool beginnerui)} {} { + code {readbutton->value(1); +mode=1; +removeselection(); +if (beginnerui) modeselect->hide(); + else modeselect->show();} {} + } + decl {BankSlot *bs[BANK_SIZE];} {} + decl {int slot,what;//"what"=what button is pressed} {} + decl {int mode,*npart,nselected;} {} + decl {Master *master;} {} + decl {void (BankProcess_::* fnc)(void);} {} + decl {Fl_Valuator *cbwig;} {public + } +} diff --git a/plugins/zynaddsubfx/src/UI/BankUI.h b/plugins/zynaddsubfx/src/UI/BankUI.h new file mode 100644 index 000000000..6c36ea2d7 --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/BankUI.h @@ -0,0 +1,101 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0109 + +#ifndef BankUI_h +#define BankUI_h +#include +#include +#include +#include +#include +#include +#include "../Misc/Master.h" +#include "../Misc/Bank.h" +#include "../Misc/Config.h" + +class BankProcess_ { +public: + virtual void process(); + Bank *bank; +}; + +class BankSlot : public Fl_Button,BankProcess_ { +public: + BankSlot(int x,int y, int w, int h, const char *label=0); + int handle(int event); + void init(int nslot_, int *what_, int *whatslot_,void (BankProcess_:: *fnc_)(void),BankProcess_ *bp_,Bank *bank_,int *nselected_); + void refresh(); +private: + int *what,*whatslot,nslot,highlight, *nselected; + void (BankProcess_:: *fnc)(void); + BankProcess_ *bp; +}; +#include +#include +#include +#include +#include +#include +#include + +class BankUI : public BankProcess_ { +public: + Fl_Double_Window* make_window(); + Fl_Double_Window *bankuiwindow; +private: + void cb_Close_i(Fl_Button*, void*); + static void cb_Close(Fl_Button*, void*); +public: + Fl_Group *modeselect; + Fl_Light_Button *writebutton; +private: + void cb_writebutton_i(Fl_Light_Button*, void*); + static void cb_writebutton(Fl_Light_Button*, void*); +public: + Fl_Light_Button *readbutton; +private: + void cb_readbutton_i(Fl_Light_Button*, void*); + static void cb_readbutton(Fl_Light_Button*, void*); +public: + Fl_Light_Button *clearbutton; +private: + void cb_clearbutton_i(Fl_Light_Button*, void*); + static void cb_clearbutton(Fl_Light_Button*, void*); +public: + Fl_Light_Button *swapbutton; +private: + void cb_swapbutton_i(Fl_Light_Button*, void*); + static void cb_swapbutton(Fl_Light_Button*, void*); + void cb_New_i(Fl_Button*, void*); + static void cb_New(Fl_Button*, void*); + void cb_auto_i(Fl_Check_Button*, void*); + static void cb_auto(Fl_Check_Button*, void*); +public: + Fl_Choice *banklist; +private: + void cb_banklist_i(Fl_Choice*, void*); + static void cb_banklist(Fl_Choice*, void*); + void cb_Refresh_i(Fl_Button*, void*); + static void cb_Refresh(Fl_Button*, void*); + void cb_Show_i(Fl_Check_Button*, void*); + static void cb_Show(Fl_Check_Button*, void*); +public: + BankUI(Master *master_,int *npart_); + virtual ~BankUI(); + void show(); + void hide(); + void init(Fl_Valuator *cbwig_); + void process(); + void refreshmainwindow(); + void removeselection(); + void rescan_for_banks(); + void simplesetmode(bool beginnerui); +private: + BankSlot *bs[BANK_SIZE]; + int slot,what; //"what"=what button is pressed + int mode,*npart,nselected; + Master *master; + void (BankProcess_::* fnc)(void); +public: + Fl_Valuator *cbwig; +}; +#endif diff --git a/plugins/zynaddsubfx/src/UI/ConfigUI.cc b/plugins/zynaddsubfx/src/UI/ConfigUI.cc new file mode 100644 index 000000000..be6d20eab --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/ConfigUI.cc @@ -0,0 +1,561 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0109 + +#include "ConfigUI.h" +//Copyright (c) 2002-2005 Nasca Octavian Paul +//License: GNU GPL version 2 or later + +void ConfigUI::cb_configwindow_i(Fl_Double_Window* o, void*) { + writebankcfg(); +o->hide(); +} +void ConfigUI::cb_configwindow(Fl_Double_Window* o, void* v) { + ((ConfigUI*)(o->user_data()))->cb_configwindow_i(o,v); +} + +void ConfigUI::cb__i(Fl_Choice* o, void*) { + if ((int)o->value()==0) samplerateinput->activate(); + else samplerateinput->deactivate(); + +int samplerates[8]={44100,16000,22050,32000,44100,48000,88200,96000}; +config.cfg.SampleRate=samplerates[(int)o->value()]; + +setsamplerateinput(); +} +void ConfigUI::cb_(Fl_Choice* o, void* v) { + ((ConfigUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb__i(o,v); +} + +Fl_Menu_Item ConfigUI::menu_[] = { + {"Custom", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 14, 0}, + {"16000Hz", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 14, 0}, + {"22050Hz", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 14, 0}, + {"32000Hz", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 14, 0}, + {"44100Hz", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 14, 0}, + {"48000Hz", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 14, 0}, + {"88200Hz", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 14, 0}, + {"96000Hz", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 14, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void ConfigUI::cb_samplerateinput_i(Fl_Input* o, void*) { + char *tmp; +config.cfg.SampleRate=strtoul(o->value(),&tmp,10); +} +void ConfigUI::cb_samplerateinput(Fl_Input* o, void* v) { + ((ConfigUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_samplerateinput_i(o,v); +} + +void ConfigUI::cb_Buffer_i(Fl_Input* o, void*) { + char *tmp; +config.cfg.SoundBufferSize=strtoul(o->value(),&tmp,10); +} +void ConfigUI::cb_Buffer(Fl_Input* o, void* v) { + ((ConfigUI*)(o->parent()->parent()->parent()->user_data()))->cb_Buffer_i(o,v); +} + +void ConfigUI::cb_Swap_i(Fl_Light_Button* o, void*) { + config.cfg.SwapStereo=(int) o->value(); +} +void ConfigUI::cb_Swap(Fl_Light_Button* o, void* v) { + ((ConfigUI*)(o->parent()->parent()->parent()->user_data()))->cb_Swap_i(o,v); +} + +void ConfigUI::cb_OscilSize_i(Fl_Choice* o, void*) { + config.cfg.OscilSize=128<value(); +} +void ConfigUI::cb_OscilSize(Fl_Choice* o, void* v) { + ((ConfigUI*)(o->parent()->parent()->parent()->user_data()))->cb_OscilSize_i(o,v); +} + +Fl_Menu_Item ConfigUI::menu_OscilSize[] = { + {"128", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 14, 0}, + {"256", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 14, 0}, + {"512", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 14, 0}, + {"1024", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 14, 0}, + {"2048", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 14, 0}, + {"4096", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 14, 0}, + {"8192", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 14, 0}, + {"16384", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 14, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void ConfigUI::cb_Dump_i(Fl_File_Input* o, void*) { + snprintf(config.cfg.DumpFile,config.maxstringsize,"%s",o->value()); +} +void ConfigUI::cb_Dump(Fl_File_Input* o, void* v) { + ((ConfigUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_Dump_i(o,v); +} + +void ConfigUI::cb_Dump1_i(Fl_Check_Button* o, void*) { + config.cfg.DumpNotesToFile=(int) o->value(); +dump.startnow();//this has effect only if this option was disabled; +} +void ConfigUI::cb_Dump1(Fl_Check_Button* o, void* v) { + ((ConfigUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_Dump1_i(o,v); +} + +void ConfigUI::cb_Append_i(Fl_Check_Button* o, void*) { + config.cfg.DumpAppend=(int) o->value(); +} +void ConfigUI::cb_Append(Fl_Check_Button* o, void* v) { + ((ConfigUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_Append_i(o,v); +} + +void ConfigUI::cb_OSS_i(Fl_File_Input* o, void*) { + snprintf(config.cfg.LinuxOSSSeqInDev,config.maxstringsize,"%s",o->value()); +} +void ConfigUI::cb_OSS(Fl_File_Input* o, void* v) { + ((ConfigUI*)(o->parent()->parent()->parent()->parent()->parent()->user_data()))->cb_OSS_i(o,v); +} + +void ConfigUI::cb_OSS1_i(Fl_File_Input* o, void*) { + snprintf(config.cfg.LinuxOSSWaveOutDev,config.maxstringsize,"%s",o->value()); +} +void ConfigUI::cb_OSS1(Fl_File_Input* o, void* v) { + ((ConfigUI*)(o->parent()->parent()->parent()->parent()->parent()->user_data()))->cb_OSS1_i(o,v); +} + +void ConfigUI::cb_Midi_i(Fl_Counter* o, void*) { + config.cfg.WindowsMidiInId=(int) o->value(); +midiinputnamebox->label(config.winmididevices[config.cfg.WindowsMidiInId].name); +} +void ConfigUI::cb_Midi(Fl_Counter* o, void* v) { + ((ConfigUI*)(o->parent()->parent()->parent()->parent()->parent()->user_data()))->cb_Midi_i(o,v); +} + +void ConfigUI::cb_XML_i(Fl_Counter* o, void*) { + config.cfg.GzipCompression=(int) o->value(); +} +void ConfigUI::cb_XML(Fl_Counter* o, void* v) { + ((ConfigUI*)(o->parent()->parent()->parent()->user_data()))->cb_XML_i(o,v); +} + +void ConfigUI::cb_PADsynth_i(Fl_Choice* o, void*) { + config.cfg.Interpolation=(int) o->value(); +} +void ConfigUI::cb_PADsynth(Fl_Choice* o, void* v) { + ((ConfigUI*)(o->parent()->parent()->parent()->user_data()))->cb_PADsynth_i(o,v); +} + +Fl_Menu_Item ConfigUI::menu_PADsynth[] = { + {"Linear(fast)", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Cubic(slow)", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void ConfigUI::cb_Virtual_i(Fl_Choice* o, void*) { + config.cfg.VirKeybLayout=(int) o->value();; +} +void ConfigUI::cb_Virtual(Fl_Choice* o, void* v) { + ((ConfigUI*)(o->parent()->parent()->parent()->user_data()))->cb_Virtual_i(o,v); +} + +Fl_Menu_Item ConfigUI::menu_Virtual[] = { + {" ", 0, 0, 0, 1, FL_NORMAL_LABEL, 1, 11, 0}, + {"QWERTY", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"Dvorak", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"QWERTZ", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void ConfigUI::cb_rootsbrowse_i(Fl_Browser* o, void*) { + activatebutton_rootdir(o->value()!=0); +} +void ConfigUI::cb_rootsbrowse(Fl_Browser* o, void* v) { + ((ConfigUI*)(o->parent()->parent()->parent()->user_data()))->cb_rootsbrowse_i(o,v); +} + +void ConfigUI::cb_Add_i(Fl_Button*, void*) { + const char *dirname; +dirname=fl_dir_chooser("Add a root directory for banks:",NULL,0); +if (dirname==NULL) return; + +rootsbrowse->add(dirname); +} +void ConfigUI::cb_Add(Fl_Button* o, void* v) { + ((ConfigUI*)(o->parent()->parent()->parent()->user_data()))->cb_Add_i(o,v); +} + +void ConfigUI::cb_removerootdirbutton_i(Fl_Button*, void*) { + if (rootsbrowse->value()!=0) { + rootsbrowse->remove(rootsbrowse->value()); +}; +activatebutton_rootdir(false); +} +void ConfigUI::cb_removerootdirbutton(Fl_Button* o, void* v) { + ((ConfigUI*)(o->parent()->parent()->parent()->user_data()))->cb_removerootdirbutton_i(o,v); +} + +void ConfigUI::cb_makedefaultrootdirbutton_i(Fl_Button*, void*) { + int n=rootsbrowse->value(); + +if (n!=0) { + rootsbrowse->move(1,n); + rootsbrowse->value(1); + rootsbrowse->redraw(); +}; +activatebutton_rootdir(true); +} +void ConfigUI::cb_makedefaultrootdirbutton(Fl_Button* o, void* v) { + ((ConfigUI*)(o->parent()->parent()->parent()->user_data()))->cb_makedefaultrootdirbutton_i(o,v); +} + +void ConfigUI::cb_presetbrowse_i(Fl_Browser* o, void*) { + activatebutton_presetdir(o->value()!=0); +} +void ConfigUI::cb_presetbrowse(Fl_Browser* o, void* v) { + ((ConfigUI*)(o->parent()->parent()->parent()->user_data()))->cb_presetbrowse_i(o,v); +} + +void ConfigUI::cb_Add1_i(Fl_Button*, void*) { + const char *dirname; +dirname=fl_dir_chooser("Add a preset directory :",NULL,0); +if (dirname==NULL) return; + +presetbrowse->add(dirname); +} +void ConfigUI::cb_Add1(Fl_Button* o, void* v) { + ((ConfigUI*)(o->parent()->parent()->parent()->user_data()))->cb_Add1_i(o,v); +} + +void ConfigUI::cb_removepresetbutton_i(Fl_Button*, void*) { + if (presetbrowse->value()!=0) { + presetbrowse->remove(presetbrowse->value()); +}; +activatebutton_presetdir(false); +} +void ConfigUI::cb_removepresetbutton(Fl_Button* o, void* v) { + ((ConfigUI*)(o->parent()->parent()->parent()->user_data()))->cb_removepresetbutton_i(o,v); +} + +void ConfigUI::cb_makedefaultpresetbutton_i(Fl_Button*, void*) { + int n=presetbrowse->value(); + +if (n!=0) { + presetbrowse->move(1,n); + presetbrowse->value(1); + presetbrowse->redraw(); +}; +activatebutton_presetdir(true); +} +void ConfigUI::cb_makedefaultpresetbutton(Fl_Button* o, void* v) { + ((ConfigUI*)(o->parent()->parent()->parent()->user_data()))->cb_makedefaultpresetbutton_i(o,v); +} + +void ConfigUI::cb_Close_i(Fl_Button*, void*) { + configwindow->hide(); +writebankcfg(); +writepresetcfg(); +} +void ConfigUI::cb_Close(Fl_Button* o, void* v) { + ((ConfigUI*)(o->parent()->user_data()))->cb_Close_i(o,v); +} + +Fl_Double_Window* ConfigUI::make_window() { + { configwindow = new Fl_Double_Window(510, 340, "ZynAddSubFX Settings"); + configwindow->callback((Fl_Callback*)cb_configwindow, (void*)(this)); + { Fl_Tabs* o = new Fl_Tabs(5, 5, 500, 305); + { Fl_Group* o = new Fl_Group(5, 25, 500, 285, "Main settings"); + { Fl_Group* o = new Fl_Group(15, 45, 165, 30, "Sample Rate"); + o->box(FL_ENGRAVED_FRAME); + { Fl_Choice* o = new Fl_Choice(20, 50, 85, 20); + o->down_box(FL_BORDER_BOX); + o->textsize(10); + o->callback((Fl_Callback*)cb_); + o->menu(menu_); + o->value(getsamplerateorder()); + } // Fl_Choice* o + { Fl_Input* o = samplerateinput = new Fl_Input(115, 50, 60, 20); + samplerateinput->type(2); + samplerateinput->textfont(1); + samplerateinput->callback((Fl_Callback*)cb_samplerateinput); + setsamplerateinput(); + if (getsamplerateorder()!=0) o->deactivate(); + } // Fl_Input* samplerateinput + o->end(); + } // Fl_Group* o + { Fl_Input* o = new Fl_Input(190, 45, 60, 20, "Buffer Size"); + o->tooltip("Internal Sound Buffer Size (samples)"); + o->type(2); + o->labelsize(11); + o->textfont(1); + o->callback((Fl_Callback*)cb_Buffer); + o->align(129); + char *tmpbuf=new char[100];o->cut(0,o->maximum_size()); + snprintf(tmpbuf,100,"%d",config.cfg.SoundBufferSize);o->insert(tmpbuf); + delete []tmpbuf; + } // Fl_Input* o + { Fl_Light_Button* o = new Fl_Light_Button(20, 80, 85, 20, "Swap Stereo "); + o->box(FL_THIN_UP_BOX); + o->labelsize(10); + o->callback((Fl_Callback*)cb_Swap); + o->value(config.cfg.SwapStereo); + } // Fl_Light_Button* o + { Fl_Choice* o = new Fl_Choice(175, 80, 75, 20, "OscilSize"); + o->tooltip("ADSynth Oscillator Size (samples)"); + o->down_box(FL_BORDER_BOX); + o->labelfont(1); + o->labelsize(11); + o->textsize(10); + o->callback((Fl_Callback*)cb_OscilSize); + o->menu(menu_OscilSize); + o->value( (int) (log(config.cfg.OscilSize/128.0-1.0)/log(2)) +1); + } // Fl_Choice* o + { Fl_Box* o = new Fl_Box(15, 275, 235, 30, "Most settings has effect only after ZynAddSubFX is restarted."); + o->labelfont(1); + o->labelsize(11); + o->align(FL_ALIGN_WRAP); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(10, 255, 240, 20, "Read the Readme.txt for other settings"); + o->labelfont(1); + o->labelsize(11); + o->align(FL_ALIGN_WRAP); + } // Fl_Box* o + { Fl_Group* o = new Fl_Group(15, 125, 230, 85); + o->box(FL_ENGRAVED_BOX); + { Fl_File_Input* o = new Fl_File_Input(20, 170, 220, 35, "Dump File"); + o->callback((Fl_Callback*)cb_Dump); + o->align(FL_ALIGN_TOP_LEFT); + o->insert(config.cfg.DumpFile); + } // Fl_File_Input* o + { Fl_Check_Button* o = new Fl_Check_Button(20, 130, 100, 20, "Dump notes"); + o->down_box(FL_DOWN_BOX); + o->callback((Fl_Callback*)cb_Dump1); + o->value(config.cfg.DumpNotesToFile); + } // Fl_Check_Button* o + { Fl_Check_Button* o = new Fl_Check_Button(160, 130, 80, 20, "Append"); + o->down_box(FL_DOWN_BOX); + o->callback((Fl_Callback*)cb_Append); + o->value(config.cfg.DumpAppend); + } // Fl_Check_Button* o + o->end(); + } // Fl_Group* o + { Fl_Group* o = new Fl_Group(255, 45, 245, 260); + o->box(FL_ENGRAVED_FRAME); + { Fl_Box* o = new Fl_Box(260, 50, 235, 45, "Note: Not all the following settings are used (this depends on the operating \ +system, etc..)"); + o->labelfont(1); + o->labelsize(11); + o->align(FL_ALIGN_WRAP); + } // Fl_Box* o + { Fl_Group* o = new Fl_Group(260, 110, 235, 115, "Linux"); + o->box(FL_ENGRAVED_BOX); + o->labelfont(1); + o->labelsize(13); + o->align(FL_ALIGN_TOP_LEFT); + { Fl_File_Input* o = new Fl_File_Input(265, 180, 225, 35, "OSS Sequencer Device (/dev/...)"); + o->callback((Fl_Callback*)cb_OSS); + o->align(FL_ALIGN_TOP_LEFT); + o->insert(config.cfg.LinuxOSSSeqInDev); + } // Fl_File_Input* o + { Fl_File_Input* o = new Fl_File_Input(265, 130, 225, 35, "OSS Wave Out Device (/dev/...)"); + o->callback((Fl_Callback*)cb_OSS1); + o->align(FL_ALIGN_TOP_LEFT); + o->insert(config.cfg.LinuxOSSWaveOutDev); + } // Fl_File_Input* o + o->end(); + } // Fl_Group* o + { Fl_Group* o = new Fl_Group(260, 250, 235, 50, "Windows"); + o->box(FL_ENGRAVED_BOX); + o->labelfont(1); + o->labelsize(13); + o->align(FL_ALIGN_TOP_LEFT); + { Fl_Counter* o = new Fl_Counter(270, 270, 65, 20, "Midi In Dev"); + o->type(1); + o->labelsize(11); + o->minimum(0); + o->maximum(100); + o->step(1); + o->callback((Fl_Callback*)cb_Midi); + o->align(FL_ALIGN_TOP); + o->maximum(config.winmidimax-1); + o->value(config.cfg.WindowsMidiInId); + } // Fl_Counter* o + { Fl_Box* o = midiinputnamebox = new Fl_Box(340, 260, 150, 35, "Midi input device name"); + midiinputnamebox->labelfont(1); + midiinputnamebox->labelsize(11); + midiinputnamebox->align(196|FL_ALIGN_INSIDE); + o->label(config.winmididevices[config.cfg.WindowsMidiInId].name); + } // Fl_Box* midiinputnamebox + o->end(); + } // Fl_Group* o + o->end(); + } // Fl_Group* o + { Fl_Counter* o = new Fl_Counter(20, 215, 65, 15, "XML compression level"); + o->tooltip("gzip compression level (0 - uncompressed)"); + o->type(1); + o->labelsize(11); + o->minimum(0); + o->maximum(9); + o->step(1); + o->callback((Fl_Callback*)cb_XML); + o->align(FL_ALIGN_RIGHT); + o->value(config.cfg.GzipCompression); + } // Fl_Counter* o + { Fl_Choice* o = new Fl_Choice(175, 105, 75, 15, "PADsynth Interpolation"); + o->down_box(FL_BORDER_BOX); + o->labelsize(10); + o->textsize(11); + o->callback((Fl_Callback*)cb_PADsynth); + o->menu(menu_PADsynth); + o->value(config.cfg.Interpolation); + } // Fl_Choice* o + { Fl_Choice* o = new Fl_Choice(155, 235, 85, 20, "Virtual Keyboard Layout"); + o->down_box(FL_BORDER_BOX); + o->labelsize(12); + o->textfont(1); + o->textsize(11); + o->callback((Fl_Callback*)cb_Virtual); + o->menu(menu_Virtual); + o->value(config.cfg.VirKeybLayout); + } // Fl_Choice* o + o->end(); + } // Fl_Group* o + { Fl_Group* o = new Fl_Group(5, 25, 500, 285, "Bank root dirs"); + o->hide(); + { rootsbrowse = new Fl_Browser(15, 35, 485, 220); + rootsbrowse->type(2); + rootsbrowse->callback((Fl_Callback*)cb_rootsbrowse); + } // Fl_Browser* rootsbrowse + { Fl_Button* o = new Fl_Button(15, 265, 80, 35, "Add root directory..."); + o->box(FL_THIN_UP_BOX); + o->callback((Fl_Callback*)cb_Add); + o->align(FL_ALIGN_WRAP); + } // Fl_Button* o + { Fl_Button* o = removerootdirbutton = new Fl_Button(105, 265, 80, 35, "Remove root dir..."); + removerootdirbutton->box(FL_THIN_UP_BOX); + removerootdirbutton->callback((Fl_Callback*)cb_removerootdirbutton); + removerootdirbutton->align(FL_ALIGN_WRAP); + o->deactivate(); + } // Fl_Button* removerootdirbutton + { Fl_Button* o = makedefaultrootdirbutton = new Fl_Button(190, 265, 80, 35, "Make default"); + makedefaultrootdirbutton->box(FL_THIN_UP_BOX); + makedefaultrootdirbutton->callback((Fl_Callback*)cb_makedefaultrootdirbutton); + makedefaultrootdirbutton->align(FL_ALIGN_WRAP); + o->deactivate(); + } // Fl_Button* makedefaultrootdirbutton + o->end(); + } // Fl_Group* o + { Fl_Group* o = new Fl_Group(5, 25, 500, 285, "Presets dirs"); + o->hide(); + { presetbrowse = new Fl_Browser(15, 35, 485, 220); + presetbrowse->type(2); + presetbrowse->callback((Fl_Callback*)cb_presetbrowse); + } // Fl_Browser* presetbrowse + { Fl_Button* o = new Fl_Button(15, 265, 80, 35, "Add preset directory..."); + o->box(FL_THIN_UP_BOX); + o->callback((Fl_Callback*)cb_Add1); + o->align(FL_ALIGN_WRAP); + } // Fl_Button* o + { Fl_Button* o = removepresetbutton = new Fl_Button(105, 265, 80, 35, "Remove preset dir..."); + removepresetbutton->box(FL_THIN_UP_BOX); + removepresetbutton->callback((Fl_Callback*)cb_removepresetbutton); + removepresetbutton->align(FL_ALIGN_WRAP); + o->deactivate(); + } // Fl_Button* removepresetbutton + { Fl_Button* o = makedefaultpresetbutton = new Fl_Button(190, 265, 80, 35, "Make default"); + makedefaultpresetbutton->box(FL_THIN_UP_BOX); + makedefaultpresetbutton->callback((Fl_Callback*)cb_makedefaultpresetbutton); + makedefaultpresetbutton->align(FL_ALIGN_WRAP); + o->deactivate(); + } // Fl_Button* makedefaultpresetbutton + o->end(); + } // Fl_Group* o + o->end(); + } // Fl_Tabs* o + { Fl_Button* o = new Fl_Button(200, 315, 105, 20, "Close"); + o->box(FL_THIN_UP_BOX); + o->callback((Fl_Callback*)cb_Close); + } // Fl_Button* o + configwindow->end(); + } // Fl_Double_Window* configwindow + return configwindow; +} + +ConfigUI::ConfigUI() { + make_window(); +readbankcfg(); +readpresetcfg(); +} + +void ConfigUI::activatebutton_rootdir(bool active) { + if (active) { + removerootdirbutton->activate(); + makedefaultrootdirbutton->activate(); +}else{ + removerootdirbutton->deactivate(); + makedefaultrootdirbutton->deactivate(); +}; +} + +void ConfigUI::activatebutton_presetdir(bool active) { + if (active) { + removepresetbutton->activate(); + makedefaultpresetbutton->activate(); +}else{ + removepresetbutton->deactivate(); + makedefaultpresetbutton->deactivate(); +}; +} + +void ConfigUI::readbankcfg() { + rootsbrowse->clear(); + +for (int i=0;iadd(config.cfg.bankRootDirList[i]); +}; +} + +void ConfigUI::writebankcfg() { + config.clearbankrootdirlist(); + +for (int n=0;nsize();n++){ + config.cfg.bankRootDirList[n]=new char [MAX_STRING_SIZE]; + strncpy(config.cfg.bankRootDirList[n],rootsbrowse->text(n+1),MAX_STRING_SIZE); +}; +} + +void ConfigUI::readpresetcfg() { + presetbrowse->clear(); + +for (int i=0;iadd(config.cfg.presetsDirList[i]); +}; +} + +void ConfigUI::writepresetcfg() { + config.clearpresetsdirlist(); + +for (int n=0;nsize();n++){ + config.cfg.presetsDirList[n]=new char [MAX_STRING_SIZE]; + strncpy(config.cfg.presetsDirList[n],presetbrowse->text(n+1),MAX_STRING_SIZE); +}; +} + +int ConfigUI::getsamplerateorder() { + int smpr=config.cfg.SampleRate; +int order=0; +switch(smpr){ + case 16000:order=1;break; + case 22050:order=2;break; + case 32000:order=3;break; + case 44100:order=4;break; + case 48000:order=5;break; + case 88200:order=6;break; + case 96000:order=7;break; + default:order=0;break; +}; +return(order); +} + +void ConfigUI::setsamplerateinput() { + char *tmpbuf=new char[100]; +samplerateinput->cut(0,samplerateinput->maximum_size()); +snprintf(tmpbuf,100,"%d",config.cfg.SampleRate); +samplerateinput->insert(tmpbuf); +delete []tmpbuf; +} + +void ConfigUI::show() { + configwindow->show(); +} diff --git a/plugins/zynaddsubfx/src/UI/ConfigUI.fl b/plugins/zynaddsubfx/src/UI/ConfigUI.fl new file mode 100644 index 000000000..a17872f40 --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/ConfigUI.fl @@ -0,0 +1,447 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0106 +header_name {.h} +code_name {.cc} +decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} + +decl {//License: GNU GPL version 2 or later} {} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include "../globals.h"} {public +} + +decl {\#include "../Misc/Util.h"} {public +} + +decl {\#include "../Misc/Dump.h"} {public +} + +decl {extern Dump dump;} {public +} + +class ConfigUI {} { + Function {make_window()} {} { + Fl_Window configwindow { + label {ZynAddSubFX Settings} + callback {writebankcfg(); +o->hide();} + xywh {88 313 510 340} type Double hide + } { + Fl_Tabs {} { + xywh {5 5 500 305} + } { + Fl_Group {} { + label {Main settings} + xywh {5 25 500 285} + } { + Fl_Group {} { + label {Sample Rate} + xywh {15 45 165 30} box ENGRAVED_FRAME + } { + Fl_Choice {} { + callback {if ((int)o->value()==0) samplerateinput->activate(); + else samplerateinput->deactivate(); + +int samplerates[8]={44100,16000,22050,32000,44100,48000,88200,96000}; +config.cfg.SampleRate=samplerates[(int)o->value()]; + +setsamplerateinput();} + xywh {20 50 85 20} down_box BORDER_BOX textsize 10 + code0 {o->value(getsamplerateorder());} + } { + menuitem {} { + label Custom + xywh {10 10 100 20} labelfont 1 + } + menuitem {} { + label 16000Hz + xywh {30 30 100 20} labelfont 1 + } + menuitem {} { + label 22050Hz + xywh {20 20 100 20} labelfont 1 + } + menuitem {} { + label 32000Hz + xywh {30 30 100 20} labelfont 1 + } + menuitem {} { + label 44100Hz + xywh {40 40 100 20} labelfont 1 + } + menuitem {} { + label 48000Hz + xywh {50 50 100 20} labelfont 1 + } + menuitem {} { + label 88200Hz + xywh {60 60 100 20} labelfont 1 + } + menuitem {} { + label 96000Hz + xywh {70 70 100 20} labelfont 1 + } + } + Fl_Input samplerateinput { + callback {char *tmp; +config.cfg.SampleRate=strtoul(o->value(),&tmp,10);} + xywh {115 50 60 20} type Int textfont 1 + code0 {setsamplerateinput();} + code1 {if (getsamplerateorder()!=0) o->deactivate();} + } + } + Fl_Input {} { + label {Buffer Size} + callback {char *tmp; +config.cfg.SoundBufferSize=strtoul(o->value(),&tmp,10);} + tooltip {Internal Sound Buffer Size (samples)} xywh {190 45 60 20} type Int labelsize 11 align 129 textfont 1 + code0 {char *tmpbuf=new char[100];o->cut(0,o->maximum_size());} + code1 {snprintf(tmpbuf,100,"%d",config.cfg.SoundBufferSize);o->insert(tmpbuf);} + code2 {delete []tmpbuf;} + } + Fl_Light_Button {} { + label {Swap Stereo } + callback {config.cfg.SwapStereo=(int) o->value();} + xywh {20 80 85 20} box THIN_UP_BOX labelsize 10 + code0 {o->value(config.cfg.SwapStereo);} + } + Fl_Choice {} { + label OscilSize + callback {config.cfg.OscilSize=128<value();} + tooltip {ADSynth Oscillator Size (samples)} xywh {175 80 75 20} down_box BORDER_BOX labelfont 1 labelsize 11 textsize 10 + code0 {o->value( (int) (log(config.cfg.OscilSize/128.0-1.0)/log(2)) +1);} + } { + menuitem {} { + label 128 + xywh {25 25 100 20} labelfont 1 + } + menuitem {} { + label 256 + xywh {35 35 100 20} labelfont 1 + } + menuitem {} { + label 512 + xywh {45 45 100 20} labelfont 1 + } + menuitem {} { + label 1024 + xywh {45 45 100 20} labelfont 1 + } + menuitem {} { + label 2048 + xywh {55 55 100 20} labelfont 1 + } + menuitem {} { + label 4096 + xywh {55 55 100 20} labelfont 1 + } + menuitem {} { + label 8192 + xywh {65 65 100 20} labelfont 1 + } + menuitem {} { + label 16384 + xywh {75 75 100 20} labelfont 1 + } + } + Fl_Box {} { + label {Most settings has effect only after ZynAddSubFX is restarted.} + xywh {15 275 235 30} labelfont 1 labelsize 11 align 128 + } + Fl_Box {} { + label {Read the Readme.txt for other settings} + xywh {10 255 240 20} labelfont 1 labelsize 11 align 128 + } + Fl_Group {} { + xywh {15 125 230 85} box ENGRAVED_BOX + } { + Fl_File_Input {} { + label {Dump File} + callback {snprintf(config.cfg.DumpFile,config.maxstringsize,"%s",o->value());} + xywh {20 170 220 35} align 5 + code0 {o->insert(config.cfg.DumpFile);} + } + Fl_Check_Button {} { + label {Dump notes} + callback {config.cfg.DumpNotesToFile=(int) o->value(); +dump.startnow();//this has effect only if this option was disabled} + xywh {20 130 100 20} down_box DOWN_BOX + code0 {o->value(config.cfg.DumpNotesToFile);} + } + Fl_Check_Button {} { + label Append + callback {config.cfg.DumpAppend=(int) o->value();} + xywh {160 130 80 20} down_box DOWN_BOX + code0 {o->value(config.cfg.DumpAppend);} + } + } + Fl_Group {} { + xywh {255 45 245 260} box ENGRAVED_FRAME + } { + Fl_Box {} { + label {Note: Not all the following settings are used (this depends on the operating system, etc..)} + xywh {260 50 235 45} labelfont 1 labelsize 11 align 128 + } + Fl_Group {} { + label Linux + xywh {260 110 235 115} box ENGRAVED_BOX labelfont 1 labelsize 13 align 5 + } { + Fl_File_Input {} { + label {OSS Sequencer Device (/dev/...)} + callback {snprintf(config.cfg.LinuxOSSSeqInDev,config.maxstringsize,"%s",o->value());} + xywh {265 180 225 35} align 5 + code0 {o->insert(config.cfg.LinuxOSSSeqInDev);} + } + Fl_File_Input {} { + label {OSS Wave Out Device (/dev/...)} + callback {snprintf(config.cfg.LinuxOSSWaveOutDev,config.maxstringsize,"%s",o->value());} + xywh {265 130 225 35} align 5 + code0 {o->insert(config.cfg.LinuxOSSWaveOutDev);} + } + } + Fl_Group {} { + label Windows + xywh {260 250 235 50} box ENGRAVED_BOX labelfont 1 labelsize 13 align 5 + } { + Fl_Counter {} { + label {Midi In Dev} + callback {config.cfg.WindowsMidiInId=(int) o->value(); +midiinputnamebox->label(config.winmididevices[config.cfg.WindowsMidiInId].name);} + xywh {270 270 65 20} type Simple labelsize 11 align 1 minimum 0 maximum 100 step 1 + code0 {o->maximum(config.winmidimax-1);} + code1 {o->value(config.cfg.WindowsMidiInId);} + } + Fl_Box midiinputnamebox { + label {Midi input device name} + xywh {340 260 150 35} labelfont 1 labelsize 11 align 212 + code0 {o->label(config.winmididevices[config.cfg.WindowsMidiInId].name);} + } + } + } + Fl_Counter {} { + label {XML compression level} + callback {config.cfg.GzipCompression=(int) o->value();} + tooltip {gzip compression level (0 - uncompressed)} xywh {20 215 65 15} type Simple labelsize 11 align 8 minimum 0 maximum 9 step 1 + code0 {o->value(config.cfg.GzipCompression);} + } + Fl_Choice {} { + label {PADsynth Interpolation} + callback {config.cfg.Interpolation=(int) o->value();} + xywh {175 105 75 15} down_box BORDER_BOX labelsize 10 textsize 11 + code0 {o->value(config.cfg.Interpolation);} + } { + menuitem {} { + label {Linear(fast)} + xywh {0 0 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label {Cubic(slow)} + xywh {10 10 100 20} labelfont 1 labelsize 10 + } + } + Fl_Choice {} { + label {Virtual Keyboard Layout} + callback {config.cfg.VirKeybLayout=(int) o->value();;} open selected + xywh {155 235 85 20} down_box BORDER_BOX labelsize 12 textfont 1 textsize 11 + code0 {o->value(config.cfg.VirKeybLayout);} + } { + menuitem {} { + label { } + xywh {5 5 100 20} labelfont 1 labelsize 11 deactivate + } + menuitem {} { + label QWERTY + xywh {15 15 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label Dvorak + xywh {25 25 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label QWERTZ + xywh {35 35 100 20} labelfont 1 labelsize 11 + } + } + } + Fl_Group {} { + label {Bank root dirs} + xywh {5 25 500 285} hide + } { + Fl_Browser rootsbrowse { + callback {activatebutton_rootdir(o->value()!=0);} + xywh {15 35 485 220} type Hold + } + Fl_Button {} { + label {Add root directory...} + callback {const char *dirname; +dirname=fl_dir_chooser("Add a root directory for banks:",NULL,0); +if (dirname==NULL) return; + +rootsbrowse->add(dirname);} + xywh {15 265 80 35} box THIN_UP_BOX align 128 + } + Fl_Button removerootdirbutton { + label {Remove root dir...} + callback {if (rootsbrowse->value()!=0) { + rootsbrowse->remove(rootsbrowse->value()); +}; +activatebutton_rootdir(false);} + xywh {105 265 80 35} box THIN_UP_BOX align 128 + code0 {o->deactivate();} + } + Fl_Button makedefaultrootdirbutton { + label {Make default} + callback {int n=rootsbrowse->value(); + +if (n!=0) { + rootsbrowse->move(1,n); + rootsbrowse->value(1); + rootsbrowse->redraw(); +}; +activatebutton_rootdir(true);} + xywh {190 265 80 35} box THIN_UP_BOX align 128 + code0 {o->deactivate();} + } + } + Fl_Group {} { + label {Presets dirs} + xywh {5 25 500 285} hide + } { + Fl_Browser presetbrowse { + callback {activatebutton_presetdir(o->value()!=0);} + xywh {15 35 485 220} type Hold + } + Fl_Button {} { + label {Add preset directory...} + callback {const char *dirname; +dirname=fl_dir_chooser("Add a preset directory :",NULL,0); +if (dirname==NULL) return; + +presetbrowse->add(dirname);} + xywh {15 265 80 35} box THIN_UP_BOX align 128 + } + Fl_Button removepresetbutton { + label {Remove preset dir...} + callback {if (presetbrowse->value()!=0) { + presetbrowse->remove(presetbrowse->value()); +}; +activatebutton_presetdir(false);} + xywh {105 265 80 35} box THIN_UP_BOX align 128 + code0 {o->deactivate();} + } + Fl_Button makedefaultpresetbutton { + label {Make default} + callback {int n=presetbrowse->value(); + +if (n!=0) { + presetbrowse->move(1,n); + presetbrowse->value(1); + presetbrowse->redraw(); +}; +activatebutton_presetdir(true);} + xywh {190 265 80 35} box THIN_UP_BOX align 128 + code0 {o->deactivate();} + } + } + } + Fl_Button {} { + label Close + callback {configwindow->hide(); +writebankcfg(); +writepresetcfg();} + xywh {200 315 105 20} box THIN_UP_BOX + } + } + } + Function {ConfigUI()} {} { + code {make_window(); +readbankcfg(); +readpresetcfg();} {} + } + Function {activatebutton_rootdir(bool active)} {} { + code {if (active) { + removerootdirbutton->activate(); + makedefaultrootdirbutton->activate(); +}else{ + removerootdirbutton->deactivate(); + makedefaultrootdirbutton->deactivate(); +};} {} + } + Function {activatebutton_presetdir(bool active)} {} { + code {if (active) { + removepresetbutton->activate(); + makedefaultpresetbutton->activate(); +}else{ + removepresetbutton->deactivate(); + makedefaultpresetbutton->deactivate(); +};} {} + } + Function {readbankcfg()} {} { + code {rootsbrowse->clear(); + +for (int i=0;iadd(config.cfg.bankRootDirList[i]); +};} {} + } + Function {writebankcfg()} {} { + code {config.clearbankrootdirlist(); + +for (int n=0;nsize();n++){ + config.cfg.bankRootDirList[n]=new char [MAX_STRING_SIZE]; + strncpy(config.cfg.bankRootDirList[n],rootsbrowse->text(n+1),MAX_STRING_SIZE); +};} {} + } + Function {readpresetcfg()} {} { + code {presetbrowse->clear(); + +for (int i=0;iadd(config.cfg.presetsDirList[i]); +};} {} + } + Function {writepresetcfg()} {} { + code {config.clearpresetsdirlist(); + +for (int n=0;nsize();n++){ + config.cfg.presetsDirList[n]=new char [MAX_STRING_SIZE]; + strncpy(config.cfg.presetsDirList[n],presetbrowse->text(n+1),MAX_STRING_SIZE); +};} {} + } + Function {getsamplerateorder()} {return_type int + } { + code {int smpr=config.cfg.SampleRate; +int order=0; +switch(smpr){ + case 16000:order=1;break; + case 22050:order=2;break; + case 32000:order=3;break; + case 44100:order=4;break; + case 48000:order=5;break; + case 88200:order=6;break; + case 96000:order=7;break; + default:order=0;break; +}; +return(order);} {} + } + Function {setsamplerateinput()} {return_type void + } { + code {char *tmpbuf=new char[100]; +samplerateinput->cut(0,samplerateinput->maximum_size()); +snprintf(tmpbuf,100,"%d",config.cfg.SampleRate); +samplerateinput->insert(tmpbuf); +delete []tmpbuf;} {} + } + Function {show()} {} { + code {configwindow->show();} {} + } +} diff --git a/plugins/zynaddsubfx/src/UI/ConfigUI.h b/plugins/zynaddsubfx/src/UI/ConfigUI.h new file mode 100644 index 000000000..6cc47b9ab --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/ConfigUI.h @@ -0,0 +1,120 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0109 + +#ifndef ConfigUI_h +#define ConfigUI_h +#include +#include +#include +#include +#include +#include "../globals.h" +#include "../Misc/Util.h" +#include "../Misc/Dump.h" +extern Dump dump; +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class ConfigUI { +public: + Fl_Double_Window* make_window(); + Fl_Double_Window *configwindow; +private: + void cb_configwindow_i(Fl_Double_Window*, void*); + static void cb_configwindow(Fl_Double_Window*, void*); + void cb__i(Fl_Choice*, void*); + static void cb_(Fl_Choice*, void*); + static Fl_Menu_Item menu_[]; +public: + Fl_Input *samplerateinput; +private: + void cb_samplerateinput_i(Fl_Input*, void*); + static void cb_samplerateinput(Fl_Input*, void*); + void cb_Buffer_i(Fl_Input*, void*); + static void cb_Buffer(Fl_Input*, void*); + void cb_Swap_i(Fl_Light_Button*, void*); + static void cb_Swap(Fl_Light_Button*, void*); + void cb_OscilSize_i(Fl_Choice*, void*); + static void cb_OscilSize(Fl_Choice*, void*); + static Fl_Menu_Item menu_OscilSize[]; + void cb_Dump_i(Fl_File_Input*, void*); + static void cb_Dump(Fl_File_Input*, void*); + void cb_Dump1_i(Fl_Check_Button*, void*); + static void cb_Dump1(Fl_Check_Button*, void*); + void cb_Append_i(Fl_Check_Button*, void*); + static void cb_Append(Fl_Check_Button*, void*); + void cb_OSS_i(Fl_File_Input*, void*); + static void cb_OSS(Fl_File_Input*, void*); + void cb_OSS1_i(Fl_File_Input*, void*); + static void cb_OSS1(Fl_File_Input*, void*); + void cb_Midi_i(Fl_Counter*, void*); + static void cb_Midi(Fl_Counter*, void*); +public: + Fl_Box *midiinputnamebox; +private: + void cb_XML_i(Fl_Counter*, void*); + static void cb_XML(Fl_Counter*, void*); + void cb_PADsynth_i(Fl_Choice*, void*); + static void cb_PADsynth(Fl_Choice*, void*); + static Fl_Menu_Item menu_PADsynth[]; + void cb_Virtual_i(Fl_Choice*, void*); + static void cb_Virtual(Fl_Choice*, void*); + static Fl_Menu_Item menu_Virtual[]; +public: + Fl_Browser *rootsbrowse; +private: + void cb_rootsbrowse_i(Fl_Browser*, void*); + static void cb_rootsbrowse(Fl_Browser*, void*); + void cb_Add_i(Fl_Button*, void*); + static void cb_Add(Fl_Button*, void*); +public: + Fl_Button *removerootdirbutton; +private: + void cb_removerootdirbutton_i(Fl_Button*, void*); + static void cb_removerootdirbutton(Fl_Button*, void*); +public: + Fl_Button *makedefaultrootdirbutton; +private: + void cb_makedefaultrootdirbutton_i(Fl_Button*, void*); + static void cb_makedefaultrootdirbutton(Fl_Button*, void*); +public: + Fl_Browser *presetbrowse; +private: + void cb_presetbrowse_i(Fl_Browser*, void*); + static void cb_presetbrowse(Fl_Browser*, void*); + void cb_Add1_i(Fl_Button*, void*); + static void cb_Add1(Fl_Button*, void*); +public: + Fl_Button *removepresetbutton; +private: + void cb_removepresetbutton_i(Fl_Button*, void*); + static void cb_removepresetbutton(Fl_Button*, void*); +public: + Fl_Button *makedefaultpresetbutton; +private: + void cb_makedefaultpresetbutton_i(Fl_Button*, void*); + static void cb_makedefaultpresetbutton(Fl_Button*, void*); + void cb_Close_i(Fl_Button*, void*); + static void cb_Close(Fl_Button*, void*); +public: + ConfigUI(); + void activatebutton_rootdir(bool active); + void activatebutton_presetdir(bool active); + void readbankcfg(); + void writebankcfg(); + void readpresetcfg(); + void writepresetcfg(); + int getsamplerateorder(); + void setsamplerateinput(); + void show(); +}; +#endif diff --git a/plugins/zynaddsubfx/src/UI/EffUI.cc b/plugins/zynaddsubfx/src/UI/EffUI.cc new file mode 100644 index 000000000..ede3583e2 --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/EffUI.cc @@ -0,0 +1,4055 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0109 + +#include "EffUI.h" +//Copyright (c) 2002-2005 Nasca Octavian Paul +//License: GNU GPL version 2 or later + +EQGraph::EQGraph(int x,int y, int w, int h, const char *label):Fl_Box(x,y,w,h,label) { + eff=NULL; +maxdB=30; +} + +void EQGraph::init(EffectMgr *eff_) { + eff=eff_; +oldx=-1; +khzval=-1; +} + +void EQGraph::draw_freq_line(REALTYPE freq,int type) { + fl_color(FL_GRAY); +REALTYPE freqx=getfreqpos(freq); +switch(type){ + case 0:if (active_r()) fl_color(FL_WHITE); + else fl_color(205,205,205); + fl_line_style(FL_SOLID); + break; + case 1:fl_line_style(FL_DOT);break; + case 2:fl_line_style(FL_DASH);break; +}; + + +if ((freqx>0.0)&&(freqx<1.0)) + fl_line(x()+(int) (freqx*w()),y(), + x()+(int) (freqx*w()),y()+h()); +} + +void EQGraph::draw() { + int ox=x(),oy=y(),lx=w(),ly=h(),i,iy,oiy; +REALTYPE freqx; + +if (active_r()) fl_color(0,70,150); + else fl_color(80,120,160); +fl_rectf(ox,oy,lx,ly); + + +//draw the lines +fl_color(FL_GRAY); + +fl_line_style(FL_SOLID); +fl_line(ox+2,oy+ly/2,ox+lx-2,oy+ly/2); + +freqx=getfreqpos(1000.0); +if ((freqx>0.0)&&(freqx<1.0)) + fl_line(ox+(int) (freqx*lx),oy, + ox+(int) (freqx*lx),oy+ly); + +for (i=1;i<10;i++){ + if(i==1){ + draw_freq_line(i*100.0,0); + draw_freq_line(i*1000.0,0); + }else + if (i==5){ + draw_freq_line(i*10.0,2); + draw_freq_line(i*100.0,2); + draw_freq_line(i*1000.0,2); + }else{ + draw_freq_line(i*10.0,1); + draw_freq_line(i*100.0,1); + draw_freq_line(i*1000.0,1); + }; +}; + +draw_freq_line(10000.0,0); +draw_freq_line(20000.0,1); + + +fl_line_style(FL_DOT); +int GY=6;if (lySAMPLE_RATE/2) break; + iy=getresponse(ly,frq); + if ((oiy>=0) && (oiy=0) && (iygetEQfreqresponse(freq); +int idbresp=(int) ((dbresp/maxdB+1.0)*maxy/2.0); + + +//fprintf(stderr,"%.5f\n",(dbresp/maxdB+1.0)*maxy/2.0); + + +return(idbresp); +} + +REALTYPE EQGraph::getfreqx(REALTYPE x) { + if (x>1.0) x=1.0; +return(20.0*pow((REALTYPE)1000.0,x)); +} + +REALTYPE EQGraph::getfreqpos(REALTYPE freq) { + if (freq<0.00001) freq=0.00001; +return(log(freq/20.0)/log(1000.0)); +} + +void EffUI::cb_revp_i(Fl_Choice* o, void*) { + eff->changepreset((int)o->value()); + +refresh(eff); +} +void EffUI::cb_revp(Fl_Choice* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_revp_i(o,v); +} + +Fl_Menu_Item EffUI::menu_revp[] = { + {"Cathedral 1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Cathedral 2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Cathedral 3", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Hall 1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Hall 2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Room 1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Room 2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Basement", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Tunnel", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Echoed 1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Echoed 2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Very Long 1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Very Long 2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {0,0,0,0,0,0,0,0,0} +}; + +void EffUI::cb_revp10_i(Fl_Choice* o, void*) { + eff->seteffectpar(10,(int) o->value()); +} +void EffUI::cb_revp10(Fl_Choice* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_revp10_i(o,v); +} + +Fl_Menu_Item EffUI::menu_revp10[] = { + {"Random", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Freeverb", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {0,0,0,0,0,0,0,0,0} +}; + +void EffUI::cb_revp0_i(WidgetPDial* o, void*) { + eff->seteffectpar(0,(int) o->value()); +} +void EffUI::cb_revp0(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_revp0_i(o,v); +} + +void EffUI::cb_revp1_i(WidgetPDial* o, void*) { + eff->seteffectpar(1,(int) o->value()); +} +void EffUI::cb_revp1(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_revp1_i(o,v); +} + +void EffUI::cb_revp2_i(WidgetPDial* o, void*) { + eff->seteffectpar(2,(int) o->value()); +} +void EffUI::cb_revp2(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_revp2_i(o,v); +} + +void EffUI::cb_revp3_i(WidgetPDial* o, void*) { + eff->seteffectpar(3,(int) o->value()); +} +void EffUI::cb_revp3(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_revp3_i(o,v); +} + +void EffUI::cb_revp4_i(WidgetPDial* o, void*) { + eff->seteffectpar(4,(int) o->value()); +} +void EffUI::cb_revp4(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_revp4_i(o,v); +} + +void EffUI::cb_revp5_i(WidgetPDial* o, void*) { + eff->seteffectpar(5,(int) o->value()); +} +void EffUI::cb_revp5(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_revp5_i(o,v); +} + +void EffUI::cb_revp6_i(WidgetPDial* o, void*) { + eff->seteffectpar(6,(int) o->value()); +} +void EffUI::cb_revp6(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_revp6_i(o,v); +} + +void EffUI::cb_revp7_i(WidgetPDial* o, void*) { + eff->seteffectpar(7,(int) o->value()); +} +void EffUI::cb_revp7(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_revp7_i(o,v); +} + +void EffUI::cb_revp8_i(WidgetPDial* o, void*) { + eff->seteffectpar(8,(int) o->value()); +} +void EffUI::cb_revp8(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_revp8_i(o,v); +} + +void EffUI::cb_revp9_i(WidgetPDial* o, void*) { + eff->seteffectpar(9,(int) o->value()); +} +void EffUI::cb_revp9(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_revp9_i(o,v); +} + +void EffUI::cb_revp11_i(WidgetPDial* o, void*) { + int x=64; +if (Fl::event_button1()) x=(int)o->value(); + else o->value(x); +eff->seteffectpar(11,x); +} +void EffUI::cb_revp11(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_revp11_i(o,v); +} + +void EffUI::cb_echop_i(Fl_Choice* o, void*) { + eff->changepreset((int)o->value()); +refresh(eff); +} +void EffUI::cb_echop(Fl_Choice* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_echop_i(o,v); +} + +Fl_Menu_Item EffUI::menu_echop[] = { + {"Echo 1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Echo 2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Echo 3", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Simple Echo", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Canyon", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Panning Echo 1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Panning Echo 2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Panning Echo 3", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Feedback Echo", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {0,0,0,0,0,0,0,0,0} +}; + +void EffUI::cb_echop0_i(WidgetPDial* o, void*) { + eff->seteffectpar(0,(int) o->value()); +} +void EffUI::cb_echop0(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_echop0_i(o,v); +} + +void EffUI::cb_echop1_i(WidgetPDial* o, void*) { + eff->seteffectpar(1,(int) o->value()); +} +void EffUI::cb_echop1(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_echop1_i(o,v); +} + +void EffUI::cb_echop2_i(WidgetPDial* o, void*) { + eff->seteffectpar(2,(int) o->value()); +} +void EffUI::cb_echop2(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_echop2_i(o,v); +} + +void EffUI::cb_echop3_i(WidgetPDial* o, void*) { + eff->seteffectpar(3,(int) o->value()); +} +void EffUI::cb_echop3(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_echop3_i(o,v); +} + +void EffUI::cb_echop4_i(WidgetPDial* o, void*) { + eff->seteffectpar(4,(int) o->value()); +} +void EffUI::cb_echop4(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_echop4_i(o,v); +} + +void EffUI::cb_echop5_i(WidgetPDial* o, void*) { + eff->seteffectpar(5,(int) o->value()); +} +void EffUI::cb_echop5(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_echop5_i(o,v); +} + +void EffUI::cb_echop6_i(WidgetPDial* o, void*) { + eff->seteffectpar(6,(int) o->value()); +} +void EffUI::cb_echop6(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_echop6_i(o,v); +} + +void EffUI::cb_chorusp_i(Fl_Choice* o, void*) { + eff->changepreset((int)o->value()); +refresh(eff); +} +void EffUI::cb_chorusp(Fl_Choice* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_chorusp_i(o,v); +} + +Fl_Menu_Item EffUI::menu_chorusp[] = { + {"Chorus 1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Chorus 2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Chorus 3", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Celeste 1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Celeste 2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Flange 1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Flange 2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Flange 3", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Flange 4", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Flange 5", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {0,0,0,0,0,0,0,0,0} +}; + +void EffUI::cb_chorusp0_i(WidgetPDial* o, void*) { + eff->seteffectpar(0,(int) o->value()); +} +void EffUI::cb_chorusp0(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_chorusp0_i(o,v); +} + +void EffUI::cb_chorusp1_i(WidgetPDial* o, void*) { + eff->seteffectpar(1,(int) o->value()); +} +void EffUI::cb_chorusp1(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_chorusp1_i(o,v); +} + +void EffUI::cb_chorusp2_i(WidgetPDial* o, void*) { + eff->seteffectpar(2,(int) o->value()); +} +void EffUI::cb_chorusp2(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_chorusp2_i(o,v); +} + +void EffUI::cb_chorusp3_i(WidgetPDial* o, void*) { + eff->seteffectpar(3,(int) o->value()); +} +void EffUI::cb_chorusp3(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_chorusp3_i(o,v); +} + +void EffUI::cb_chorusp5_i(WidgetPDial* o, void*) { + eff->seteffectpar(5,(int) o->value()); +} +void EffUI::cb_chorusp5(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_chorusp5_i(o,v); +} + +void EffUI::cb_chorusp6_i(WidgetPDial* o, void*) { + eff->seteffectpar(6,(int) o->value()); +} +void EffUI::cb_chorusp6(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_chorusp6_i(o,v); +} + +void EffUI::cb_chorusp7_i(WidgetPDial* o, void*) { + eff->seteffectpar(7,(int) o->value()); +} +void EffUI::cb_chorusp7(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_chorusp7_i(o,v); +} + +void EffUI::cb_chorusp8_i(WidgetPDial* o, void*) { + eff->seteffectpar(8,(int) o->value()); +} +void EffUI::cb_chorusp8(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_chorusp8_i(o,v); +} + +void EffUI::cb_chorusp9_i(WidgetPDial* o, void*) { + eff->seteffectpar(9,(int) o->value()); +} +void EffUI::cb_chorusp9(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_chorusp9_i(o,v); +} + +void EffUI::cb_Flange_i(Fl_Check_Button* o, void*) { + eff->seteffectpar(10,(int) o->value()); +} +void EffUI::cb_Flange(Fl_Check_Button* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_Flange_i(o,v); +} + +void EffUI::cb_chorusp11_i(Fl_Check_Button* o, void*) { + eff->seteffectpar(11,(int) o->value()); +} +void EffUI::cb_chorusp11(Fl_Check_Button* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_chorusp11_i(o,v); +} + +void EffUI::cb_chorusp4_i(Fl_Choice* o, void*) { + eff->seteffectpar(4,(int) o->value()); +} +void EffUI::cb_chorusp4(Fl_Choice* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_chorusp4_i(o,v); +} + +Fl_Menu_Item EffUI::menu_chorusp4[] = { + {"SINE", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"TRI", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void EffUI::cb_phaserp_i(Fl_Choice* o, void*) { + eff->changepreset((int)o->value()); +refresh(eff); +} +void EffUI::cb_phaserp(Fl_Choice* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_phaserp_i(o,v); +} + +Fl_Menu_Item EffUI::menu_phaserp[] = { + {"Phaser 1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Phaser 2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Phaser 3", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Phaser 4", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Phaser 5", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Phaser 6", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {0,0,0,0,0,0,0,0,0} +}; + +void EffUI::cb_phaserp0_i(WidgetPDial* o, void*) { + eff->seteffectpar(0,(int) o->value()); +} +void EffUI::cb_phaserp0(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_phaserp0_i(o,v); +} + +void EffUI::cb_phaserp1_i(WidgetPDial* o, void*) { + eff->seteffectpar(1,(int) o->value()); +} +void EffUI::cb_phaserp1(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_phaserp1_i(o,v); +} + +void EffUI::cb_phaserp2_i(WidgetPDial* o, void*) { + eff->seteffectpar(2,(int) o->value()); +} +void EffUI::cb_phaserp2(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_phaserp2_i(o,v); +} + +void EffUI::cb_phaserp3_i(WidgetPDial* o, void*) { + eff->seteffectpar(3,(int) o->value()); +} +void EffUI::cb_phaserp3(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_phaserp3_i(o,v); +} + +void EffUI::cb_phaserp5_i(WidgetPDial* o, void*) { + eff->seteffectpar(5,(int) o->value()); +} +void EffUI::cb_phaserp5(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_phaserp5_i(o,v); +} + +void EffUI::cb_phaserp6_i(WidgetPDial* o, void*) { + eff->seteffectpar(6,(int) o->value()); +} +void EffUI::cb_phaserp6(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_phaserp6_i(o,v); +} + +void EffUI::cb_phaserp7_i(WidgetPDial* o, void*) { + eff->seteffectpar(7,(int) o->value()); +} +void EffUI::cb_phaserp7(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_phaserp7_i(o,v); +} + +void EffUI::cb_phaserp9_i(WidgetPDial* o, void*) { + eff->seteffectpar(9,(int) o->value()); +} +void EffUI::cb_phaserp9(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_phaserp9_i(o,v); +} + +void EffUI::cb_phaserp10_i(Fl_Check_Button* o, void*) { + eff->seteffectpar(10,(int) o->value()); +} +void EffUI::cb_phaserp10(Fl_Check_Button* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_phaserp10_i(o,v); +} + +void EffUI::cb_phaserp4_i(Fl_Choice* o, void*) { + eff->seteffectpar(4,(int) o->value()); +} +void EffUI::cb_phaserp4(Fl_Choice* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_phaserp4_i(o,v); +} + +Fl_Menu_Item EffUI::menu_phaserp4[] = { + {"SINE", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"TRI", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void EffUI::cb_phaserp8_i(Fl_Counter* o, void*) { + eff->seteffectpar(8,(int) o->value()); +} +void EffUI::cb_phaserp8(Fl_Counter* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_phaserp8_i(o,v); +} + +void EffUI::cb_phaserp11_i(WidgetPDial* o, void*) { + eff->seteffectpar(11,(int) o->value()); +} +void EffUI::cb_phaserp11(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_phaserp11_i(o,v); +} + +void EffUI::cb_awp_i(Fl_Choice* o, void*) { + eff->changepreset((int)o->value()); +refresh(eff); +} +void EffUI::cb_awp(Fl_Choice* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_awp_i(o,v); +} + +Fl_Menu_Item EffUI::menu_awp[] = { + {"Alienwah 1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Alienwah 2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Alienwah 3", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Alienwah 4", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {0,0,0,0,0,0,0,0,0} +}; + +void EffUI::cb_awp0_i(WidgetPDial* o, void*) { + eff->seteffectpar(0,(int) o->value()); +} +void EffUI::cb_awp0(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_awp0_i(o,v); +} + +void EffUI::cb_awp1_i(WidgetPDial* o, void*) { + eff->seteffectpar(1,(int) o->value()); +} +void EffUI::cb_awp1(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_awp1_i(o,v); +} + +void EffUI::cb_awp2_i(WidgetPDial* o, void*) { + eff->seteffectpar(2,(int) o->value()); +} +void EffUI::cb_awp2(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_awp2_i(o,v); +} + +void EffUI::cb_awp3_i(WidgetPDial* o, void*) { + eff->seteffectpar(3,(int) o->value()); +} +void EffUI::cb_awp3(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_awp3_i(o,v); +} + +void EffUI::cb_awp5_i(WidgetPDial* o, void*) { + eff->seteffectpar(5,(int) o->value()); +} +void EffUI::cb_awp5(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_awp5_i(o,v); +} + +void EffUI::cb_awp6_i(WidgetPDial* o, void*) { + eff->seteffectpar(6,(int) o->value()); +} +void EffUI::cb_awp6(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_awp6_i(o,v); +} + +void EffUI::cb_awp7_i(WidgetPDial* o, void*) { + eff->seteffectpar(7,(int) o->value()); +} +void EffUI::cb_awp7(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_awp7_i(o,v); +} + +void EffUI::cb_awp9_i(WidgetPDial* o, void*) { + eff->seteffectpar(9,(int) o->value()); +} +void EffUI::cb_awp9(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_awp9_i(o,v); +} + +void EffUI::cb_awp4_i(Fl_Choice* o, void*) { + eff->seteffectpar(4,(int) o->value()); +} +void EffUI::cb_awp4(Fl_Choice* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_awp4_i(o,v); +} + +Fl_Menu_Item EffUI::menu_awp4[] = { + {"SINE", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"TRI", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void EffUI::cb_awp10_i(WidgetPDial* o, void*) { + eff->seteffectpar(10,(int) o->value()); +} +void EffUI::cb_awp10(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_awp10_i(o,v); +} + +void EffUI::cb_awp8_i(Fl_Counter* o, void*) { + eff->seteffectpar(8,(int) o->value()); +} +void EffUI::cb_awp8(Fl_Counter* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_awp8_i(o,v); +} + +void EffUI::cb_distp_i(Fl_Choice* o, void*) { + eff->changepreset((int)o->value()); +refresh(eff); +} +void EffUI::cb_distp(Fl_Choice* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_distp_i(o,v); +} + +Fl_Menu_Item EffUI::menu_distp[] = { + {"Overdrive 1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Overdrive 2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"A. Exciter 1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"A. Exciter 2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Guitar Amp", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Quantisize", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {0,0,0,0,0,0,0,0,0} +}; + +void EffUI::cb_distp0_i(WidgetPDial* o, void*) { + eff->seteffectpar(0,(int) o->value()); +} +void EffUI::cb_distp0(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_distp0_i(o,v); +} + +void EffUI::cb_distp1_i(WidgetPDial* o, void*) { + eff->seteffectpar(1,(int) o->value()); +} +void EffUI::cb_distp1(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_distp1_i(o,v); +} + +void EffUI::cb_distp2_i(WidgetPDial* o, void*) { + eff->seteffectpar(2,(int) o->value()); +} +void EffUI::cb_distp2(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_distp2_i(o,v); +} + +void EffUI::cb_distp3_i(WidgetPDial* o, void*) { + eff->seteffectpar(3,(int) o->value()); +} +void EffUI::cb_distp3(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_distp3_i(o,v); +} + +void EffUI::cb_distp4_i(WidgetPDial* o, void*) { + eff->seteffectpar(4,(int) o->value()); +} +void EffUI::cb_distp4(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_distp4_i(o,v); +} + +void EffUI::cb_distp7_i(WidgetPDial* o, void*) { + eff->seteffectpar(7,(int) o->value()); +} +void EffUI::cb_distp7(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_distp7_i(o,v); +} + +void EffUI::cb_distp8_i(WidgetPDial* o, void*) { + eff->seteffectpar(8,(int) o->value()); +} +void EffUI::cb_distp8(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_distp8_i(o,v); +} + +void EffUI::cb_distp5_i(Fl_Choice* o, void*) { + eff->seteffectpar(5,(int) o->value()); +} +void EffUI::cb_distp5(Fl_Choice* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_distp5_i(o,v); +} + +Fl_Menu_Item EffUI::menu_distp5[] = { + {"Atan", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Asym1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Pow", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Sine", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Qnts", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Zigzg", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Lmt", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"LmtU", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"LmtL", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"ILmt", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Clip", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Asym2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Pow2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Sgm", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void EffUI::cb_distp6_i(Fl_Check_Button* o, void*) { + eff->seteffectpar(6,(int) o->value()); +} +void EffUI::cb_distp6(Fl_Check_Button* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_distp6_i(o,v); +} + +void EffUI::cb_distp9_i(Fl_Check_Button* o, void*) { + eff->seteffectpar(9,(int) o->value()); +} +void EffUI::cb_distp9(Fl_Check_Button* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_distp9_i(o,v); +} + +void EffUI::cb_distp10_i(Fl_Check_Button* o, void*) { + eff->seteffectpar(10,(int) o->value()); +} +void EffUI::cb_distp10(Fl_Check_Button* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_distp10_i(o,v); +} + +void EffUI::cb_eqp0_i(WidgetPDial* o, void*) { + eff->seteffectpar(0,(int) o->value()); +eqgraph->redraw(); +} +void EffUI::cb_eqp0(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_eqp0_i(o,v); +} + +void EffUI::cb_bandcounter_i(Fl_Counter* o, void*) { + eqband=(int) o->value(); +int npb=eqband*5+10; + +int type=eff->geteffectpar(npb); +typechoice->value(type); + +if (type>6) gaindial->activate(); + else gaindial->deactivate(); + +if (type==0) bandgroup->deactivate(); +else bandgroup->activate(); + +int freq=eff->geteffectpar(npb+1); +freqdial->value(freq); + +int gain=eff->geteffectpar(npb+2); +gaindial->value(gain); + +int q=eff->geteffectpar(npb+3); +qdial->value(q); + +int dbl=eff->geteffectpar(npb+4); +stagescounter->value(dbl); +} +void EffUI::cb_bandcounter(Fl_Counter* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_bandcounter_i(o,v); +} + +void EffUI::cb_freqdial_i(WidgetPDial* o, void*) { + int np=eqband*5+11; +eff->seteffectpar(np,(int) o->value()); +eqgraph->redraw(); +} +void EffUI::cb_freqdial(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->parent()->user_data()))->cb_freqdial_i(o,v); +} + +void EffUI::cb_gaindial_i(WidgetPDial* o, void*) { + int np=eqband*5+12; +eff->seteffectpar(np,(int) o->value()); +eqgraph->redraw(); +} +void EffUI::cb_gaindial(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->parent()->user_data()))->cb_gaindial_i(o,v); +} + +void EffUI::cb_qdial_i(WidgetPDial* o, void*) { + int np=eqband*5+13; +eff->seteffectpar(np,(int) o->value()); +eqgraph->redraw(); +} +void EffUI::cb_qdial(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->parent()->user_data()))->cb_qdial_i(o,v); +} + +void EffUI::cb_stagescounter_i(Fl_Counter* o, void*) { + int np=eqband*5+14; +eff->seteffectpar(np,(int) o->value()); +eqgraph->redraw(); +} +void EffUI::cb_stagescounter(Fl_Counter* o, void* v) { + ((EffUI*)(o->parent()->parent()->user_data()))->cb_stagescounter_i(o,v); +} + +void EffUI::cb_typechoice_i(Fl_Choice* o, void*) { + int np=eqband*5+10; +eff->seteffectpar(np,(int) o->value()); +bandcounter->do_callback(); +eqgraph->redraw(); +} +void EffUI::cb_typechoice(Fl_Choice* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_typechoice_i(o,v); +} + +Fl_Menu_Item EffUI::menu_typechoice[] = { + {"OFF", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Lp1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Hp1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Lp2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Hp2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Bp2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"N2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Pk", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"LSh", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"HSh", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void EffUI::cb_dfp_i(Fl_Choice* o, void*) { + eff->changepreset((int)o->value()); +refresh(eff); +} +void EffUI::cb_dfp(Fl_Choice* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_dfp_i(o,v); +} + +Fl_Menu_Item EffUI::menu_dfp[] = { + {"WahWah", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"AutoWah", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Sweep", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"VocalMorph1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"VocalMorph2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {0,0,0,0,0,0,0,0,0} +}; + +void EffUI::cb_dfp0_i(WidgetPDial* o, void*) { + eff->seteffectpar(0,(int) o->value()); +} +void EffUI::cb_dfp0(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_dfp0_i(o,v); +} + +void EffUI::cb_dfp1_i(WidgetPDial* o, void*) { + eff->seteffectpar(1,(int) o->value()); +} +void EffUI::cb_dfp1(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_dfp1_i(o,v); +} + +void EffUI::cb_dfp2_i(WidgetPDial* o, void*) { + eff->seteffectpar(2,(int) o->value()); +} +void EffUI::cb_dfp2(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_dfp2_i(o,v); +} + +void EffUI::cb_dfp3_i(WidgetPDial* o, void*) { + eff->seteffectpar(3,(int) o->value()); +} +void EffUI::cb_dfp3(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_dfp3_i(o,v); +} + +void EffUI::cb_dfp5_i(WidgetPDial* o, void*) { + eff->seteffectpar(5,(int) o->value()); +} +void EffUI::cb_dfp5(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_dfp5_i(o,v); +} + +void EffUI::cb_dfp6_i(WidgetPDial* o, void*) { + eff->seteffectpar(6,(int) o->value()); +} +void EffUI::cb_dfp6(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_dfp6_i(o,v); +} + +void EffUI::cb_dfp4_i(Fl_Choice* o, void*) { + eff->seteffectpar(4,(int) o->value()); +} +void EffUI::cb_dfp4(Fl_Choice* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_dfp4_i(o,v); +} + +Fl_Menu_Item EffUI::menu_dfp4[] = { + {"SINE", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"TRI", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void EffUI::cb_Filter_i(Fl_Button*, void*) { + filterwindow->show(); +} +void EffUI::cb_Filter(Fl_Button* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_Filter_i(o,v); +} + +void EffUI::cb_dfp7_i(WidgetPDial* o, void*) { + eff->seteffectpar(7,(int) o->value()); +} +void EffUI::cb_dfp7(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->parent()->user_data()))->cb_dfp7_i(o,v); +} + +void EffUI::cb_dfp9_i(WidgetPDial* o, void*) { + eff->seteffectpar(9,(int) o->value()); +} +void EffUI::cb_dfp9(WidgetPDial* o, void* v) { + ((EffUI*)(o->parent()->parent()->user_data()))->cb_dfp9_i(o,v); +} + +void EffUI::cb_dfp8_i(Fl_Check_Button* o, void*) { + eff->seteffectpar(8,(int) o->value()); +} +void EffUI::cb_dfp8(Fl_Check_Button* o, void* v) { + ((EffUI*)(o->parent()->parent()->user_data()))->cb_dfp8_i(o,v); +} + +void EffUI::cb_Close_i(Fl_Button*, void*) { + filterwindow->hide(); +} +void EffUI::cb_Close(Fl_Button* o, void* v) { + ((EffUI*)(o->parent()->user_data()))->cb_Close_i(o,v); +} + +EffUI::EffUI(int x,int y, int w, int h, const char *label):Fl_Group(x,y,w,h,label) { + eff=NULL; +filterwindow=NULL; +} + +EffUI::~EffUI() { + effnullwindow->hide();//delete (effnullwindow); +effreverbwindow->hide();//delete (effreverbwindow); +effechowindow->hide();//delete (effechowindow); +effchoruswindow->hide();//delete (effchoruswindow); +effphaserwindow->hide();//delete (effphaserwindow); +effalienwahwindow->hide();//delete (effalienwahwindow); +effdistorsionwindow->hide();//delete (effdistorsionwindow); +effeqwindow->hide();//delete (effeqwindow); +effdynamicfilterwindow->hide();//delete (effdynamicfilterwindow); + +if (filterwindow!=NULL){ + filterwindow->hide(); + delete(filterwindow); +}; +} + +Fl_Group* EffUI::make_null_window() { + { effnullwindow = new Fl_Group(0, 0, 380, 95); + effnullwindow->box(FL_PLASTIC_UP_BOX); + effnullwindow->color((Fl_Color)221); + effnullwindow->selection_color(FL_BACKGROUND_COLOR); + effnullwindow->labeltype(FL_NO_LABEL); + effnullwindow->labelfont(1); + effnullwindow->labelsize(14); + effnullwindow->labelcolor(FL_FOREGROUND_COLOR); + effnullwindow->user_data((void*)(this)); + effnullwindow->align(FL_ALIGN_TOP); + effnullwindow->when(FL_WHEN_RELEASE); + { Fl_Text_Display* o = new Fl_Text_Display(120, 35, 10, 20, "No Effect"); + o->box(FL_NO_BOX); + o->labeltype(FL_EMBOSSED_LABEL); + o->labelfont(1); + o->labelsize(22); + o->labelcolor((Fl_Color)43); + o->align(FL_ALIGN_RIGHT); + } // Fl_Text_Display* o + effnullwindow->end(); + } // Fl_Group* effnullwindow + return effnullwindow; +} + +Fl_Group* EffUI::make_reverb_window() { + { effreverbwindow = new Fl_Group(0, 0, 380, 95); + effreverbwindow->box(FL_PLASTIC_UP_BOX); + effreverbwindow->color((Fl_Color)221); + effreverbwindow->selection_color(FL_BACKGROUND_COLOR); + effreverbwindow->labeltype(FL_NO_LABEL); + effreverbwindow->labelfont(1); + effreverbwindow->labelsize(14); + effreverbwindow->labelcolor(FL_FOREGROUND_COLOR); + effreverbwindow->user_data((void*)(this)); + effreverbwindow->align(FL_ALIGN_TOP); + effreverbwindow->when(FL_WHEN_RELEASE); + { Fl_Text_Display* o = new Fl_Text_Display(275, 10, 10, 20, "Reverb "); + o->box(FL_NO_BOX); + o->labeltype(FL_EMBOSSED_LABEL); + o->labelfont(1); + o->labelsize(22); + o->align(FL_ALIGN_RIGHT); + } // Fl_Text_Display* o + { revp = new Fl_Choice(10, 15, 90, 15, "Preset"); + revp->down_box(FL_BORDER_BOX); + revp->color((Fl_Color)14); + revp->selection_color(FL_FOREGROUND_COLOR); + revp->labelfont(1); + revp->labelsize(10); + revp->textfont(1); + revp->textsize(10); + revp->textcolor(7); + revp->callback((Fl_Callback*)cb_revp); + revp->align(FL_ALIGN_TOP_LEFT); + revp->menu(menu_revp); + } // Fl_Choice* revp + { revp10 = new Fl_Choice(110, 15, 75, 15, "Type"); + revp10->down_box(FL_BORDER_BOX); + revp10->color((Fl_Color)14); + revp10->labelfont(1); + revp10->labelsize(10); + revp10->textfont(1); + revp10->textsize(10); + revp10->textcolor(7); + revp10->callback((Fl_Callback*)cb_revp10); + revp10->align(FL_ALIGN_TOP_LEFT); + revp10->menu(menu_revp10); + } // Fl_Choice* revp10 + { revp0 = new WidgetPDial(10, 40, 30, 30, "Vol"); + revp0->tooltip("Effect Volume"); + revp0->box(FL_ROUND_UP_BOX); + revp0->color(FL_BACKGROUND_COLOR); + revp0->selection_color(FL_INACTIVE_COLOR); + revp0->labeltype(FL_NORMAL_LABEL); + revp0->labelfont(1); + revp0->labelsize(11); + revp0->labelcolor(FL_FOREGROUND_COLOR); + revp0->maximum(127); + revp0->callback((Fl_Callback*)cb_revp0); + revp0->align(FL_ALIGN_BOTTOM); + revp0->when(FL_WHEN_CHANGED); + } // WidgetPDial* revp0 + { revp1 = new WidgetPDial(45, 40, 30, 30, "Pan"); + revp1->box(FL_ROUND_UP_BOX); + revp1->color(FL_BACKGROUND_COLOR); + revp1->selection_color(FL_INACTIVE_COLOR); + revp1->labeltype(FL_NORMAL_LABEL); + revp1->labelfont(1); + revp1->labelsize(11); + revp1->labelcolor(FL_FOREGROUND_COLOR); + revp1->maximum(127); + revp1->callback((Fl_Callback*)cb_revp1); + revp1->align(FL_ALIGN_BOTTOM); + revp1->when(FL_WHEN_CHANGED); + } // WidgetPDial* revp1 + { revp2 = new WidgetPDial(80, 40, 30, 30, "Time"); + revp2->tooltip("Duration of Effect"); + revp2->box(FL_ROUND_UP_BOX); + revp2->color(FL_BACKGROUND_COLOR); + revp2->selection_color(FL_INACTIVE_COLOR); + revp2->labeltype(FL_NORMAL_LABEL); + revp2->labelfont(1); + revp2->labelsize(11); + revp2->labelcolor(FL_FOREGROUND_COLOR); + revp2->maximum(127); + revp2->callback((Fl_Callback*)cb_revp2); + revp2->align(FL_ALIGN_BOTTOM); + revp2->when(FL_WHEN_CHANGED); + } // WidgetPDial* revp2 + { revp3 = new WidgetPDial(120, 40, 30, 30, "I.del"); + revp3->tooltip("Initial Delay"); + revp3->box(FL_ROUND_UP_BOX); + revp3->color(FL_BACKGROUND_COLOR); + revp3->selection_color(FL_INACTIVE_COLOR); + revp3->labeltype(FL_NORMAL_LABEL); + revp3->labelfont(1); + revp3->labelsize(11); + revp3->labelcolor(FL_FOREGROUND_COLOR); + revp3->maximum(127); + revp3->callback((Fl_Callback*)cb_revp3); + revp3->align(FL_ALIGN_BOTTOM); + revp3->when(FL_WHEN_RELEASE); + } // WidgetPDial* revp3 + { revp4 = new WidgetPDial(155, 40, 30, 30, "I.delfb"); + revp4->tooltip("Initial Delay Feedback"); + revp4->box(FL_ROUND_UP_BOX); + revp4->color(FL_BACKGROUND_COLOR); + revp4->selection_color(FL_INACTIVE_COLOR); + revp4->labeltype(FL_NORMAL_LABEL); + revp4->labelfont(1); + revp4->labelsize(11); + revp4->labelcolor(FL_FOREGROUND_COLOR); + revp4->maximum(127); + revp4->callback((Fl_Callback*)cb_revp4); + revp4->align(FL_ALIGN_BOTTOM); + revp4->when(FL_WHEN_CHANGED); + } // WidgetPDial* revp4 + { revp5 = new WidgetPDial(200, 40, 30, 30, "R.delay"); + revp5->box(FL_ROUND_UP_BOX); + revp5->color(FL_BACKGROUND_COLOR); + revp5->selection_color(FL_INACTIVE_COLOR); + revp5->labeltype(FL_NORMAL_LABEL); + revp5->labelfont(1); + revp5->labelsize(11); + revp5->labelcolor(FL_FOREGROUND_COLOR); + revp5->maximum(127); + revp5->callback((Fl_Callback*)cb_revp5); + revp5->align(FL_ALIGN_BOTTOM); + revp5->when(FL_WHEN_RELEASE); + revp5->deactivate(); + } // WidgetPDial* revp5 + { revp6 = new WidgetPDial(235, 40, 30, 30, "E/R"); + revp6->box(FL_ROUND_UP_BOX); + revp6->color(FL_BACKGROUND_COLOR); + revp6->selection_color(FL_INACTIVE_COLOR); + revp6->labeltype(FL_NORMAL_LABEL); + revp6->labelfont(1); + revp6->labelsize(11); + revp6->labelcolor(FL_FOREGROUND_COLOR); + revp6->maximum(127); + revp6->callback((Fl_Callback*)cb_revp6); + revp6->align(FL_ALIGN_BOTTOM); + revp6->when(FL_WHEN_CHANGED); + revp6->deactivate(); + } // WidgetPDial* revp6 + { revp7 = new WidgetPDial(270, 40, 30, 30, "LPF"); + revp7->tooltip("Low Pass Filter"); + revp7->box(FL_ROUND_UP_BOX); + revp7->color(FL_BACKGROUND_COLOR); + revp7->selection_color(FL_INACTIVE_COLOR); + revp7->labeltype(FL_NORMAL_LABEL); + revp7->labelfont(1); + revp7->labelsize(11); + revp7->labelcolor(FL_FOREGROUND_COLOR); + revp7->maximum(127); + revp7->callback((Fl_Callback*)cb_revp7); + revp7->align(FL_ALIGN_BOTTOM); + revp7->when(FL_WHEN_CHANGED); + } // WidgetPDial* revp7 + { revp8 = new WidgetPDial(305, 40, 30, 30, "HPF"); + revp8->tooltip("High Pass Filter"); + revp8->box(FL_ROUND_UP_BOX); + revp8->color(FL_BACKGROUND_COLOR); + revp8->selection_color(FL_INACTIVE_COLOR); + revp8->labeltype(FL_NORMAL_LABEL); + revp8->labelfont(1); + revp8->labelsize(11); + revp8->labelcolor(FL_FOREGROUND_COLOR); + revp8->maximum(127); + revp8->callback((Fl_Callback*)cb_revp8); + revp8->align(FL_ALIGN_BOTTOM); + revp8->when(FL_WHEN_CHANGED); + } // WidgetPDial* revp8 + { revp9 = new WidgetPDial(340, 40, 30, 30, "Damp"); + revp9->tooltip("Dampening"); + revp9->box(FL_ROUND_UP_BOX); + revp9->color(FL_BACKGROUND_COLOR); + revp9->selection_color(FL_INACTIVE_COLOR); + revp9->labeltype(FL_NORMAL_LABEL); + revp9->labelfont(1); + revp9->labelsize(11); + revp9->labelcolor(FL_FOREGROUND_COLOR); + revp9->minimum(64); + revp9->maximum(127); + revp9->step(1); + revp9->callback((Fl_Callback*)cb_revp9); + revp9->align(FL_ALIGN_BOTTOM); + revp9->when(FL_WHEN_CHANGED); + } // WidgetPDial* revp9 + { revp11 = new WidgetPDial(190, 10, 25, 25, "R.S."); + revp11->tooltip("RoomSize"); + revp11->box(FL_ROUND_UP_BOX); + revp11->color(FL_BACKGROUND_COLOR); + revp11->selection_color(FL_INACTIVE_COLOR); + revp11->labeltype(FL_NORMAL_LABEL); + revp11->labelfont(1); + revp11->labelsize(8); + revp11->labelcolor(FL_FOREGROUND_COLOR); + revp11->minimum(1); + revp11->maximum(127); + revp11->step(1); + revp11->callback((Fl_Callback*)cb_revp11); + revp11->align(FL_ALIGN_RIGHT); + revp11->when(FL_WHEN_CHANGED); + } // WidgetPDial* revp11 + effreverbwindow->end(); + } // Fl_Group* effreverbwindow + return effreverbwindow; +} + +Fl_Group* EffUI::make_echo_window() { + { effechowindow = new Fl_Group(0, 0, 380, 95); + effechowindow->box(FL_PLASTIC_UP_BOX); + effechowindow->color((Fl_Color)221); + effechowindow->selection_color(FL_BACKGROUND_COLOR); + effechowindow->labeltype(FL_NO_LABEL); + effechowindow->labelfont(1); + effechowindow->labelsize(14); + effechowindow->labelcolor(FL_FOREGROUND_COLOR); + effechowindow->user_data((void*)(this)); + effechowindow->align(FL_ALIGN_TOP); + effechowindow->when(FL_WHEN_RELEASE); + { echop = new Fl_Choice(11, 15, 95, 15, "Preset"); + echop->down_box(FL_BORDER_BOX); + echop->color((Fl_Color)14); + echop->selection_color(FL_FOREGROUND_COLOR); + echop->labelfont(1); + echop->labelsize(10); + echop->textfont(1); + echop->textsize(10); + echop->textcolor(7); + echop->callback((Fl_Callback*)cb_echop); + echop->align(FL_ALIGN_TOP_LEFT); + echop->menu(menu_echop); + } // Fl_Choice* echop + { Fl_Text_Display* o = new Fl_Text_Display(295, 10, 10, 20, "Echo"); + o->box(FL_NO_BOX); + o->labeltype(FL_EMBOSSED_LABEL); + o->labelfont(1); + o->labelsize(22); + o->align(FL_ALIGN_RIGHT); + } // Fl_Text_Display* o + { echop0 = new WidgetPDial(10, 40, 30, 30, "Vol"); + echop0->tooltip("Effect Volume"); + echop0->box(FL_ROUND_UP_BOX); + echop0->color(FL_BACKGROUND_COLOR); + echop0->selection_color(FL_INACTIVE_COLOR); + echop0->labeltype(FL_NORMAL_LABEL); + echop0->labelfont(1); + echop0->labelsize(11); + echop0->labelcolor(FL_FOREGROUND_COLOR); + echop0->maximum(127); + echop0->callback((Fl_Callback*)cb_echop0); + echop0->align(FL_ALIGN_BOTTOM); + echop0->when(FL_WHEN_CHANGED); + } // WidgetPDial* echop0 + { echop1 = new WidgetPDial(45, 40, 30, 30, "Pan"); + echop1->box(FL_ROUND_UP_BOX); + echop1->color(FL_BACKGROUND_COLOR); + echop1->selection_color(FL_INACTIVE_COLOR); + echop1->labeltype(FL_NORMAL_LABEL); + echop1->labelfont(1); + echop1->labelsize(11); + echop1->labelcolor(FL_FOREGROUND_COLOR); + echop1->maximum(127); + echop1->callback((Fl_Callback*)cb_echop1); + echop1->align(FL_ALIGN_BOTTOM); + echop1->when(FL_WHEN_CHANGED); + } // WidgetPDial* echop1 + { echop2 = new WidgetPDial(80, 40, 30, 30, "Delay"); + echop2->box(FL_ROUND_UP_BOX); + echop2->color(FL_BACKGROUND_COLOR); + echop2->selection_color(FL_INACTIVE_COLOR); + echop2->labeltype(FL_NORMAL_LABEL); + echop2->labelfont(1); + echop2->labelsize(11); + echop2->labelcolor(FL_FOREGROUND_COLOR); + echop2->maximum(127); + echop2->callback((Fl_Callback*)cb_echop2); + echop2->align(FL_ALIGN_BOTTOM); + echop2->when(FL_WHEN_RELEASE); + } // WidgetPDial* echop2 + { echop3 = new WidgetPDial(120, 40, 30, 30, "LRdl."); + echop3->tooltip("Delay Between L/R"); + echop3->box(FL_ROUND_UP_BOX); + echop3->color(FL_BACKGROUND_COLOR); + echop3->selection_color(FL_INACTIVE_COLOR); + echop3->labeltype(FL_NORMAL_LABEL); + echop3->labelfont(1); + echop3->labelsize(11); + echop3->labelcolor(FL_FOREGROUND_COLOR); + echop3->maximum(127); + echop3->callback((Fl_Callback*)cb_echop3); + echop3->align(FL_ALIGN_BOTTOM); + echop3->when(FL_WHEN_RELEASE); + } // WidgetPDial* echop3 + { echop4 = new WidgetPDial(155, 40, 30, 30, "LRc."); + echop4->tooltip("L/R Crossover"); + echop4->box(FL_ROUND_UP_BOX); + echop4->color(FL_BACKGROUND_COLOR); + echop4->selection_color(FL_INACTIVE_COLOR); + echop4->labeltype(FL_NORMAL_LABEL); + echop4->labelfont(1); + echop4->labelsize(11); + echop4->labelcolor(FL_FOREGROUND_COLOR); + echop4->maximum(127); + echop4->callback((Fl_Callback*)cb_echop4); + echop4->align(FL_ALIGN_BOTTOM); + echop4->when(FL_WHEN_CHANGED); + } // WidgetPDial* echop4 + { echop5 = new WidgetPDial(195, 40, 30, 30, "Fb."); + echop5->tooltip("Feedback"); + echop5->box(FL_ROUND_UP_BOX); + echop5->color(FL_BACKGROUND_COLOR); + echop5->selection_color(FL_INACTIVE_COLOR); + echop5->labeltype(FL_NORMAL_LABEL); + echop5->labelfont(1); + echop5->labelsize(11); + echop5->labelcolor(FL_FOREGROUND_COLOR); + echop5->maximum(127); + echop5->callback((Fl_Callback*)cb_echop5); + echop5->align(FL_ALIGN_BOTTOM); + echop5->when(FL_WHEN_CHANGED); + } // WidgetPDial* echop5 + { echop6 = new WidgetPDial(235, 40, 30, 30, "Damp"); + echop6->tooltip("Dampening"); + echop6->box(FL_ROUND_UP_BOX); + echop6->color(FL_BACKGROUND_COLOR); + echop6->selection_color(FL_INACTIVE_COLOR); + echop6->labeltype(FL_NORMAL_LABEL); + echop6->labelfont(1); + echop6->labelsize(11); + echop6->labelcolor(FL_FOREGROUND_COLOR); + echop6->maximum(127); + echop6->callback((Fl_Callback*)cb_echop6); + echop6->align(FL_ALIGN_BOTTOM); + echop6->when(FL_WHEN_CHANGED); + } // WidgetPDial* echop6 + effechowindow->end(); + } // Fl_Group* effechowindow + return effechowindow; +} + +Fl_Group* EffUI::make_chorus_window() { + { effchoruswindow = new Fl_Group(0, 0, 380, 95); + effchoruswindow->box(FL_PLASTIC_UP_BOX); + effchoruswindow->color((Fl_Color)221); + effchoruswindow->selection_color(FL_BACKGROUND_COLOR); + effchoruswindow->labeltype(FL_NO_LABEL); + effchoruswindow->labelfont(1); + effchoruswindow->labelsize(14); + effchoruswindow->labelcolor(FL_FOREGROUND_COLOR); + effchoruswindow->user_data((void*)(this)); + effchoruswindow->align(FL_ALIGN_TOP); + effchoruswindow->when(FL_WHEN_RELEASE); + { chorusp = new Fl_Choice(10, 15, 90, 15, "Preset"); + chorusp->down_box(FL_BORDER_BOX); + chorusp->color((Fl_Color)14); + chorusp->selection_color(FL_FOREGROUND_COLOR); + chorusp->labelfont(1); + chorusp->labelsize(10); + chorusp->textfont(1); + chorusp->textsize(10); + chorusp->textcolor(7); + chorusp->callback((Fl_Callback*)cb_chorusp); + chorusp->align(FL_ALIGN_TOP_LEFT); + chorusp->menu(menu_chorusp); + } // Fl_Choice* chorusp + { Fl_Text_Display* o = new Fl_Text_Display(265, 10, 10, 20, "Chorus"); + o->box(FL_NO_BOX); + o->labeltype(FL_EMBOSSED_LABEL); + o->labelfont(1); + o->labelsize(22); + o->align(FL_ALIGN_RIGHT); + } // Fl_Text_Display* o + { chorusp0 = new WidgetPDial(10, 40, 30, 30, "Vol"); + chorusp0->box(FL_ROUND_UP_BOX); + chorusp0->color(FL_BACKGROUND_COLOR); + chorusp0->selection_color(FL_INACTIVE_COLOR); + chorusp0->labeltype(FL_NORMAL_LABEL); + chorusp0->labelfont(1); + chorusp0->labelsize(11); + chorusp0->labelcolor(FL_FOREGROUND_COLOR); + chorusp0->maximum(127); + chorusp0->callback((Fl_Callback*)cb_chorusp0); + chorusp0->align(FL_ALIGN_BOTTOM); + chorusp0->when(FL_WHEN_CHANGED); + } // WidgetPDial* chorusp0 + { chorusp1 = new WidgetPDial(45, 40, 30, 30, "Pan"); + chorusp1->box(FL_ROUND_UP_BOX); + chorusp1->color(FL_BACKGROUND_COLOR); + chorusp1->selection_color(FL_INACTIVE_COLOR); + chorusp1->labeltype(FL_NORMAL_LABEL); + chorusp1->labelfont(1); + chorusp1->labelsize(11); + chorusp1->labelcolor(FL_FOREGROUND_COLOR); + chorusp1->maximum(127); + chorusp1->callback((Fl_Callback*)cb_chorusp1); + chorusp1->align(FL_ALIGN_BOTTOM); + chorusp1->when(FL_WHEN_CHANGED); + } // WidgetPDial* chorusp1 + { chorusp2 = new WidgetPDial(85, 40, 30, 30, "Freq"); + chorusp2->tooltip("LFO Frequency"); + chorusp2->box(FL_ROUND_UP_BOX); + chorusp2->color(FL_BACKGROUND_COLOR); + chorusp2->selection_color(FL_INACTIVE_COLOR); + chorusp2->labeltype(FL_NORMAL_LABEL); + chorusp2->labelfont(1); + chorusp2->labelsize(11); + chorusp2->labelcolor(FL_FOREGROUND_COLOR); + chorusp2->maximum(127); + chorusp2->callback((Fl_Callback*)cb_chorusp2); + chorusp2->align(FL_ALIGN_BOTTOM); + chorusp2->when(FL_WHEN_CHANGED); + } // WidgetPDial* chorusp2 + { chorusp3 = new WidgetPDial(120, 40, 30, 30, "Rnd"); + chorusp3->tooltip("LFO Randomness"); + chorusp3->box(FL_ROUND_UP_BOX); + chorusp3->color(FL_BACKGROUND_COLOR); + chorusp3->selection_color(FL_INACTIVE_COLOR); + chorusp3->labeltype(FL_NORMAL_LABEL); + chorusp3->labelfont(1); + chorusp3->labelsize(11); + chorusp3->labelcolor(FL_FOREGROUND_COLOR); + chorusp3->maximum(127); + chorusp3->callback((Fl_Callback*)cb_chorusp3); + chorusp3->align(FL_ALIGN_BOTTOM); + chorusp3->when(FL_WHEN_RELEASE); + } // WidgetPDial* chorusp3 + { chorusp5 = new WidgetPDial(200, 40, 30, 30, "St.df"); + chorusp5->tooltip("L/R Phase Shift"); + chorusp5->box(FL_ROUND_UP_BOX); + chorusp5->color(FL_BACKGROUND_COLOR); + chorusp5->selection_color(FL_INACTIVE_COLOR); + chorusp5->labeltype(FL_NORMAL_LABEL); + chorusp5->labelfont(1); + chorusp5->labelsize(11); + chorusp5->labelcolor(FL_FOREGROUND_COLOR); + chorusp5->maximum(127); + chorusp5->callback((Fl_Callback*)cb_chorusp5); + chorusp5->align(FL_ALIGN_BOTTOM); + chorusp5->when(FL_WHEN_CHANGED); + } // WidgetPDial* chorusp5 + { chorusp6 = new WidgetPDial(235, 40, 30, 30, "Dpth"); + chorusp6->tooltip("LFO Depth"); + chorusp6->box(FL_ROUND_UP_BOX); + chorusp6->color(FL_BACKGROUND_COLOR); + chorusp6->selection_color(FL_INACTIVE_COLOR); + chorusp6->labeltype(FL_NORMAL_LABEL); + chorusp6->labelfont(1); + chorusp6->labelsize(11); + chorusp6->labelcolor(FL_FOREGROUND_COLOR); + chorusp6->maximum(127); + chorusp6->callback((Fl_Callback*)cb_chorusp6); + chorusp6->align(FL_ALIGN_BOTTOM); + chorusp6->when(FL_WHEN_CHANGED); + } // WidgetPDial* chorusp6 + { chorusp7 = new WidgetPDial(270, 40, 30, 30, "Delay"); + chorusp7->box(FL_ROUND_UP_BOX); + chorusp7->color(FL_BACKGROUND_COLOR); + chorusp7->selection_color(FL_INACTIVE_COLOR); + chorusp7->labeltype(FL_NORMAL_LABEL); + chorusp7->labelfont(1); + chorusp7->labelsize(11); + chorusp7->labelcolor(FL_FOREGROUND_COLOR); + chorusp7->maximum(127); + chorusp7->callback((Fl_Callback*)cb_chorusp7); + chorusp7->align(FL_ALIGN_BOTTOM); + chorusp7->when(FL_WHEN_CHANGED); + } // WidgetPDial* chorusp7 + { chorusp8 = new WidgetPDial(305, 40, 30, 30, "Fb"); + chorusp8->tooltip("Feedback"); + chorusp8->box(FL_ROUND_UP_BOX); + chorusp8->color(FL_BACKGROUND_COLOR); + chorusp8->selection_color(FL_INACTIVE_COLOR); + chorusp8->labeltype(FL_NORMAL_LABEL); + chorusp8->labelfont(1); + chorusp8->labelsize(11); + chorusp8->labelcolor(FL_FOREGROUND_COLOR); + chorusp8->maximum(127); + chorusp8->callback((Fl_Callback*)cb_chorusp8); + chorusp8->align(FL_ALIGN_BOTTOM); + chorusp8->when(FL_WHEN_CHANGED); + } // WidgetPDial* chorusp8 + { chorusp9 = new WidgetPDial(340, 40, 30, 30, "L/R"); + chorusp9->tooltip("Channel Routing"); + chorusp9->box(FL_ROUND_UP_BOX); + chorusp9->color(FL_BACKGROUND_COLOR); + chorusp9->selection_color(FL_INACTIVE_COLOR); + chorusp9->labeltype(FL_NORMAL_LABEL); + chorusp9->labelfont(1); + chorusp9->labelsize(11); + chorusp9->labelcolor(FL_FOREGROUND_COLOR); + chorusp9->maximum(127); + chorusp9->callback((Fl_Callback*)cb_chorusp9); + chorusp9->align(FL_ALIGN_BOTTOM); + chorusp9->when(FL_WHEN_CHANGED); + } // WidgetPDial* chorusp9 + { Fl_Check_Button* o = new Fl_Check_Button(120, 10, 55, 20, "Flange"); + o->box(FL_THIN_UP_BOX); + o->down_box(FL_DOWN_BOX); + o->color((Fl_Color)230); + o->labelfont(1); + o->labelsize(10); + o->callback((Fl_Callback*)cb_Flange); + o->hide(); + o->deactivate(); + o->value(eff->geteffectpar(10)); + } // Fl_Check_Button* o + { chorusp11 = new Fl_Check_Button(185, 10, 70, 20, "Substract"); + chorusp11->tooltip("inverts the output"); + chorusp11->box(FL_THIN_UP_BOX); + chorusp11->down_box(FL_DOWN_BOX); + chorusp11->color((Fl_Color)230); + chorusp11->labelfont(1); + chorusp11->labelsize(10); + chorusp11->callback((Fl_Callback*)cb_chorusp11); + } // Fl_Check_Button* chorusp11 + { chorusp4 = new Fl_Choice(155, 50, 40, 15, "LFO type"); + chorusp4->tooltip("LFO function"); + chorusp4->down_box(FL_BORDER_BOX); + chorusp4->labelfont(1); + chorusp4->labelsize(10); + chorusp4->textsize(8); + chorusp4->callback((Fl_Callback*)cb_chorusp4); + chorusp4->align(130); + chorusp4->menu(menu_chorusp4); + } // Fl_Choice* chorusp4 + effchoruswindow->end(); + } // Fl_Group* effchoruswindow + return effchoruswindow; +} + +Fl_Group* EffUI::make_phaser_window() { + { effphaserwindow = new Fl_Group(0, 0, 380, 95); + effphaserwindow->box(FL_PLASTIC_UP_BOX); + effphaserwindow->color((Fl_Color)221); + effphaserwindow->selection_color(FL_BACKGROUND_COLOR); + effphaserwindow->labeltype(FL_NO_LABEL); + effphaserwindow->labelfont(1); + effphaserwindow->labelsize(14); + effphaserwindow->labelcolor(FL_FOREGROUND_COLOR); + effphaserwindow->user_data((void*)(this)); + effphaserwindow->align(FL_ALIGN_TOP); + effphaserwindow->when(FL_WHEN_RELEASE); + { phaserp = new Fl_Choice(10, 15, 90, 15, "Preset"); + phaserp->down_box(FL_BORDER_BOX); + phaserp->color((Fl_Color)14); + phaserp->selection_color(FL_FOREGROUND_COLOR); + phaserp->labelfont(1); + phaserp->labelsize(10); + phaserp->textfont(1); + phaserp->textsize(10); + phaserp->textcolor(7); + phaserp->callback((Fl_Callback*)cb_phaserp); + phaserp->align(FL_ALIGN_TOP_LEFT); + phaserp->menu(menu_phaserp); + } // Fl_Choice* phaserp + { Fl_Text_Display* o = new Fl_Text_Display(275, 10, 10, 20, "Phaser"); + o->box(FL_NO_BOX); + o->labeltype(FL_EMBOSSED_LABEL); + o->labelfont(1); + o->labelsize(22); + o->align(FL_ALIGN_RIGHT); + } // Fl_Text_Display* o + { phaserp0 = new WidgetPDial(10, 40, 30, 30, "Vol"); + phaserp0->tooltip("Effect Volume"); + phaserp0->box(FL_ROUND_UP_BOX); + phaserp0->color(FL_BACKGROUND_COLOR); + phaserp0->selection_color(FL_INACTIVE_COLOR); + phaserp0->labeltype(FL_NORMAL_LABEL); + phaserp0->labelfont(1); + phaserp0->labelsize(11); + phaserp0->labelcolor(FL_FOREGROUND_COLOR); + phaserp0->maximum(127); + phaserp0->callback((Fl_Callback*)cb_phaserp0); + phaserp0->align(FL_ALIGN_BOTTOM); + phaserp0->when(FL_WHEN_CHANGED); + } // WidgetPDial* phaserp0 + { phaserp1 = new WidgetPDial(45, 40, 30, 30, "Pan"); + phaserp1->box(FL_ROUND_UP_BOX); + phaserp1->color(FL_BACKGROUND_COLOR); + phaserp1->selection_color(FL_INACTIVE_COLOR); + phaserp1->labeltype(FL_NORMAL_LABEL); + phaserp1->labelfont(1); + phaserp1->labelsize(11); + phaserp1->labelcolor(FL_FOREGROUND_COLOR); + phaserp1->maximum(127); + phaserp1->callback((Fl_Callback*)cb_phaserp1); + phaserp1->align(FL_ALIGN_BOTTOM); + phaserp1->when(FL_WHEN_CHANGED); + } // WidgetPDial* phaserp1 + { phaserp2 = new WidgetPDial(85, 40, 30, 30, "Freq"); + phaserp2->tooltip("LFO frequency"); + phaserp2->box(FL_ROUND_UP_BOX); + phaserp2->color(FL_BACKGROUND_COLOR); + phaserp2->selection_color(FL_INACTIVE_COLOR); + phaserp2->labeltype(FL_NORMAL_LABEL); + phaserp2->labelfont(1); + phaserp2->labelsize(11); + phaserp2->labelcolor(FL_FOREGROUND_COLOR); + phaserp2->maximum(127); + phaserp2->callback((Fl_Callback*)cb_phaserp2); + phaserp2->align(FL_ALIGN_BOTTOM); + phaserp2->when(FL_WHEN_CHANGED); + } // WidgetPDial* phaserp2 + { phaserp3 = new WidgetPDial(120, 40, 30, 30, "Rnd"); + phaserp3->tooltip("LFO randomness"); + phaserp3->box(FL_ROUND_UP_BOX); + phaserp3->color(FL_BACKGROUND_COLOR); + phaserp3->selection_color(FL_INACTIVE_COLOR); + phaserp3->labeltype(FL_NORMAL_LABEL); + phaserp3->labelfont(1); + phaserp3->labelsize(11); + phaserp3->labelcolor(FL_FOREGROUND_COLOR); + phaserp3->maximum(127); + phaserp3->callback((Fl_Callback*)cb_phaserp3); + phaserp3->align(FL_ALIGN_BOTTOM); + phaserp3->when(FL_WHEN_RELEASE); + } // WidgetPDial* phaserp3 + { phaserp5 = new WidgetPDial(200, 40, 30, 30, "St.df"); + phaserp5->tooltip("Left/Right Channel Phase Shift"); + phaserp5->box(FL_ROUND_UP_BOX); + phaserp5->color(FL_BACKGROUND_COLOR); + phaserp5->selection_color(FL_INACTIVE_COLOR); + phaserp5->labeltype(FL_NORMAL_LABEL); + phaserp5->labelfont(1); + phaserp5->labelsize(11); + phaserp5->labelcolor(FL_FOREGROUND_COLOR); + phaserp5->maximum(127); + phaserp5->callback((Fl_Callback*)cb_phaserp5); + phaserp5->align(FL_ALIGN_BOTTOM); + phaserp5->when(FL_WHEN_CHANGED); + } // WidgetPDial* phaserp5 + { phaserp6 = new WidgetPDial(235, 40, 30, 30, "Dpth"); + phaserp6->tooltip("LFO Depth"); + phaserp6->box(FL_ROUND_UP_BOX); + phaserp6->color(FL_BACKGROUND_COLOR); + phaserp6->selection_color(FL_INACTIVE_COLOR); + phaserp6->labeltype(FL_NORMAL_LABEL); + phaserp6->labelfont(1); + phaserp6->labelsize(11); + phaserp6->labelcolor(FL_FOREGROUND_COLOR); + phaserp6->maximum(127); + phaserp6->callback((Fl_Callback*)cb_phaserp6); + phaserp6->align(FL_ALIGN_BOTTOM); + phaserp6->when(FL_WHEN_CHANGED); + } // WidgetPDial* phaserp6 + { phaserp7 = new WidgetPDial(270, 40, 30, 30, "Fb"); + phaserp7->tooltip("Feedback"); + phaserp7->box(FL_ROUND_UP_BOX); + phaserp7->color(FL_BACKGROUND_COLOR); + phaserp7->selection_color(FL_INACTIVE_COLOR); + phaserp7->labeltype(FL_NORMAL_LABEL); + phaserp7->labelfont(1); + phaserp7->labelsize(11); + phaserp7->labelcolor(FL_FOREGROUND_COLOR); + phaserp7->maximum(127); + phaserp7->callback((Fl_Callback*)cb_phaserp7); + phaserp7->align(FL_ALIGN_BOTTOM); + phaserp7->when(FL_WHEN_CHANGED); + } // WidgetPDial* phaserp7 + { phaserp9 = new WidgetPDial(345, 40, 30, 30, "L/R"); + phaserp9->tooltip("Channel Routing"); + phaserp9->box(FL_ROUND_UP_BOX); + phaserp9->color(FL_BACKGROUND_COLOR); + phaserp9->selection_color(FL_INACTIVE_COLOR); + phaserp9->labeltype(FL_NORMAL_LABEL); + phaserp9->labelfont(1); + phaserp9->labelsize(11); + phaserp9->labelcolor(FL_FOREGROUND_COLOR); + phaserp9->maximum(127); + phaserp9->callback((Fl_Callback*)cb_phaserp9); + phaserp9->align(FL_ALIGN_BOTTOM); + phaserp9->when(FL_WHEN_CHANGED); + } // WidgetPDial* phaserp9 + { phaserp10 = new Fl_Check_Button(185, 10, 74, 20, "Substract"); + phaserp10->tooltip("inverts output"); + phaserp10->box(FL_THIN_UP_BOX); + phaserp10->down_box(FL_DOWN_BOX); + phaserp10->color((Fl_Color)230); + phaserp10->labelfont(1); + phaserp10->labelsize(10); + phaserp10->callback((Fl_Callback*)cb_phaserp10); + } // Fl_Check_Button* phaserp10 + { phaserp4 = new Fl_Choice(155, 50, 40, 15, "LFO type"); + phaserp4->tooltip("LFO function"); + phaserp4->down_box(FL_BORDER_BOX); + phaserp4->labelfont(1); + phaserp4->labelsize(10); + phaserp4->textsize(8); + phaserp4->callback((Fl_Callback*)cb_phaserp4); + phaserp4->align(130); + phaserp4->menu(menu_phaserp4); + } // Fl_Choice* phaserp4 + { Fl_Counter* o = phaserp8 = new Fl_Counter(305, 55, 35, 15, "Stages"); + phaserp8->type(1); + phaserp8->labelfont(1); + phaserp8->labelsize(11); + phaserp8->minimum(0); + phaserp8->maximum(127); + phaserp8->step(1); + phaserp8->callback((Fl_Callback*)cb_phaserp8); + o->range(1,MAX_PHASER_STAGES); + } // Fl_Counter* phaserp8 + { phaserp11 = new WidgetPDial(155, 10, 25, 25, "Phase"); + phaserp11->box(FL_ROUND_UP_BOX); + phaserp11->color(FL_BACKGROUND_COLOR); + phaserp11->selection_color(FL_INACTIVE_COLOR); + phaserp11->labeltype(FL_NORMAL_LABEL); + phaserp11->labelfont(1); + phaserp11->labelsize(10); + phaserp11->labelcolor(FL_FOREGROUND_COLOR); + phaserp11->maximum(127); + phaserp11->callback((Fl_Callback*)cb_phaserp11); + phaserp11->align(FL_ALIGN_BOTTOM); + phaserp11->when(FL_WHEN_CHANGED); + } // WidgetPDial* phaserp11 + effphaserwindow->end(); + } // Fl_Group* effphaserwindow + return effphaserwindow; +} + +Fl_Group* EffUI::make_alienwah_window() { + { effalienwahwindow = new Fl_Group(0, 0, 380, 95); + effalienwahwindow->box(FL_PLASTIC_UP_BOX); + effalienwahwindow->color((Fl_Color)221); + effalienwahwindow->selection_color(FL_BACKGROUND_COLOR); + effalienwahwindow->labeltype(FL_NO_LABEL); + effalienwahwindow->labelfont(1); + effalienwahwindow->labelsize(14); + effalienwahwindow->labelcolor(FL_FOREGROUND_COLOR); + effalienwahwindow->user_data((void*)(this)); + effalienwahwindow->align(FL_ALIGN_TOP); + effalienwahwindow->when(FL_WHEN_RELEASE); + { awp = new Fl_Choice(10, 15, 90, 15, "Preset"); + awp->down_box(FL_BORDER_BOX); + awp->color((Fl_Color)14); + awp->selection_color(FL_FOREGROUND_COLOR); + awp->labelfont(1); + awp->labelsize(10); + awp->textfont(1); + awp->textsize(10); + awp->textcolor(7); + awp->callback((Fl_Callback*)cb_awp); + awp->align(FL_ALIGN_TOP_LEFT); + awp->menu(menu_awp); + } // Fl_Choice* awp + { Fl_Text_Display* o = new Fl_Text_Display(245, 10, 10, 20, "AlienWah"); + o->box(FL_NO_BOX); + o->labeltype(FL_EMBOSSED_LABEL); + o->labelfont(1); + o->labelsize(22); + o->align(FL_ALIGN_RIGHT); + } // Fl_Text_Display* o + { awp0 = new WidgetPDial(10, 40, 30, 30, "Vol"); + awp0->tooltip("Effect Volume"); + awp0->box(FL_ROUND_UP_BOX); + awp0->color(FL_BACKGROUND_COLOR); + awp0->selection_color(FL_INACTIVE_COLOR); + awp0->labeltype(FL_NORMAL_LABEL); + awp0->labelfont(1); + awp0->labelsize(11); + awp0->labelcolor(FL_FOREGROUND_COLOR); + awp0->maximum(127); + awp0->callback((Fl_Callback*)cb_awp0); + awp0->align(FL_ALIGN_BOTTOM); + awp0->when(FL_WHEN_CHANGED); + } // WidgetPDial* awp0 + { awp1 = new WidgetPDial(45, 40, 30, 30, "Pan"); + awp1->box(FL_ROUND_UP_BOX); + awp1->color(FL_BACKGROUND_COLOR); + awp1->selection_color(FL_INACTIVE_COLOR); + awp1->labeltype(FL_NORMAL_LABEL); + awp1->labelfont(1); + awp1->labelsize(11); + awp1->labelcolor(FL_FOREGROUND_COLOR); + awp1->maximum(127); + awp1->callback((Fl_Callback*)cb_awp1); + awp1->align(FL_ALIGN_BOTTOM); + awp1->when(FL_WHEN_CHANGED); + } // WidgetPDial* awp1 + { awp2 = new WidgetPDial(85, 40, 30, 30, "Freq"); + awp2->tooltip("LFO Frequency"); + awp2->box(FL_ROUND_UP_BOX); + awp2->color(FL_BACKGROUND_COLOR); + awp2->selection_color(FL_INACTIVE_COLOR); + awp2->labeltype(FL_NORMAL_LABEL); + awp2->labelfont(1); + awp2->labelsize(11); + awp2->labelcolor(FL_FOREGROUND_COLOR); + awp2->maximum(127); + awp2->callback((Fl_Callback*)cb_awp2); + awp2->align(FL_ALIGN_BOTTOM); + awp2->when(FL_WHEN_CHANGED); + } // WidgetPDial* awp2 + { awp3 = new WidgetPDial(120, 40, 30, 30, "Rnd"); + awp3->tooltip("LFO Randomness"); + awp3->box(FL_ROUND_UP_BOX); + awp3->color(FL_BACKGROUND_COLOR); + awp3->selection_color(FL_INACTIVE_COLOR); + awp3->labeltype(FL_NORMAL_LABEL); + awp3->labelfont(1); + awp3->labelsize(11); + awp3->labelcolor(FL_FOREGROUND_COLOR); + awp3->maximum(127); + awp3->callback((Fl_Callback*)cb_awp3); + awp3->align(FL_ALIGN_BOTTOM); + awp3->when(FL_WHEN_RELEASE); + } // WidgetPDial* awp3 + { awp5 = new WidgetPDial(200, 40, 30, 30, "St.df"); + awp5->tooltip("Left/Right Channel Phase Shift"); + awp5->box(FL_ROUND_UP_BOX); + awp5->color(FL_BACKGROUND_COLOR); + awp5->selection_color(FL_INACTIVE_COLOR); + awp5->labeltype(FL_NORMAL_LABEL); + awp5->labelfont(1); + awp5->labelsize(11); + awp5->labelcolor(FL_FOREGROUND_COLOR); + awp5->maximum(127); + awp5->callback((Fl_Callback*)cb_awp5); + awp5->align(FL_ALIGN_BOTTOM); + awp5->when(FL_WHEN_CHANGED); + } // WidgetPDial* awp5 + { awp6 = new WidgetPDial(235, 40, 30, 30, "Dpth"); + awp6->tooltip("Depth"); + awp6->box(FL_ROUND_UP_BOX); + awp6->color(FL_BACKGROUND_COLOR); + awp6->selection_color(FL_INACTIVE_COLOR); + awp6->labeltype(FL_NORMAL_LABEL); + awp6->labelfont(1); + awp6->labelsize(11); + awp6->labelcolor(FL_FOREGROUND_COLOR); + awp6->maximum(127); + awp6->callback((Fl_Callback*)cb_awp6); + awp6->align(FL_ALIGN_BOTTOM); + awp6->when(FL_WHEN_CHANGED); + } // WidgetPDial* awp6 + { awp7 = new WidgetPDial(270, 40, 30, 30, "Fb"); + awp7->tooltip("Feedback"); + awp7->box(FL_ROUND_UP_BOX); + awp7->color(FL_BACKGROUND_COLOR); + awp7->selection_color(FL_INACTIVE_COLOR); + awp7->labeltype(FL_NORMAL_LABEL); + awp7->labelfont(1); + awp7->labelsize(11); + awp7->labelcolor(FL_FOREGROUND_COLOR); + awp7->maximum(127); + awp7->callback((Fl_Callback*)cb_awp7); + awp7->align(FL_ALIGN_BOTTOM); + awp7->when(FL_WHEN_CHANGED); + } // WidgetPDial* awp7 + { awp9 = new WidgetPDial(345, 40, 30, 30, "L/R"); + awp9->box(FL_ROUND_UP_BOX); + awp9->color(FL_BACKGROUND_COLOR); + awp9->selection_color(FL_INACTIVE_COLOR); + awp9->labeltype(FL_NORMAL_LABEL); + awp9->labelfont(1); + awp9->labelsize(11); + awp9->labelcolor(FL_FOREGROUND_COLOR); + awp9->maximum(127); + awp9->callback((Fl_Callback*)cb_awp9); + awp9->align(FL_ALIGN_BOTTOM); + awp9->when(FL_WHEN_CHANGED); + } // WidgetPDial* awp9 + { awp4 = new Fl_Choice(155, 50, 40, 15, "LFO type"); + awp4->tooltip("LFO function"); + awp4->down_box(FL_BORDER_BOX); + awp4->labelfont(1); + awp4->labelsize(10); + awp4->textsize(8); + awp4->callback((Fl_Callback*)cb_awp4); + awp4->align(130); + awp4->menu(menu_awp4); + } // Fl_Choice* awp4 + { awp10 = new WidgetPDial(160, 5, 30, 30, "Phase"); + awp10->box(FL_ROUND_UP_BOX); + awp10->color(FL_BACKGROUND_COLOR); + awp10->selection_color(FL_INACTIVE_COLOR); + awp10->labeltype(FL_NORMAL_LABEL); + awp10->labelfont(1); + awp10->labelsize(11); + awp10->labelcolor(FL_FOREGROUND_COLOR); + awp10->maximum(127); + awp10->callback((Fl_Callback*)cb_awp10); + awp10->align(FL_ALIGN_BOTTOM); + awp10->when(FL_WHEN_CHANGED); + } // WidgetPDial* awp10 + { Fl_Counter* o = awp8 = new Fl_Counter(305, 55, 35, 15, "Delay"); + awp8->type(1); + awp8->labelfont(1); + awp8->labelsize(11); + awp8->minimum(0); + awp8->maximum(127); + awp8->step(1); + awp8->callback((Fl_Callback*)cb_awp8); + o->range(1,MAX_ALIENWAH_DELAY); + } // Fl_Counter* awp8 + effalienwahwindow->end(); + } // Fl_Group* effalienwahwindow + return effalienwahwindow; +} + +Fl_Group* EffUI::make_distorsion_window() { + { effdistorsionwindow = new Fl_Group(0, 0, 380, 95); + effdistorsionwindow->box(FL_PLASTIC_UP_BOX); + effdistorsionwindow->color((Fl_Color)221); + effdistorsionwindow->selection_color(FL_BACKGROUND_COLOR); + effdistorsionwindow->labeltype(FL_NO_LABEL); + effdistorsionwindow->labelfont(1); + effdistorsionwindow->labelsize(14); + effdistorsionwindow->labelcolor(FL_FOREGROUND_COLOR); + effdistorsionwindow->user_data((void*)(this)); + effdistorsionwindow->align(FL_ALIGN_TOP); + effdistorsionwindow->when(FL_WHEN_RELEASE); + { distp = new Fl_Choice(11, 15, 95, 15, "Preset"); + distp->down_box(FL_BORDER_BOX); + distp->color((Fl_Color)14); + distp->selection_color(FL_FOREGROUND_COLOR); + distp->labelfont(1); + distp->labelsize(10); + distp->textfont(1); + distp->textsize(10); + distp->textcolor(7); + distp->callback((Fl_Callback*)cb_distp); + distp->align(FL_ALIGN_TOP_LEFT); + distp->menu(menu_distp); + } // Fl_Choice* distp + { Fl_Text_Display* o = new Fl_Text_Display(230, 10, 10, 20, "Distortion"); + o->box(FL_NO_BOX); + o->labeltype(FL_EMBOSSED_LABEL); + o->labelfont(1); + o->labelsize(22); + o->align(FL_ALIGN_RIGHT); + } // Fl_Text_Display* o + { distp0 = new WidgetPDial(10, 40, 30, 30, "Vol"); + distp0->tooltip("Effect Volume"); + distp0->box(FL_ROUND_UP_BOX); + distp0->color(FL_BACKGROUND_COLOR); + distp0->selection_color(FL_INACTIVE_COLOR); + distp0->labeltype(FL_NORMAL_LABEL); + distp0->labelfont(1); + distp0->labelsize(11); + distp0->labelcolor(FL_FOREGROUND_COLOR); + distp0->maximum(127); + distp0->callback((Fl_Callback*)cb_distp0); + distp0->align(FL_ALIGN_BOTTOM); + distp0->when(FL_WHEN_CHANGED); + } // WidgetPDial* distp0 + { distp1 = new WidgetPDial(45, 40, 30, 30, "Pan"); + distp1->box(FL_ROUND_UP_BOX); + distp1->color(FL_BACKGROUND_COLOR); + distp1->selection_color(FL_INACTIVE_COLOR); + distp1->labeltype(FL_NORMAL_LABEL); + distp1->labelfont(1); + distp1->labelsize(11); + distp1->labelcolor(FL_FOREGROUND_COLOR); + distp1->maximum(127); + distp1->callback((Fl_Callback*)cb_distp1); + distp1->align(FL_ALIGN_BOTTOM); + distp1->when(FL_WHEN_CHANGED); + } // WidgetPDial* distp1 + { distp2 = new WidgetPDial(80, 40, 30, 30, "LRc."); + distp2->tooltip("L/R Mix"); + distp2->box(FL_ROUND_UP_BOX); + distp2->color(FL_BACKGROUND_COLOR); + distp2->selection_color(FL_INACTIVE_COLOR); + distp2->labeltype(FL_NORMAL_LABEL); + distp2->labelfont(1); + distp2->labelsize(11); + distp2->labelcolor(FL_FOREGROUND_COLOR); + distp2->maximum(127); + distp2->callback((Fl_Callback*)cb_distp2); + distp2->align(FL_ALIGN_BOTTOM); + distp2->when(FL_WHEN_RELEASE); + } // WidgetPDial* distp2 + { distp3 = new WidgetPDial(120, 40, 30, 30, "Drive"); + distp3->tooltip("Input Amplification"); + distp3->box(FL_ROUND_UP_BOX); + distp3->color(FL_BACKGROUND_COLOR); + distp3->selection_color(FL_INACTIVE_COLOR); + distp3->labeltype(FL_NORMAL_LABEL); + distp3->labelfont(1); + distp3->labelsize(11); + distp3->labelcolor(FL_FOREGROUND_COLOR); + distp3->maximum(127); + distp3->callback((Fl_Callback*)cb_distp3); + distp3->align(FL_ALIGN_BOTTOM); + distp3->when(FL_WHEN_RELEASE); + } // WidgetPDial* distp3 + { distp4 = new WidgetPDial(155, 40, 30, 30, "Level"); + distp4->tooltip("Output Amplification"); + distp4->box(FL_ROUND_UP_BOX); + distp4->color(FL_BACKGROUND_COLOR); + distp4->selection_color(FL_INACTIVE_COLOR); + distp4->labeltype(FL_NORMAL_LABEL); + distp4->labelfont(1); + distp4->labelsize(11); + distp4->labelcolor(FL_FOREGROUND_COLOR); + distp4->maximum(127); + distp4->callback((Fl_Callback*)cb_distp4); + distp4->align(FL_ALIGN_BOTTOM); + distp4->when(FL_WHEN_CHANGED); + } // WidgetPDial* distp4 + { distp7 = new WidgetPDial(285, 40, 30, 30, "LPF"); + distp7->tooltip("Low Pass Filter"); + distp7->box(FL_ROUND_UP_BOX); + distp7->color(FL_BACKGROUND_COLOR); + distp7->selection_color(FL_INACTIVE_COLOR); + distp7->labeltype(FL_NORMAL_LABEL); + distp7->labelfont(1); + distp7->labelsize(11); + distp7->labelcolor(FL_FOREGROUND_COLOR); + distp7->maximum(127); + distp7->callback((Fl_Callback*)cb_distp7); + distp7->align(FL_ALIGN_BOTTOM); + distp7->when(FL_WHEN_CHANGED); + } // WidgetPDial* distp7 + { distp8 = new WidgetPDial(320, 40, 30, 30, "HPF"); + distp8->tooltip("High Pass Filter"); + distp8->box(FL_ROUND_UP_BOX); + distp8->color(FL_BACKGROUND_COLOR); + distp8->selection_color(FL_INACTIVE_COLOR); + distp8->labeltype(FL_NORMAL_LABEL); + distp8->labelfont(1); + distp8->labelsize(11); + distp8->labelcolor(FL_FOREGROUND_COLOR); + distp8->maximum(127); + distp8->callback((Fl_Callback*)cb_distp8); + distp8->align(FL_ALIGN_BOTTOM); + distp8->when(FL_WHEN_CHANGED); + } // WidgetPDial* distp8 + { distp5 = new Fl_Choice(190, 50, 60, 20, "Type"); + distp5->box(FL_UP_BOX); + distp5->down_box(FL_BORDER_BOX); + distp5->labelfont(1); + distp5->labelsize(11); + distp5->textsize(10); + distp5->callback((Fl_Callback*)cb_distp5); + distp5->align(FL_ALIGN_BOTTOM); + distp5->menu(menu_distp5); + } // Fl_Choice* distp5 + { distp6 = new Fl_Check_Button(260, 55, 15, 15, "Neg."); + distp6->down_box(FL_DOWN_BOX); + distp6->labelfont(1); + distp6->labelsize(11); + distp6->callback((Fl_Callback*)cb_distp6); + distp6->align(FL_ALIGN_BOTTOM); + } // Fl_Check_Button* distp6 + { distp9 = new Fl_Check_Button(355, 60, 15, 15, "St."); + distp9->tooltip("Stereo"); + distp9->down_box(FL_DOWN_BOX); + distp9->labelfont(1); + distp9->labelsize(11); + distp9->callback((Fl_Callback*)cb_distp9); + distp9->align(FL_ALIGN_BOTTOM); + } // Fl_Check_Button* distp9 + { distp10 = new Fl_Check_Button(355, 44, 15, 15, "PF"); + distp10->tooltip("Applies the filters(before or after) the distorsion"); + distp10->down_box(FL_DOWN_BOX); + distp10->labelfont(1); + distp10->labelsize(11); + distp10->callback((Fl_Callback*)cb_distp10); + distp10->align(FL_ALIGN_TOP); + } // Fl_Check_Button* distp10 + effdistorsionwindow->end(); + } // Fl_Group* effdistorsionwindow + return effdistorsionwindow; +} + +Fl_Group* EffUI::make_eq_window() { + { effeqwindow = new Fl_Group(0, 0, 380, 95); + effeqwindow->box(FL_PLASTIC_UP_BOX); + effeqwindow->color((Fl_Color)221); + effeqwindow->selection_color(FL_BACKGROUND_COLOR); + effeqwindow->labeltype(FL_NO_LABEL); + effeqwindow->labelfont(1); + effeqwindow->labelsize(14); + effeqwindow->labelcolor(FL_FOREGROUND_COLOR); + effeqwindow->user_data((void*)(this)); + effeqwindow->align(FL_ALIGN_TOP); + effeqwindow->when(FL_WHEN_RELEASE); + { Fl_Text_Display* o = new Fl_Text_Display(320, 10, 15, 20, "EQ"); + o->box(FL_NO_BOX); + o->labeltype(FL_EMBOSSED_LABEL); + o->labelfont(1); + o->labelsize(22); + o->align(FL_ALIGN_RIGHT); + } // Fl_Text_Display* o + { eqp0 = new WidgetPDial(10, 35, 30, 30, "Gain"); + eqp0->box(FL_ROUND_UP_BOX); + eqp0->color(FL_BACKGROUND_COLOR); + eqp0->selection_color(FL_INACTIVE_COLOR); + eqp0->labeltype(FL_NORMAL_LABEL); + eqp0->labelfont(1); + eqp0->labelsize(11); + eqp0->labelcolor(FL_FOREGROUND_COLOR); + eqp0->maximum(127); + eqp0->callback((Fl_Callback*)cb_eqp0); + eqp0->align(FL_ALIGN_BOTTOM); + eqp0->when(FL_WHEN_CHANGED); + } // WidgetPDial* eqp0 + { Fl_Counter* o = bandcounter = new Fl_Counter(240, 20, 45, 15, "B."); + bandcounter->tooltip("Band no."); + bandcounter->type(1); + bandcounter->labelfont(1); + bandcounter->labelsize(11); + bandcounter->minimum(0); + bandcounter->maximum(1); + bandcounter->step(1); + bandcounter->textfont(1); + bandcounter->textsize(11); + bandcounter->callback((Fl_Callback*)cb_bandcounter); + bandcounter->align(FL_ALIGN_TOP); + o->bounds(0,MAX_EQ_BANDS-1); + } // Fl_Counter* bandcounter + { Fl_Group* o = bandgroup = new Fl_Group(245, 40, 130, 50); + bandgroup->box(FL_ENGRAVED_FRAME); + { freqdial = new WidgetPDial(250, 50, 25, 25, "Freq"); + freqdial->box(FL_ROUND_UP_BOX); + freqdial->color(FL_BACKGROUND_COLOR); + freqdial->selection_color(FL_INACTIVE_COLOR); + freqdial->labeltype(FL_NORMAL_LABEL); + freqdial->labelfont(1); + freqdial->labelsize(10); + freqdial->labelcolor(FL_FOREGROUND_COLOR); + freqdial->maximum(127); + freqdial->callback((Fl_Callback*)cb_freqdial); + freqdial->align(FL_ALIGN_BOTTOM); + freqdial->when(3); + } // WidgetPDial* freqdial + { gaindial = new WidgetPDial(280, 50, 25, 25, "Gain"); + gaindial->box(FL_ROUND_UP_BOX); + gaindial->color(FL_BACKGROUND_COLOR); + gaindial->selection_color(FL_INACTIVE_COLOR); + gaindial->labeltype(FL_NORMAL_LABEL); + gaindial->labelfont(1); + gaindial->labelsize(10); + gaindial->labelcolor(FL_FOREGROUND_COLOR); + gaindial->maximum(127); + gaindial->step(1); + gaindial->callback((Fl_Callback*)cb_gaindial); + gaindial->align(FL_ALIGN_BOTTOM); + gaindial->when(3); + } // WidgetPDial* gaindial + { qdial = new WidgetPDial(310, 50, 25, 25, "Q"); + qdial->tooltip("Resonance/Bandwidth"); + qdial->box(FL_ROUND_UP_BOX); + qdial->color(FL_BACKGROUND_COLOR); + qdial->selection_color(FL_INACTIVE_COLOR); + qdial->labeltype(FL_NORMAL_LABEL); + qdial->labelfont(1); + qdial->labelsize(10); + qdial->labelcolor(FL_FOREGROUND_COLOR); + qdial->maximum(127); + qdial->callback((Fl_Callback*)cb_qdial); + qdial->align(FL_ALIGN_BOTTOM); + qdial->when(3); + } // WidgetPDial* qdial + { Fl_Counter* o = stagescounter = new Fl_Counter(340, 60, 30, 15, "St."); + stagescounter->tooltip("Additional filter stages"); + stagescounter->type(1); + stagescounter->labelfont(1); + stagescounter->labelsize(10); + stagescounter->minimum(1); + stagescounter->maximum(127); + stagescounter->step(1); + stagescounter->textfont(1); + stagescounter->textsize(11); + stagescounter->callback((Fl_Callback*)cb_stagescounter); + o->bounds(0,MAX_FILTER_STAGES-1); + } // Fl_Counter* stagescounter + if (eff->geteffectpar(10)==0) o->deactivate(); + bandgroup->end(); + } // Fl_Group* bandgroup + { typechoice = new Fl_Choice(290, 20, 40, 15, "T."); + typechoice->tooltip("Type"); + typechoice->down_box(FL_BORDER_BOX); + typechoice->labelfont(1); + typechoice->labelsize(10); + typechoice->textsize(10); + typechoice->callback((Fl_Callback*)cb_typechoice); + typechoice->align(FL_ALIGN_TOP); + typechoice->when(FL_WHEN_RELEASE_ALWAYS); + typechoice->menu(menu_typechoice); + } // Fl_Choice* typechoice + { EQGraph* o = eqgraph = new EQGraph(45, 10, 190, 75); + eqgraph->box(FL_BORDER_BOX); + eqgraph->color((Fl_Color)178); + eqgraph->selection_color(FL_BACKGROUND_COLOR); + eqgraph->labeltype(FL_NORMAL_LABEL); + eqgraph->labelfont(0); + eqgraph->labelsize(14); + eqgraph->labelcolor(FL_FOREGROUND_COLOR); + eqgraph->align(FL_ALIGN_CENTER); + eqgraph->when(FL_WHEN_RELEASE); + o->init(eff); + } // EQGraph* eqgraph + effeqwindow->end(); + } // Fl_Group* effeqwindow + return effeqwindow; +} + +Fl_Group* EffUI::make_dynamicfilter_window() { + { effdynamicfilterwindow = new Fl_Group(0, 0, 380, 95); + effdynamicfilterwindow->box(FL_PLASTIC_UP_BOX); + effdynamicfilterwindow->color((Fl_Color)221); + effdynamicfilterwindow->selection_color(FL_BACKGROUND_COLOR); + effdynamicfilterwindow->labeltype(FL_NO_LABEL); + effdynamicfilterwindow->labelfont(1); + effdynamicfilterwindow->labelsize(14); + effdynamicfilterwindow->labelcolor(FL_FOREGROUND_COLOR); + effdynamicfilterwindow->user_data((void*)(this)); + effdynamicfilterwindow->align(FL_ALIGN_TOP); + effdynamicfilterwindow->when(FL_WHEN_RELEASE); + { dfp = new Fl_Choice(10, 15, 90, 15, "Preset"); + dfp->down_box(FL_BORDER_BOX); + dfp->color((Fl_Color)14); + dfp->selection_color(FL_FOREGROUND_COLOR); + dfp->labelfont(1); + dfp->labelsize(10); + dfp->textfont(1); + dfp->textsize(10); + dfp->textcolor(7); + dfp->callback((Fl_Callback*)cb_dfp); + dfp->align(FL_ALIGN_TOP_LEFT); + dfp->menu(menu_dfp); + } // Fl_Choice* dfp + { Fl_Text_Display* o = new Fl_Text_Display(245, 10, 10, 20, "DynFilter"); + o->box(FL_NO_BOX); + o->labeltype(FL_EMBOSSED_LABEL); + o->labelfont(1); + o->labelsize(22); + o->align(FL_ALIGN_RIGHT); + } // Fl_Text_Display* o + { dfp0 = new WidgetPDial(10, 40, 30, 30, "Vol"); + dfp0->tooltip("Effect Volume"); + dfp0->box(FL_ROUND_UP_BOX); + dfp0->color(FL_BACKGROUND_COLOR); + dfp0->selection_color(FL_INACTIVE_COLOR); + dfp0->labeltype(FL_NORMAL_LABEL); + dfp0->labelfont(1); + dfp0->labelsize(11); + dfp0->labelcolor(FL_FOREGROUND_COLOR); + dfp0->maximum(127); + dfp0->callback((Fl_Callback*)cb_dfp0); + dfp0->align(FL_ALIGN_BOTTOM); + dfp0->when(FL_WHEN_CHANGED); + } // WidgetPDial* dfp0 + { dfp1 = new WidgetPDial(45, 40, 30, 30, "Pan"); + dfp1->box(FL_ROUND_UP_BOX); + dfp1->color(FL_BACKGROUND_COLOR); + dfp1->selection_color(FL_INACTIVE_COLOR); + dfp1->labeltype(FL_NORMAL_LABEL); + dfp1->labelfont(1); + dfp1->labelsize(11); + dfp1->labelcolor(FL_FOREGROUND_COLOR); + dfp1->maximum(127); + dfp1->callback((Fl_Callback*)cb_dfp1); + dfp1->align(FL_ALIGN_BOTTOM); + dfp1->when(FL_WHEN_CHANGED); + } // WidgetPDial* dfp1 + { dfp2 = new WidgetPDial(85, 40, 30, 30, "Freq"); + dfp2->tooltip("LFO Frequency"); + dfp2->box(FL_ROUND_UP_BOX); + dfp2->color(FL_BACKGROUND_COLOR); + dfp2->selection_color(FL_INACTIVE_COLOR); + dfp2->labeltype(FL_NORMAL_LABEL); + dfp2->labelfont(1); + dfp2->labelsize(11); + dfp2->labelcolor(FL_FOREGROUND_COLOR); + dfp2->maximum(127); + dfp2->callback((Fl_Callback*)cb_dfp2); + dfp2->align(FL_ALIGN_BOTTOM); + dfp2->when(FL_WHEN_CHANGED); + } // WidgetPDial* dfp2 + { dfp3 = new WidgetPDial(120, 40, 30, 30, "Rnd"); + dfp3->tooltip("LFO Randomness"); + dfp3->box(FL_ROUND_UP_BOX); + dfp3->color(FL_BACKGROUND_COLOR); + dfp3->selection_color(FL_INACTIVE_COLOR); + dfp3->labeltype(FL_NORMAL_LABEL); + dfp3->labelfont(1); + dfp3->labelsize(11); + dfp3->labelcolor(FL_FOREGROUND_COLOR); + dfp3->maximum(127); + dfp3->callback((Fl_Callback*)cb_dfp3); + dfp3->align(FL_ALIGN_BOTTOM); + dfp3->when(FL_WHEN_RELEASE); + } // WidgetPDial* dfp3 + { dfp5 = new WidgetPDial(200, 40, 30, 30, "St.df"); + dfp5->tooltip("Left/Right Channel Phase Shift"); + dfp5->box(FL_ROUND_UP_BOX); + dfp5->color(FL_BACKGROUND_COLOR); + dfp5->selection_color(FL_INACTIVE_COLOR); + dfp5->labeltype(FL_NORMAL_LABEL); + dfp5->labelfont(1); + dfp5->labelsize(11); + dfp5->labelcolor(FL_FOREGROUND_COLOR); + dfp5->maximum(127); + dfp5->callback((Fl_Callback*)cb_dfp5); + dfp5->align(FL_ALIGN_BOTTOM); + dfp5->when(FL_WHEN_CHANGED); + } // WidgetPDial* dfp5 + { dfp6 = new WidgetPDial(235, 40, 30, 30, "LfoD"); + dfp6->tooltip("LFO Depth"); + dfp6->box(FL_ROUND_UP_BOX); + dfp6->color(FL_BACKGROUND_COLOR); + dfp6->selection_color(FL_INACTIVE_COLOR); + dfp6->labeltype(FL_NORMAL_LABEL); + dfp6->labelfont(1); + dfp6->labelsize(11); + dfp6->labelcolor(FL_FOREGROUND_COLOR); + dfp6->maximum(127); + dfp6->callback((Fl_Callback*)cb_dfp6); + dfp6->align(FL_ALIGN_BOTTOM); + dfp6->when(FL_WHEN_CHANGED); + } // WidgetPDial* dfp6 + { dfp4 = new Fl_Choice(155, 50, 40, 15, "LFO type"); + dfp4->tooltip("LFO function"); + dfp4->down_box(FL_BORDER_BOX); + dfp4->labelfont(1); + dfp4->labelsize(10); + dfp4->textsize(8); + dfp4->callback((Fl_Callback*)cb_dfp4); + dfp4->align(130); + dfp4->menu(menu_dfp4); + } // Fl_Choice* dfp4 + { Fl_Button* o = new Fl_Button(115, 10, 55, 25, "Filter"); + o->box(FL_PLASTIC_THIN_UP_BOX); + o->callback((Fl_Callback*)cb_Filter); + } // Fl_Button* o + { Fl_Group* o = new Fl_Group(270, 40, 105, 45); + o->box(FL_BORDER_BOX); + o->color((Fl_Color)181); + { dfp7 = new WidgetPDial(275, 45, 25, 25, "A.S."); + dfp7->tooltip("Filter vs Amplitude"); + dfp7->box(FL_ROUND_UP_BOX); + dfp7->color(FL_BACKGROUND_COLOR); + dfp7->selection_color(FL_INACTIVE_COLOR); + dfp7->labeltype(FL_NORMAL_LABEL); + dfp7->labelfont(1); + dfp7->labelsize(11); + dfp7->labelcolor(FL_FOREGROUND_COLOR); + dfp7->maximum(127); + dfp7->callback((Fl_Callback*)cb_dfp7); + dfp7->align(FL_ALIGN_BOTTOM); + dfp7->when(FL_WHEN_CHANGED); + } // WidgetPDial* dfp7 + { dfp9 = new WidgetPDial(305, 45, 25, 25, "A.M"); + dfp9->tooltip("rate that amplitude changes the filter"); + dfp9->box(FL_ROUND_UP_BOX); + dfp9->color(FL_BACKGROUND_COLOR); + dfp9->selection_color(FL_INACTIVE_COLOR); + dfp9->labeltype(FL_NORMAL_LABEL); + dfp9->labelfont(1); + dfp9->labelsize(11); + dfp9->labelcolor(FL_FOREGROUND_COLOR); + dfp9->maximum(127); + dfp9->callback((Fl_Callback*)cb_dfp9); + dfp9->align(FL_ALIGN_BOTTOM); + dfp9->when(FL_WHEN_CHANGED); + } // WidgetPDial* dfp9 + { dfp8 = new Fl_Check_Button(345, 55, 15, 15, "A.Inv."); + dfp8->tooltip("enable for filter frequency to lower with higher input amplitude"); + dfp8->down_box(FL_DOWN_BOX); + dfp8->labelfont(1); + dfp8->labelsize(11); + dfp8->callback((Fl_Callback*)cb_dfp8); + dfp8->align(FL_ALIGN_BOTTOM); + } // Fl_Check_Button* dfp8 + o->end(); + } // Fl_Group* o + effdynamicfilterwindow->end(); + } // Fl_Group* effdynamicfilterwindow + return effdynamicfilterwindow; +} + +Fl_Double_Window* EffUI::make_filter_window() { + { filterwindow = new Fl_Double_Window(290, 110, "Filter Parameters for DynFilter Eff."); + filterwindow->user_data((void*)(this)); + { FilterUI* o = new FilterUI(5, 5, 275, 75, "DynFilter effect - Filter"); + o->box(FL_FLAT_BOX); + o->color(FL_LIGHT1); + o->selection_color(FL_BACKGROUND_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); + o->align(FL_ALIGN_WRAP|FL_ALIGN_INSIDE); + o->when(FL_WHEN_RELEASE); + o->init(eff->filterpars,NULL,NULL); + o->use_for_dynamic_filter(); + o->end(); + } // FilterUI* o + { Fl_Button* o = new Fl_Button(105, 85, 70, 20, "Close"); + o->box(FL_THIN_UP_BOX); + o->callback((Fl_Callback*)cb_Close); + } // Fl_Button* o + filterwindow->end(); + } // Fl_Double_Window* filterwindow + return filterwindow; +} + +void EffUI::init(EffectMgr *eff_) { + eff=eff_; + +make_null_window(); +make_reverb_window(); +make_echo_window(); +make_chorus_window(); +make_phaser_window(); +make_alienwah_window(); +make_distorsion_window(); +make_eq_window(); +make_dynamicfilter_window(); + +int px=this->parent()->x(); +int py=this->parent()->y(); + +effnullwindow->position(px,py); +effreverbwindow->position(px,py); +effechowindow->position(px,py); +effchoruswindow->position(px,py); +effphaserwindow->position(px,py); +effalienwahwindow->position(px,py); +effdistorsionwindow->position(px,py); +effeqwindow->position(px,py); +effdynamicfilterwindow->position(px,py); + +refresh(eff); +} + +void EffUI::refresh(EffectMgr *eff_) { + eff=eff_; +this->hide(); + +effnullwindow->hide(); +effreverbwindow->hide(); +effechowindow->hide(); +effchoruswindow->hide(); +effphaserwindow->hide(); +effalienwahwindow->hide(); +effdistorsionwindow->hide(); +effeqwindow->hide(); +effdynamicfilterwindow->hide(); + +eqband=0; + +if (filterwindow!=NULL){ + filterwindow->hide(); + delete(filterwindow); + filterwindow=NULL; +}; + +switch(eff->geteffect()){ + case 1: + revp->value(eff->getpreset()); + revp0->value(eff->geteffectpar(0));if (eff->insertion!=0) revp0->label("D/W"); + revp1->value(eff->geteffectpar(1)); + revp2->value(eff->geteffectpar(2)); + revp3->value(eff->geteffectpar(3)); + revp4->value(eff->geteffectpar(4)); + revp5->value(eff->geteffectpar(5)); + revp6->value(eff->geteffectpar(6)); + revp7->value(eff->geteffectpar(7)); + revp8->value(eff->geteffectpar(8)); + revp9->value(eff->geteffectpar(9)); + revp10->value(eff->geteffectpar(10)); + revp11->value(eff->geteffectpar(11)); + + effreverbwindow->show(); + break; + case 2: + echop->value(eff->getpreset()); + echop0->value(eff->geteffectpar(0));if (eff->insertion!=0) echop0->label("D/W"); + echop1->value(eff->geteffectpar(1)); + echop2->value(eff->geteffectpar(2)); + echop3->value(eff->geteffectpar(3)); + echop4->value(eff->geteffectpar(4)); + echop5->value(eff->geteffectpar(5)); + echop6->value(eff->geteffectpar(6)); + effechowindow->show(); + break; + case 3: + chorusp->value(eff->getpreset()); + chorusp0->value(eff->geteffectpar(0));if (eff->insertion!=0) chorusp0->label("D/W"); + chorusp1->value(eff->geteffectpar(1)); + chorusp2->value(eff->geteffectpar(2)); + chorusp3->value(eff->geteffectpar(3)); + chorusp4->value(eff->geteffectpar(4)); + chorusp5->value(eff->geteffectpar(5)); + chorusp6->value(eff->geteffectpar(6)); + chorusp7->value(eff->geteffectpar(7)); + chorusp8->value(eff->geteffectpar(8)); + chorusp9->value(eff->geteffectpar(9)); + chorusp11->value(eff->geteffectpar(11)); + effchoruswindow->show(); + break; + case 4: + phaserp->value(eff->getpreset()); + phaserp0->value(eff->geteffectpar(0));if (eff->insertion!=0) phaserp0->label("D/W"); + phaserp1->value(eff->geteffectpar(1)); + phaserp2->value(eff->geteffectpar(2)); + phaserp3->value(eff->geteffectpar(3)); + phaserp4->value(eff->geteffectpar(4)); + phaserp5->value(eff->geteffectpar(5)); + phaserp6->value(eff->geteffectpar(6)); + phaserp7->value(eff->geteffectpar(7)); + phaserp8->value(eff->geteffectpar(8)); + phaserp9->value(eff->geteffectpar(9)); + phaserp10->value(eff->geteffectpar(10)); + phaserp11->value(eff->geteffectpar(11)); + effphaserwindow->show(); + break; + case 5: + awp->value(eff->getpreset()); + awp0->value(eff->geteffectpar(0));if (eff->insertion!=0) awp0->label("D/W"); + awp1->value(eff->geteffectpar(1)); + awp2->value(eff->geteffectpar(2)); + awp3->value(eff->geteffectpar(3)); + awp4->value(eff->geteffectpar(4)); + awp5->value(eff->geteffectpar(5)); + awp6->value(eff->geteffectpar(6)); + awp7->value(eff->geteffectpar(7)); + awp8->value(eff->geteffectpar(8)); + awp9->value(eff->geteffectpar(9)); + awp10->value(eff->geteffectpar(10)); + + effalienwahwindow->show(); + break; + case 6: + distp->value(eff->getpreset()); + distp0->value(eff->geteffectpar(0));if (eff->insertion!=0) distp0->label("D/W"); + distp1->value(eff->geteffectpar(1)); + distp2->value(eff->geteffectpar(2)); + distp3->value(eff->geteffectpar(3)); + distp4->value(eff->geteffectpar(4)); + distp5->value(eff->geteffectpar(5)); + distp6->value(eff->geteffectpar(6)); + distp7->value(eff->geteffectpar(7)); + distp8->value(eff->geteffectpar(8)); + distp9->value(eff->geteffectpar(9)); + distp10->value(eff->geteffectpar(10)); + effdistorsionwindow->show(); + break; + case 7:eqband=0; + eqp0->value(eff->geteffectpar(0)); + bandcounter->value(eqband); + bandcounter->do_callback(); + typechoice->value(eff->geteffectpar(10)); + eqgraph->redraw(); + freqdial->value(eff->geteffectpar(11)); + gaindial->value(eff->geteffectpar(12)); + if (eff->geteffectpar(10)<6) gaindial->deactivate(); + qdial->value(eff->geteffectpar(13)); + stagescounter->value(eff->geteffectpar(14)); + eqgraph->init(eff); + effeqwindow->show(); + break; + case 8:make_filter_window(); + dfp->value(eff->getpreset()); + dfp0->value(eff->geteffectpar(0));if (eff->insertion!=0) dfp0->label("D/W"); + dfp1->value(eff->geteffectpar(1)); + dfp2->value(eff->geteffectpar(2)); + dfp3->value(eff->geteffectpar(3)); + dfp4->value(eff->geteffectpar(4)); + dfp5->value(eff->geteffectpar(5)); + dfp6->value(eff->geteffectpar(6)); + dfp7->value(eff->geteffectpar(7)); + dfp8->value(eff->geteffectpar(8)); + dfp9->value(eff->geteffectpar(9)); + + + effdynamicfilterwindow->show(); + break; + default:effnullwindow->show(); + break; +}; + +this->show(); +} + +void EffUI::refresh() { + refresh(eff); +} + +void SimpleEffUI::cb_revpa_i(Fl_Choice* o, void*) { + eff->changepreset((int)o->value()); + +refresh(eff); +} +void SimpleEffUI::cb_revpa(Fl_Choice* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_revpa_i(o,v); +} + +Fl_Menu_Item SimpleEffUI::menu_revp1[] = { + {"Cathedral 1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Cathedral 2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Cathedral 3", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Hall 1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Hall 2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Room 1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Room 2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Basement", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Tunnel", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Echoed 1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Echoed 2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Very Long 1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Very Long 2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {0,0,0,0,0,0,0,0,0} +}; + +void SimpleEffUI::cb_revp01_i(WidgetPDial* o, void*) { + eff->seteffectpar(0,(int) o->value()); +} +void SimpleEffUI::cb_revp01(WidgetPDial* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_revp01_i(o,v); +} + +void SimpleEffUI::cb_revp21_i(WidgetPDial* o, void*) { + eff->seteffectpar(2,(int) o->value()); +} +void SimpleEffUI::cb_revp21(WidgetPDial* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_revp21_i(o,v); +} + +void SimpleEffUI::cb_revp31_i(WidgetPDial* o, void*) { + eff->seteffectpar(3,(int) o->value()); +} +void SimpleEffUI::cb_revp31(WidgetPDial* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_revp31_i(o,v); +} + +void SimpleEffUI::cb_revp91_i(WidgetPDial* o, void*) { + eff->seteffectpar(9,(int) o->value()); +} +void SimpleEffUI::cb_revp91(WidgetPDial* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_revp91_i(o,v); +} + +void SimpleEffUI::cb_echop7_i(Fl_Choice* o, void*) { + eff->changepreset((int)o->value()); +refresh(eff); +} +void SimpleEffUI::cb_echop7(Fl_Choice* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_echop7_i(o,v); +} + +Fl_Menu_Item SimpleEffUI::menu_echop1[] = { + {"Echo 1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Echo 2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Echo 3", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Simple Echo", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Canyon", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Panning Echo 1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Panning Echo 2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Panning Echo 3", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Feedback Echo", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {0,0,0,0,0,0,0,0,0} +}; + +void SimpleEffUI::cb_echop01_i(WidgetPDial* o, void*) { + eff->seteffectpar(0,(int) o->value()); +} +void SimpleEffUI::cb_echop01(WidgetPDial* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_echop01_i(o,v); +} + +void SimpleEffUI::cb_echop21_i(WidgetPDial* o, void*) { + eff->seteffectpar(2,(int) o->value()); +} +void SimpleEffUI::cb_echop21(WidgetPDial* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_echop21_i(o,v); +} + +void SimpleEffUI::cb_echop51_i(WidgetPDial* o, void*) { + eff->seteffectpar(5,(int) o->value()); +} +void SimpleEffUI::cb_echop51(WidgetPDial* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_echop51_i(o,v); +} + +void SimpleEffUI::cb_choruspa_i(Fl_Choice* o, void*) { + eff->changepreset((int)o->value()); +refresh(eff); +} +void SimpleEffUI::cb_choruspa(Fl_Choice* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_choruspa_i(o,v); +} + +Fl_Menu_Item SimpleEffUI::menu_chorusp1[] = { + {"Chorus 1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Chorus 2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Chorus 3", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Celeste 1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Celeste 2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Flange 1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Flange 2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Flange 3", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Flange 4", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Flange 5", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {0,0,0,0,0,0,0,0,0} +}; + +void SimpleEffUI::cb_chorusp01_i(WidgetPDial* o, void*) { + eff->seteffectpar(0,(int) o->value()); +} +void SimpleEffUI::cb_chorusp01(WidgetPDial* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_chorusp01_i(o,v); +} + +void SimpleEffUI::cb_chorusp21_i(WidgetPDial* o, void*) { + eff->seteffectpar(2,(int) o->value()); +} +void SimpleEffUI::cb_chorusp21(WidgetPDial* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_chorusp21_i(o,v); +} + +void SimpleEffUI::cb_chorusp61_i(WidgetPDial* o, void*) { + eff->seteffectpar(6,(int) o->value()); +} +void SimpleEffUI::cb_chorusp61(WidgetPDial* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_chorusp61_i(o,v); +} + +void SimpleEffUI::cb_chorusp71_i(WidgetPDial* o, void*) { + eff->seteffectpar(7,(int) o->value()); +} +void SimpleEffUI::cb_chorusp71(WidgetPDial* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_chorusp71_i(o,v); +} + +void SimpleEffUI::cb_chorusp81_i(WidgetPDial* o, void*) { + eff->seteffectpar(8,(int) o->value()); +} +void SimpleEffUI::cb_chorusp81(WidgetPDial* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_chorusp81_i(o,v); +} + +void SimpleEffUI::cb_Flange1_i(Fl_Check_Button* o, void*) { + eff->seteffectpar(10,(int) o->value()); +} +void SimpleEffUI::cb_Flange1(Fl_Check_Button* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_Flange1_i(o,v); +} + +void SimpleEffUI::cb_phaserpa_i(Fl_Choice* o, void*) { + eff->changepreset((int)o->value()); +refresh(eff); +} +void SimpleEffUI::cb_phaserpa(Fl_Choice* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_phaserpa_i(o,v); +} + +Fl_Menu_Item SimpleEffUI::menu_phaserp1[] = { + {"Phaser 1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Phaser 2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Phaser 3", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Phaser 4", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Phaser 5", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Phaser 6", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {0,0,0,0,0,0,0,0,0} +}; + +void SimpleEffUI::cb_phaserp01_i(WidgetPDial* o, void*) { + eff->seteffectpar(0,(int) o->value()); +} +void SimpleEffUI::cb_phaserp01(WidgetPDial* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_phaserp01_i(o,v); +} + +void SimpleEffUI::cb_phaserp21_i(WidgetPDial* o, void*) { + eff->seteffectpar(2,(int) o->value()); +} +void SimpleEffUI::cb_phaserp21(WidgetPDial* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_phaserp21_i(o,v); +} + +void SimpleEffUI::cb_phaserp51_i(WidgetPDial* o, void*) { + eff->seteffectpar(5,(int) o->value()); +} +void SimpleEffUI::cb_phaserp51(WidgetPDial* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_phaserp51_i(o,v); +} + +void SimpleEffUI::cb_phaserp61_i(WidgetPDial* o, void*) { + eff->seteffectpar(6,(int) o->value()); +} +void SimpleEffUI::cb_phaserp61(WidgetPDial* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_phaserp61_i(o,v); +} + +void SimpleEffUI::cb_phaserp71_i(WidgetPDial* o, void*) { + eff->seteffectpar(7,(int) o->value()); +} +void SimpleEffUI::cb_phaserp71(WidgetPDial* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_phaserp71_i(o,v); +} + +void SimpleEffUI::cb_phaserp81_i(Fl_Counter* o, void*) { + eff->seteffectpar(8,(int) o->value()); +} +void SimpleEffUI::cb_phaserp81(Fl_Counter* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_phaserp81_i(o,v); +} + +void SimpleEffUI::cb_awpa_i(Fl_Choice* o, void*) { + eff->changepreset((int)o->value()); +refresh(eff); +} +void SimpleEffUI::cb_awpa(Fl_Choice* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_awpa_i(o,v); +} + +Fl_Menu_Item SimpleEffUI::menu_awp1[] = { + {"Alienwah 1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Alienwah 2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Alienwah 3", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Alienwah 4", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {0,0,0,0,0,0,0,0,0} +}; + +void SimpleEffUI::cb_awp01_i(WidgetPDial* o, void*) { + eff->seteffectpar(0,(int) o->value()); +} +void SimpleEffUI::cb_awp01(WidgetPDial* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_awp01_i(o,v); +} + +void SimpleEffUI::cb_awp21_i(WidgetPDial* o, void*) { + eff->seteffectpar(2,(int) o->value()); +} +void SimpleEffUI::cb_awp21(WidgetPDial* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_awp21_i(o,v); +} + +void SimpleEffUI::cb_awp61_i(WidgetPDial* o, void*) { + eff->seteffectpar(6,(int) o->value()); +} +void SimpleEffUI::cb_awp61(WidgetPDial* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_awp61_i(o,v); +} + +void SimpleEffUI::cb_awp81_i(Fl_Counter* o, void*) { + eff->seteffectpar(8,(int) o->value()); +} +void SimpleEffUI::cb_awp81(Fl_Counter* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_awp81_i(o,v); +} + +void SimpleEffUI::cb_distpa_i(Fl_Choice* o, void*) { + eff->changepreset((int)o->value()); +refresh(eff); +} +void SimpleEffUI::cb_distpa(Fl_Choice* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_distpa_i(o,v); +} + +Fl_Menu_Item SimpleEffUI::menu_distp1[] = { + {"Overdrive 1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Overdrive 2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"A. Exciter 1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"A. Exciter 2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Guitar Amp", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Quantisize", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {0,0,0,0,0,0,0,0,0} +}; + +void SimpleEffUI::cb_distp01_i(WidgetPDial* o, void*) { + eff->seteffectpar(0,(int) o->value()); +} +void SimpleEffUI::cb_distp01(WidgetPDial* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_distp01_i(o,v); +} + +void SimpleEffUI::cb_distp31_i(WidgetPDial* o, void*) { + eff->seteffectpar(3,(int) o->value()); +} +void SimpleEffUI::cb_distp31(WidgetPDial* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_distp31_i(o,v); +} + +void SimpleEffUI::cb_distp41_i(WidgetPDial* o, void*) { + eff->seteffectpar(4,(int) o->value()); +} +void SimpleEffUI::cb_distp41(WidgetPDial* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_distp41_i(o,v); +} + +void SimpleEffUI::cb_distp71_i(WidgetPDial* o, void*) { + eff->seteffectpar(7,(int) o->value()); +} +void SimpleEffUI::cb_distp71(WidgetPDial* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_distp71_i(o,v); +} + +void SimpleEffUI::cb_distp51_i(Fl_Choice* o, void*) { + eff->seteffectpar(5,(int) o->value()); +} +void SimpleEffUI::cb_distp51(Fl_Choice* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_distp51_i(o,v); +} + +Fl_Menu_Item SimpleEffUI::menu_distp51[] = { + {"Atan", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Asym1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Pow", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Sine", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Qnts", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Zigzg", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Lmt", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"LmtU", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"LmtL", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"ILmt", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Clip", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Asym2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Pow2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Sgm", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void SimpleEffUI::cb_bandcounter1_i(Fl_Counter* o, void*) { + eqband=(int) o->value(); +int npb=eqband*5+10; + +int type=eff->geteffectpar(npb); +typechoice->value(type); + +if (type>6) gaindial->activate(); + else gaindial->deactivate(); + +if (type==0) bandgroup->deactivate(); +else bandgroup->activate(); + +int freq=eff->geteffectpar(npb+1); +freqdial->value(freq); + +int gain=eff->geteffectpar(npb+2); +gaindial->value(gain); + +int q=eff->geteffectpar(npb+3); +qdial->value(q); + +int dbl=eff->geteffectpar(npb+4); +stagescounter->value(dbl); +} +void SimpleEffUI::cb_bandcounter1(Fl_Counter* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_bandcounter1_i(o,v); +} + +void SimpleEffUI::cb_freqdial1_i(WidgetPDial* o, void*) { + int np=eqband*5+11; +eff->seteffectpar(np,(int) o->value()); +eqgraph->redraw(); +} +void SimpleEffUI::cb_freqdial1(WidgetPDial* o, void* v) { + ((SimpleEffUI*)(o->parent()->parent()->user_data()))->cb_freqdial1_i(o,v); +} + +void SimpleEffUI::cb_gaindial1_i(WidgetPDial* o, void*) { + int np=eqband*5+12; +eff->seteffectpar(np,(int) o->value()); +eqgraph->redraw(); +} +void SimpleEffUI::cb_gaindial1(WidgetPDial* o, void* v) { + ((SimpleEffUI*)(o->parent()->parent()->user_data()))->cb_gaindial1_i(o,v); +} + +void SimpleEffUI::cb_qdial1_i(WidgetPDial* o, void*) { + int np=eqband*5+13; +eff->seteffectpar(np,(int) o->value()); +eqgraph->redraw(); +} +void SimpleEffUI::cb_qdial1(WidgetPDial* o, void* v) { + ((SimpleEffUI*)(o->parent()->parent()->user_data()))->cb_qdial1_i(o,v); +} + +void SimpleEffUI::cb_stagescounter1_i(Fl_Counter* o, void*) { + int np=eqband*5+14; +eff->seteffectpar(np,(int) o->value()); +eqgraph->redraw(); +} +void SimpleEffUI::cb_stagescounter1(Fl_Counter* o, void* v) { + ((SimpleEffUI*)(o->parent()->parent()->user_data()))->cb_stagescounter1_i(o,v); +} + +void SimpleEffUI::cb_typechoice1_i(Fl_Choice* o, void*) { + int np=eqband*5+10; +eff->seteffectpar(np,(int) o->value()); +bandcounter->do_callback(); +eqgraph->redraw(); +} +void SimpleEffUI::cb_typechoice1(Fl_Choice* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_typechoice1_i(o,v); +} + +Fl_Menu_Item SimpleEffUI::menu_typechoice1[] = { + {"OFF", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Lp1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Hp1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Lp2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Hp2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Bp2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"N2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Pk", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"LSh", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"HSh", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void SimpleEffUI::cb_dfpa_i(Fl_Choice* o, void*) { + eff->changepreset((int)o->value()); +refresh(eff); +} +void SimpleEffUI::cb_dfpa(Fl_Choice* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_dfpa_i(o,v); +} + +Fl_Menu_Item SimpleEffUI::menu_dfp1[] = { + {"WahWah", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"AutoWah", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"Sweep", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"VocalMorph1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {"VocalMorph2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 7}, + {0,0,0,0,0,0,0,0,0} +}; + +void SimpleEffUI::cb_dfp01_i(WidgetPDial* o, void*) { + eff->seteffectpar(0,(int) o->value()); +} +void SimpleEffUI::cb_dfp01(WidgetPDial* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_dfp01_i(o,v); +} + +void SimpleEffUI::cb_dfp21_i(WidgetPDial* o, void*) { + eff->seteffectpar(2,(int) o->value()); +} +void SimpleEffUI::cb_dfp21(WidgetPDial* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_dfp21_i(o,v); +} + +void SimpleEffUI::cb_dfp61_i(WidgetPDial* o, void*) { + eff->seteffectpar(6,(int) o->value()); +} +void SimpleEffUI::cb_dfp61(WidgetPDial* o, void* v) { + ((SimpleEffUI*)(o->parent()->user_data()))->cb_dfp61_i(o,v); +} + +void SimpleEffUI::cb_dfp71_i(WidgetPDial* o, void*) { + eff->seteffectpar(7,(int) o->value()); +} +void SimpleEffUI::cb_dfp71(WidgetPDial* o, void* v) { + ((SimpleEffUI*)(o->parent()->parent()->user_data()))->cb_dfp71_i(o,v); +} + +void SimpleEffUI::cb_dfp91_i(WidgetPDial* o, void*) { + eff->seteffectpar(9,(int) o->value()); +} +void SimpleEffUI::cb_dfp91(WidgetPDial* o, void* v) { + ((SimpleEffUI*)(o->parent()->parent()->user_data()))->cb_dfp91_i(o,v); +} + +SimpleEffUI::SimpleEffUI(int x,int y, int w, int h, const char *label):Fl_Group(x,y,w,h,label) { + eff=NULL; +} + +SimpleEffUI::~SimpleEffUI() { + effnullwindow->hide();//delete (effnullwindow); +effreverbwindow->hide();//delete (effreverbwindow); +effechowindow->hide();//delete (effechowindow); +effchoruswindow->hide();//delete (effchoruswindow); +effphaserwindow->hide();//delete (effphaserwindow); +effalienwahwindow->hide();//delete (effalienwahwindow); +effdistorsionwindow->hide();//delete (effdistorsionwindow); +effeqwindow->hide();//delete (effeqwindow); +effdynamicfilterwindow->hide();//delete (effdynamicfilterwindow); +} + +Fl_Group* SimpleEffUI::make_null_window() { + { effnullwindow = new Fl_Group(0, 0, 230, 95); + effnullwindow->box(FL_PLASTIC_UP_BOX); + effnullwindow->color((Fl_Color)221); + effnullwindow->selection_color(FL_BACKGROUND_COLOR); + effnullwindow->labeltype(FL_NO_LABEL); + effnullwindow->labelfont(1); + effnullwindow->labelsize(14); + effnullwindow->labelcolor(FL_FOREGROUND_COLOR); + effnullwindow->user_data((void*)(this)); + effnullwindow->align(FL_ALIGN_TOP); + effnullwindow->when(FL_WHEN_RELEASE); + { Fl_Text_Display* o = new Fl_Text_Display(25, 35, 35, 20, "No Effect"); + o->box(FL_NO_BOX); + o->labeltype(FL_EMBOSSED_LABEL); + o->labelfont(1); + o->labelsize(22); + o->labelcolor((Fl_Color)43); + o->align(FL_ALIGN_RIGHT); + } // Fl_Text_Display* o + effnullwindow->end(); + } // Fl_Group* effnullwindow + return effnullwindow; +} + +Fl_Group* SimpleEffUI::make_reverb_window() { + { effreverbwindow = new Fl_Group(0, 0, 230, 95); + effreverbwindow->box(FL_PLASTIC_UP_BOX); + effreverbwindow->color((Fl_Color)221); + effreverbwindow->selection_color(FL_BACKGROUND_COLOR); + effreverbwindow->labeltype(FL_NO_LABEL); + effreverbwindow->labelfont(1); + effreverbwindow->labelsize(14); + effreverbwindow->labelcolor(FL_FOREGROUND_COLOR); + effreverbwindow->user_data((void*)(this)); + effreverbwindow->align(FL_ALIGN_TOP); + effreverbwindow->when(FL_WHEN_RELEASE); + { Fl_Text_Display* o = new Fl_Text_Display(115, 10, 20, 20, "Reverb "); + o->box(FL_NO_BOX); + o->labeltype(FL_EMBOSSED_LABEL); + o->labelfont(1); + o->labelsize(22); + o->align(FL_ALIGN_RIGHT); + } // Fl_Text_Display* o + { revp = new Fl_Choice(10, 15, 90, 15, "Preset"); + revp->down_box(FL_BORDER_BOX); + revp->color((Fl_Color)14); + revp->selection_color(FL_FOREGROUND_COLOR); + revp->labelfont(1); + revp->labelsize(10); + revp->textfont(1); + revp->textsize(10); + revp->textcolor(7); + revp->callback((Fl_Callback*)cb_revpa); + revp->align(FL_ALIGN_TOP_LEFT); + revp->menu(menu_revp1); + } // Fl_Choice* revp + { revp0 = new WidgetPDial(10, 40, 30, 30, "Vol"); + revp0->tooltip("Effect Volume"); + revp0->box(FL_ROUND_UP_BOX); + revp0->color(FL_BACKGROUND_COLOR); + revp0->selection_color(FL_INACTIVE_COLOR); + revp0->labeltype(FL_NORMAL_LABEL); + revp0->labelfont(1); + revp0->labelsize(11); + revp0->labelcolor(FL_FOREGROUND_COLOR); + revp0->maximum(127); + revp0->callback((Fl_Callback*)cb_revp01); + revp0->align(FL_ALIGN_BOTTOM); + revp0->when(FL_WHEN_CHANGED); + } // WidgetPDial* revp0 + { revp2 = new WidgetPDial(45, 40, 30, 30, "Time"); + revp2->tooltip("Duration of Reverb"); + revp2->box(FL_ROUND_UP_BOX); + revp2->color(FL_BACKGROUND_COLOR); + revp2->selection_color(FL_INACTIVE_COLOR); + revp2->labeltype(FL_NORMAL_LABEL); + revp2->labelfont(1); + revp2->labelsize(11); + revp2->labelcolor(FL_FOREGROUND_COLOR); + revp2->maximum(127); + revp2->callback((Fl_Callback*)cb_revp21); + revp2->align(FL_ALIGN_BOTTOM); + revp2->when(FL_WHEN_CHANGED); + } // WidgetPDial* revp2 + { revp3 = new WidgetPDial(85, 40, 30, 30, "I.del"); + revp3->tooltip("Initial Delay"); + revp3->box(FL_ROUND_UP_BOX); + revp3->color(FL_BACKGROUND_COLOR); + revp3->selection_color(FL_INACTIVE_COLOR); + revp3->labeltype(FL_NORMAL_LABEL); + revp3->labelfont(1); + revp3->labelsize(11); + revp3->labelcolor(FL_FOREGROUND_COLOR); + revp3->maximum(127); + revp3->callback((Fl_Callback*)cb_revp31); + revp3->align(FL_ALIGN_BOTTOM); + revp3->when(FL_WHEN_RELEASE); + } // WidgetPDial* revp3 + { revp9 = new WidgetPDial(120, 40, 30, 30, "Damp"); + revp9->tooltip("Dampening"); + revp9->box(FL_ROUND_UP_BOX); + revp9->color(FL_BACKGROUND_COLOR); + revp9->selection_color(FL_INACTIVE_COLOR); + revp9->labeltype(FL_NORMAL_LABEL); + revp9->labelfont(1); + revp9->labelsize(11); + revp9->labelcolor(FL_FOREGROUND_COLOR); + revp9->minimum(64); + revp9->maximum(127); + revp9->step(1); + revp9->callback((Fl_Callback*)cb_revp91); + revp9->align(FL_ALIGN_BOTTOM); + revp9->when(FL_WHEN_CHANGED); + } // WidgetPDial* revp9 + effreverbwindow->end(); + } // Fl_Group* effreverbwindow + return effreverbwindow; +} + +Fl_Group* SimpleEffUI::make_echo_window() { + { effechowindow = new Fl_Group(0, 0, 230, 95); + effechowindow->box(FL_PLASTIC_UP_BOX); + effechowindow->color((Fl_Color)221); + effechowindow->selection_color(FL_BACKGROUND_COLOR); + effechowindow->labeltype(FL_NO_LABEL); + effechowindow->labelfont(1); + effechowindow->labelsize(14); + effechowindow->labelcolor(FL_FOREGROUND_COLOR); + effechowindow->user_data((void*)(this)); + effechowindow->align(FL_ALIGN_TOP); + effechowindow->when(FL_WHEN_RELEASE); + { echop = new Fl_Choice(11, 15, 95, 15, "Preset"); + echop->down_box(FL_BORDER_BOX); + echop->color((Fl_Color)14); + echop->selection_color(FL_FOREGROUND_COLOR); + echop->labelfont(1); + echop->labelsize(10); + echop->textfont(1); + echop->textsize(10); + echop->textcolor(7); + echop->callback((Fl_Callback*)cb_echop7); + echop->align(FL_ALIGN_TOP_LEFT); + echop->menu(menu_echop1); + } // Fl_Choice* echop + { Fl_Text_Display* o = new Fl_Text_Display(145, 10, 10, 20, "Echo"); + o->box(FL_NO_BOX); + o->labeltype(FL_EMBOSSED_LABEL); + o->labelfont(1); + o->labelsize(22); + o->align(FL_ALIGN_RIGHT); + } // Fl_Text_Display* o + { echop0 = new WidgetPDial(10, 40, 30, 30, "Vol"); + echop0->tooltip("Effect Volume"); + echop0->box(FL_ROUND_UP_BOX); + echop0->color(FL_BACKGROUND_COLOR); + echop0->selection_color(FL_INACTIVE_COLOR); + echop0->labeltype(FL_NORMAL_LABEL); + echop0->labelfont(1); + echop0->labelsize(11); + echop0->labelcolor(FL_FOREGROUND_COLOR); + echop0->maximum(127); + echop0->callback((Fl_Callback*)cb_echop01); + echop0->align(FL_ALIGN_BOTTOM); + echop0->when(FL_WHEN_CHANGED); + } // WidgetPDial* echop0 + { echop2 = new WidgetPDial(45, 40, 30, 30, "Delay"); + echop2->box(FL_ROUND_UP_BOX); + echop2->color(FL_BACKGROUND_COLOR); + echop2->selection_color(FL_INACTIVE_COLOR); + echop2->labeltype(FL_NORMAL_LABEL); + echop2->labelfont(1); + echop2->labelsize(11); + echop2->labelcolor(FL_FOREGROUND_COLOR); + echop2->maximum(127); + echop2->callback((Fl_Callback*)cb_echop21); + echop2->align(FL_ALIGN_BOTTOM); + echop2->when(FL_WHEN_RELEASE); + } // WidgetPDial* echop2 + { echop5 = new WidgetPDial(80, 40, 30, 30, "Fb."); + echop5->tooltip("Feedback"); + echop5->box(FL_ROUND_UP_BOX); + echop5->color(FL_BACKGROUND_COLOR); + echop5->selection_color(FL_INACTIVE_COLOR); + echop5->labeltype(FL_NORMAL_LABEL); + echop5->labelfont(1); + echop5->labelsize(11); + echop5->labelcolor(FL_FOREGROUND_COLOR); + echop5->maximum(127); + echop5->callback((Fl_Callback*)cb_echop51); + echop5->align(FL_ALIGN_BOTTOM); + echop5->when(FL_WHEN_CHANGED); + } // WidgetPDial* echop5 + effechowindow->end(); + } // Fl_Group* effechowindow + return effechowindow; +} + +Fl_Group* SimpleEffUI::make_chorus_window() { + { effchoruswindow = new Fl_Group(0, 0, 230, 95); + effchoruswindow->box(FL_PLASTIC_UP_BOX); + effchoruswindow->color((Fl_Color)221); + effchoruswindow->selection_color(FL_BACKGROUND_COLOR); + effchoruswindow->labeltype(FL_NO_LABEL); + effchoruswindow->labelfont(1); + effchoruswindow->labelsize(14); + effchoruswindow->labelcolor(FL_FOREGROUND_COLOR); + effchoruswindow->user_data((void*)(this)); + effchoruswindow->align(FL_ALIGN_TOP); + effchoruswindow->when(FL_WHEN_RELEASE); + { chorusp = new Fl_Choice(10, 15, 90, 15, "Preset"); + chorusp->down_box(FL_BORDER_BOX); + chorusp->color((Fl_Color)14); + chorusp->selection_color(FL_FOREGROUND_COLOR); + chorusp->labelfont(1); + chorusp->labelsize(10); + chorusp->textfont(1); + chorusp->textsize(10); + chorusp->textcolor(7); + chorusp->callback((Fl_Callback*)cb_choruspa); + chorusp->align(FL_ALIGN_TOP_LEFT); + chorusp->menu(menu_chorusp1); + } // Fl_Choice* chorusp + { Fl_Text_Display* o = new Fl_Text_Display(120, 10, 10, 20, "Chorus"); + o->box(FL_NO_BOX); + o->labeltype(FL_EMBOSSED_LABEL); + o->labelfont(1); + o->labelsize(22); + o->align(FL_ALIGN_RIGHT); + } // Fl_Text_Display* o + { chorusp0 = new WidgetPDial(10, 40, 30, 30, "Vol"); + chorusp0->tooltip("Effect Volume"); + chorusp0->box(FL_ROUND_UP_BOX); + chorusp0->color(FL_BACKGROUND_COLOR); + chorusp0->selection_color(FL_INACTIVE_COLOR); + chorusp0->labeltype(FL_NORMAL_LABEL); + chorusp0->labelfont(1); + chorusp0->labelsize(11); + chorusp0->labelcolor(FL_FOREGROUND_COLOR); + chorusp0->maximum(127); + chorusp0->callback((Fl_Callback*)cb_chorusp01); + chorusp0->align(FL_ALIGN_BOTTOM); + chorusp0->when(FL_WHEN_CHANGED); + } // WidgetPDial* chorusp0 + { chorusp2 = new WidgetPDial(45, 40, 30, 30, "Freq"); + chorusp2->tooltip("LFO Frequency"); + chorusp2->box(FL_ROUND_UP_BOX); + chorusp2->color(FL_BACKGROUND_COLOR); + chorusp2->selection_color(FL_INACTIVE_COLOR); + chorusp2->labeltype(FL_NORMAL_LABEL); + chorusp2->labelfont(1); + chorusp2->labelsize(11); + chorusp2->labelcolor(FL_FOREGROUND_COLOR); + chorusp2->maximum(127); + chorusp2->callback((Fl_Callback*)cb_chorusp21); + chorusp2->align(FL_ALIGN_BOTTOM); + chorusp2->when(FL_WHEN_CHANGED); + } // WidgetPDial* chorusp2 + { chorusp6 = new WidgetPDial(80, 40, 30, 30, "Dpth"); + chorusp6->tooltip("Depth"); + chorusp6->box(FL_ROUND_UP_BOX); + chorusp6->color(FL_BACKGROUND_COLOR); + chorusp6->selection_color(FL_INACTIVE_COLOR); + chorusp6->labeltype(FL_NORMAL_LABEL); + chorusp6->labelfont(1); + chorusp6->labelsize(11); + chorusp6->labelcolor(FL_FOREGROUND_COLOR); + chorusp6->maximum(127); + chorusp6->callback((Fl_Callback*)cb_chorusp61); + chorusp6->align(FL_ALIGN_BOTTOM); + chorusp6->when(FL_WHEN_CHANGED); + } // WidgetPDial* chorusp6 + { chorusp7 = new WidgetPDial(115, 40, 30, 30, "Delay"); + chorusp7->box(FL_ROUND_UP_BOX); + chorusp7->color(FL_BACKGROUND_COLOR); + chorusp7->selection_color(FL_INACTIVE_COLOR); + chorusp7->labeltype(FL_NORMAL_LABEL); + chorusp7->labelfont(1); + chorusp7->labelsize(11); + chorusp7->labelcolor(FL_FOREGROUND_COLOR); + chorusp7->maximum(127); + chorusp7->callback((Fl_Callback*)cb_chorusp71); + chorusp7->align(FL_ALIGN_BOTTOM); + chorusp7->when(FL_WHEN_CHANGED); + } // WidgetPDial* chorusp7 + { chorusp8 = new WidgetPDial(150, 40, 30, 30, "Fb"); + chorusp8->tooltip("Feedback"); + chorusp8->box(FL_ROUND_UP_BOX); + chorusp8->color(FL_BACKGROUND_COLOR); + chorusp8->selection_color(FL_INACTIVE_COLOR); + chorusp8->labeltype(FL_NORMAL_LABEL); + chorusp8->labelfont(1); + chorusp8->labelsize(11); + chorusp8->labelcolor(FL_FOREGROUND_COLOR); + chorusp8->maximum(127); + chorusp8->callback((Fl_Callback*)cb_chorusp81); + chorusp8->align(FL_ALIGN_BOTTOM); + chorusp8->when(FL_WHEN_CHANGED); + } // WidgetPDial* chorusp8 + { Fl_Check_Button* o = new Fl_Check_Button(120, 10, 55, 20, "Flange"); + o->box(FL_THIN_UP_BOX); + o->down_box(FL_DOWN_BOX); + o->color((Fl_Color)230); + o->labelfont(1); + o->labelsize(10); + o->callback((Fl_Callback*)cb_Flange1); + o->hide(); + o->deactivate(); + o->value(eff->geteffectpar(10)); + } // Fl_Check_Button* o + effchoruswindow->end(); + } // Fl_Group* effchoruswindow + return effchoruswindow; +} + +Fl_Group* SimpleEffUI::make_phaser_window() { + { effphaserwindow = new Fl_Group(0, 0, 230, 95); + effphaserwindow->box(FL_PLASTIC_UP_BOX); + effphaserwindow->color((Fl_Color)221); + effphaserwindow->selection_color(FL_BACKGROUND_COLOR); + effphaserwindow->labeltype(FL_NO_LABEL); + effphaserwindow->labelfont(1); + effphaserwindow->labelsize(14); + effphaserwindow->labelcolor(FL_FOREGROUND_COLOR); + effphaserwindow->user_data((void*)(this)); + effphaserwindow->align(FL_ALIGN_TOP); + effphaserwindow->when(FL_WHEN_RELEASE); + { phaserp = new Fl_Choice(10, 15, 90, 15, "Preset"); + phaserp->down_box(FL_BORDER_BOX); + phaserp->color((Fl_Color)14); + phaserp->selection_color(FL_FOREGROUND_COLOR); + phaserp->labelfont(1); + phaserp->labelsize(10); + phaserp->textfont(1); + phaserp->textsize(10); + phaserp->textcolor(7); + phaserp->callback((Fl_Callback*)cb_phaserpa); + phaserp->align(FL_ALIGN_TOP_LEFT); + phaserp->menu(menu_phaserp1); + } // Fl_Choice* phaserp + { Fl_Text_Display* o = new Fl_Text_Display(125, 10, 10, 20, "Phaser"); + o->box(FL_NO_BOX); + o->labeltype(FL_EMBOSSED_LABEL); + o->labelfont(1); + o->labelsize(22); + o->align(FL_ALIGN_RIGHT); + } // Fl_Text_Display* o + { phaserp0 = new WidgetPDial(10, 40, 30, 30, "Vol"); + phaserp0->tooltip("Effect Volume"); + phaserp0->box(FL_ROUND_UP_BOX); + phaserp0->color(FL_BACKGROUND_COLOR); + phaserp0->selection_color(FL_INACTIVE_COLOR); + phaserp0->labeltype(FL_NORMAL_LABEL); + phaserp0->labelfont(1); + phaserp0->labelsize(11); + phaserp0->labelcolor(FL_FOREGROUND_COLOR); + phaserp0->maximum(127); + phaserp0->callback((Fl_Callback*)cb_phaserp01); + phaserp0->align(FL_ALIGN_BOTTOM); + phaserp0->when(FL_WHEN_CHANGED); + } // WidgetPDial* phaserp0 + { phaserp2 = new WidgetPDial(45, 40, 30, 30, "Freq"); + phaserp2->tooltip("LFO frequency"); + phaserp2->box(FL_ROUND_UP_BOX); + phaserp2->color(FL_BACKGROUND_COLOR); + phaserp2->selection_color(FL_INACTIVE_COLOR); + phaserp2->labeltype(FL_NORMAL_LABEL); + phaserp2->labelfont(1); + phaserp2->labelsize(11); + phaserp2->labelcolor(FL_FOREGROUND_COLOR); + phaserp2->maximum(127); + phaserp2->callback((Fl_Callback*)cb_phaserp21); + phaserp2->align(FL_ALIGN_BOTTOM); + phaserp2->when(FL_WHEN_CHANGED); + } // WidgetPDial* phaserp2 + { phaserp5 = new WidgetPDial(80, 40, 30, 30, "St.df"); + phaserp5->tooltip("Left/Right Channel Phase Shift"); + phaserp5->box(FL_ROUND_UP_BOX); + phaserp5->color(FL_BACKGROUND_COLOR); + phaserp5->selection_color(FL_INACTIVE_COLOR); + phaserp5->labeltype(FL_NORMAL_LABEL); + phaserp5->labelfont(1); + phaserp5->labelsize(11); + phaserp5->labelcolor(FL_FOREGROUND_COLOR); + phaserp5->maximum(127); + phaserp5->callback((Fl_Callback*)cb_phaserp51); + phaserp5->align(FL_ALIGN_BOTTOM); + phaserp5->when(FL_WHEN_CHANGED); + } // WidgetPDial* phaserp5 + { phaserp6 = new WidgetPDial(115, 40, 30, 30, "Dpth"); + phaserp6->tooltip("Depth"); + phaserp6->box(FL_ROUND_UP_BOX); + phaserp6->color(FL_BACKGROUND_COLOR); + phaserp6->selection_color(FL_INACTIVE_COLOR); + phaserp6->labeltype(FL_NORMAL_LABEL); + phaserp6->labelfont(1); + phaserp6->labelsize(11); + phaserp6->labelcolor(FL_FOREGROUND_COLOR); + phaserp6->maximum(127); + phaserp6->callback((Fl_Callback*)cb_phaserp61); + phaserp6->align(FL_ALIGN_BOTTOM); + phaserp6->when(FL_WHEN_CHANGED); + } // WidgetPDial* phaserp6 + { phaserp7 = new WidgetPDial(150, 40, 30, 30, "Fb"); + phaserp7->tooltip("Feedback"); + phaserp7->box(FL_ROUND_UP_BOX); + phaserp7->color(FL_BACKGROUND_COLOR); + phaserp7->selection_color(FL_INACTIVE_COLOR); + phaserp7->labeltype(FL_NORMAL_LABEL); + phaserp7->labelfont(1); + phaserp7->labelsize(11); + phaserp7->labelcolor(FL_FOREGROUND_COLOR); + phaserp7->maximum(127); + phaserp7->callback((Fl_Callback*)cb_phaserp71); + phaserp7->align(FL_ALIGN_BOTTOM); + phaserp7->when(FL_WHEN_CHANGED); + } // WidgetPDial* phaserp7 + { Fl_Counter* o = phaserp8 = new Fl_Counter(185, 55, 35, 15, "Stages"); + phaserp8->type(1); + phaserp8->labelfont(1); + phaserp8->labelsize(11); + phaserp8->minimum(0); + phaserp8->maximum(127); + phaserp8->step(1); + phaserp8->callback((Fl_Callback*)cb_phaserp81); + o->range(1,MAX_PHASER_STAGES); + } // Fl_Counter* phaserp8 + effphaserwindow->end(); + } // Fl_Group* effphaserwindow + return effphaserwindow; +} + +Fl_Group* SimpleEffUI::make_alienwah_window() { + { effalienwahwindow = new Fl_Group(0, 0, 230, 95); + effalienwahwindow->box(FL_PLASTIC_UP_BOX); + effalienwahwindow->color((Fl_Color)221); + effalienwahwindow->selection_color(FL_BACKGROUND_COLOR); + effalienwahwindow->labeltype(FL_NO_LABEL); + effalienwahwindow->labelfont(1); + effalienwahwindow->labelsize(14); + effalienwahwindow->labelcolor(FL_FOREGROUND_COLOR); + effalienwahwindow->user_data((void*)(this)); + effalienwahwindow->align(FL_ALIGN_TOP); + effalienwahwindow->when(FL_WHEN_RELEASE); + { awp = new Fl_Choice(10, 15, 90, 15, "Preset"); + awp->down_box(FL_BORDER_BOX); + awp->color((Fl_Color)14); + awp->selection_color(FL_FOREGROUND_COLOR); + awp->labelfont(1); + awp->labelsize(10); + awp->textfont(1); + awp->textsize(10); + awp->textcolor(7); + awp->callback((Fl_Callback*)cb_awpa); + awp->align(FL_ALIGN_TOP_LEFT); + awp->menu(menu_awp1); + } // Fl_Choice* awp + { Fl_Text_Display* o = new Fl_Text_Display(100, 10, 10, 20, "AlienWah"); + o->box(FL_NO_BOX); + o->labeltype(FL_EMBOSSED_LABEL); + o->labelfont(1); + o->labelsize(22); + o->align(FL_ALIGN_RIGHT); + } // Fl_Text_Display* o + { awp0 = new WidgetPDial(10, 40, 30, 30, "Vol"); + awp0->tooltip("Effect Volume"); + awp0->box(FL_ROUND_UP_BOX); + awp0->color(FL_BACKGROUND_COLOR); + awp0->selection_color(FL_INACTIVE_COLOR); + awp0->labeltype(FL_NORMAL_LABEL); + awp0->labelfont(1); + awp0->labelsize(11); + awp0->labelcolor(FL_FOREGROUND_COLOR); + awp0->maximum(127); + awp0->callback((Fl_Callback*)cb_awp01); + awp0->align(FL_ALIGN_BOTTOM); + awp0->when(FL_WHEN_CHANGED); + } // WidgetPDial* awp0 + { awp2 = new WidgetPDial(45, 40, 30, 30, "Freq"); + awp2->tooltip("LFO frequency"); + awp2->box(FL_ROUND_UP_BOX); + awp2->color(FL_BACKGROUND_COLOR); + awp2->selection_color(FL_INACTIVE_COLOR); + awp2->labeltype(FL_NORMAL_LABEL); + awp2->labelfont(1); + awp2->labelsize(11); + awp2->labelcolor(FL_FOREGROUND_COLOR); + awp2->maximum(127); + awp2->callback((Fl_Callback*)cb_awp21); + awp2->align(FL_ALIGN_BOTTOM); + awp2->when(FL_WHEN_CHANGED); + } // WidgetPDial* awp2 + { awp6 = new WidgetPDial(85, 40, 30, 30, "Dpth"); + awp6->tooltip("Depth"); + awp6->box(FL_ROUND_UP_BOX); + awp6->color(FL_BACKGROUND_COLOR); + awp6->selection_color(FL_INACTIVE_COLOR); + awp6->labeltype(FL_NORMAL_LABEL); + awp6->labelfont(1); + awp6->labelsize(11); + awp6->labelcolor(FL_FOREGROUND_COLOR); + awp6->maximum(127); + awp6->callback((Fl_Callback*)cb_awp61); + awp6->align(FL_ALIGN_BOTTOM); + awp6->when(FL_WHEN_CHANGED); + } // WidgetPDial* awp6 + { Fl_Counter* o = awp8 = new Fl_Counter(125, 55, 35, 15, "Delay"); + awp8->type(1); + awp8->labelfont(1); + awp8->labelsize(11); + awp8->minimum(0); + awp8->maximum(127); + awp8->step(1); + awp8->callback((Fl_Callback*)cb_awp81); + o->range(1,MAX_ALIENWAH_DELAY); + } // Fl_Counter* awp8 + effalienwahwindow->end(); + } // Fl_Group* effalienwahwindow + return effalienwahwindow; +} + +Fl_Group* SimpleEffUI::make_distorsion_window() { + { effdistorsionwindow = new Fl_Group(0, 0, 230, 95); + effdistorsionwindow->box(FL_PLASTIC_UP_BOX); + effdistorsionwindow->color((Fl_Color)221); + effdistorsionwindow->selection_color(FL_BACKGROUND_COLOR); + effdistorsionwindow->labeltype(FL_NO_LABEL); + effdistorsionwindow->labelfont(1); + effdistorsionwindow->labelsize(14); + effdistorsionwindow->labelcolor(FL_FOREGROUND_COLOR); + effdistorsionwindow->user_data((void*)(this)); + effdistorsionwindow->align(FL_ALIGN_TOP); + effdistorsionwindow->when(FL_WHEN_RELEASE); + { distp = new Fl_Choice(11, 15, 95, 15, "Preset"); + distp->down_box(FL_BORDER_BOX); + distp->color((Fl_Color)14); + distp->selection_color(FL_FOREGROUND_COLOR); + distp->labelfont(1); + distp->labelsize(10); + distp->textfont(1); + distp->textsize(10); + distp->textcolor(7); + distp->callback((Fl_Callback*)cb_distpa); + distp->align(FL_ALIGN_TOP_LEFT); + distp->menu(menu_distp1); + } // Fl_Choice* distp + { Fl_Text_Display* o = new Fl_Text_Display(110, 10, 10, 20, "Distortion"); + o->box(FL_NO_BOX); + o->labeltype(FL_EMBOSSED_LABEL); + o->labelfont(1); + o->labelsize(16); + o->align(FL_ALIGN_RIGHT); + } // Fl_Text_Display* o + { distp0 = new WidgetPDial(10, 40, 30, 30, "Vol"); + distp0->tooltip("Effect Volume"); + distp0->box(FL_ROUND_UP_BOX); + distp0->color(FL_BACKGROUND_COLOR); + distp0->selection_color(FL_INACTIVE_COLOR); + distp0->labeltype(FL_NORMAL_LABEL); + distp0->labelfont(1); + distp0->labelsize(11); + distp0->labelcolor(FL_FOREGROUND_COLOR); + distp0->maximum(127); + distp0->callback((Fl_Callback*)cb_distp01); + distp0->align(FL_ALIGN_BOTTOM); + distp0->when(FL_WHEN_CHANGED); + } // WidgetPDial* distp0 + { distp3 = new WidgetPDial(45, 40, 30, 30, "Drive"); + distp3->tooltip("Input amplification"); + distp3->box(FL_ROUND_UP_BOX); + distp3->color(FL_BACKGROUND_COLOR); + distp3->selection_color(FL_INACTIVE_COLOR); + distp3->labeltype(FL_NORMAL_LABEL); + distp3->labelfont(1); + distp3->labelsize(11); + distp3->labelcolor(FL_FOREGROUND_COLOR); + distp3->maximum(127); + distp3->callback((Fl_Callback*)cb_distp31); + distp3->align(FL_ALIGN_BOTTOM); + distp3->when(FL_WHEN_RELEASE); + } // WidgetPDial* distp3 + { distp4 = new WidgetPDial(80, 40, 30, 30, "Level"); + distp4->tooltip("Output Amplification"); + distp4->box(FL_ROUND_UP_BOX); + distp4->color(FL_BACKGROUND_COLOR); + distp4->selection_color(FL_INACTIVE_COLOR); + distp4->labeltype(FL_NORMAL_LABEL); + distp4->labelfont(1); + distp4->labelsize(11); + distp4->labelcolor(FL_FOREGROUND_COLOR); + distp4->maximum(127); + distp4->callback((Fl_Callback*)cb_distp41); + distp4->align(FL_ALIGN_BOTTOM); + distp4->when(FL_WHEN_CHANGED); + } // WidgetPDial* distp4 + { distp7 = new WidgetPDial(190, 40, 30, 30, "LPF"); + distp7->tooltip("Low Pass Filter"); + distp7->box(FL_ROUND_UP_BOX); + distp7->color(FL_BACKGROUND_COLOR); + distp7->selection_color(FL_INACTIVE_COLOR); + distp7->labeltype(FL_NORMAL_LABEL); + distp7->labelfont(1); + distp7->labelsize(11); + distp7->labelcolor(FL_FOREGROUND_COLOR); + distp7->maximum(127); + distp7->callback((Fl_Callback*)cb_distp71); + distp7->align(FL_ALIGN_BOTTOM); + distp7->when(FL_WHEN_CHANGED); + } // WidgetPDial* distp7 + { distp5 = new Fl_Choice(120, 50, 60, 20, "Type"); + distp5->box(FL_UP_BOX); + distp5->down_box(FL_BORDER_BOX); + distp5->labelfont(1); + distp5->labelsize(11); + distp5->textsize(10); + distp5->callback((Fl_Callback*)cb_distp51); + distp5->align(FL_ALIGN_BOTTOM); + distp5->menu(menu_distp51); + } // Fl_Choice* distp5 + effdistorsionwindow->end(); + } // Fl_Group* effdistorsionwindow + return effdistorsionwindow; +} + +Fl_Group* SimpleEffUI::make_eq_window() { + { effeqwindow = new Fl_Group(0, 0, 230, 95); + effeqwindow->box(FL_PLASTIC_UP_BOX); + effeqwindow->color((Fl_Color)221); + effeqwindow->selection_color(FL_BACKGROUND_COLOR); + effeqwindow->labeltype(FL_NO_LABEL); + effeqwindow->labelfont(1); + effeqwindow->labelsize(14); + effeqwindow->labelcolor(FL_FOREGROUND_COLOR); + effeqwindow->user_data((void*)(this)); + effeqwindow->align(FL_ALIGN_TOP); + effeqwindow->when(FL_WHEN_RELEASE); + { Fl_Text_Display* o = new Fl_Text_Display(170, 5, 15, 25, "EQ"); + o->box(FL_NO_BOX); + o->labeltype(FL_EMBOSSED_LABEL); + o->labelfont(1); + o->labelsize(22); + o->align(FL_ALIGN_RIGHT); + } // Fl_Text_Display* o + { Fl_Counter* o = bandcounter = new Fl_Counter(85, 15, 45, 15, "Band"); + bandcounter->tooltip("Band no."); + bandcounter->type(1); + bandcounter->labelfont(1); + bandcounter->labelsize(11); + bandcounter->minimum(0); + bandcounter->maximum(1); + bandcounter->step(1); + bandcounter->textfont(1); + bandcounter->textsize(11); + bandcounter->callback((Fl_Callback*)cb_bandcounter1); + bandcounter->align(FL_ALIGN_TOP); + o->bounds(0,MAX_EQ_BANDS-1); + } // Fl_Counter* bandcounter + { Fl_Group* o = bandgroup = new Fl_Group(5, 5, 75, 85); + bandgroup->box(FL_ENGRAVED_FRAME); + { freqdial = new WidgetPDial(10, 10, 25, 25, "Freq"); + freqdial->box(FL_ROUND_UP_BOX); + freqdial->color(FL_BACKGROUND_COLOR); + freqdial->selection_color(FL_INACTIVE_COLOR); + freqdial->labeltype(FL_NORMAL_LABEL); + freqdial->labelfont(1); + freqdial->labelsize(10); + freqdial->labelcolor(FL_FOREGROUND_COLOR); + freqdial->maximum(127); + freqdial->callback((Fl_Callback*)cb_freqdial1); + freqdial->align(FL_ALIGN_BOTTOM); + freqdial->when(3); + } // WidgetPDial* freqdial + { gaindial = new WidgetPDial(45, 10, 25, 25, "Gain"); + gaindial->box(FL_ROUND_UP_BOX); + gaindial->color(FL_BACKGROUND_COLOR); + gaindial->selection_color(FL_INACTIVE_COLOR); + gaindial->labeltype(FL_NORMAL_LABEL); + gaindial->labelfont(1); + gaindial->labelsize(10); + gaindial->labelcolor(FL_FOREGROUND_COLOR); + gaindial->maximum(127); + gaindial->step(1); + gaindial->callback((Fl_Callback*)cb_gaindial1); + gaindial->align(FL_ALIGN_BOTTOM); + gaindial->when(3); + } // WidgetPDial* gaindial + { qdial = new WidgetPDial(10, 50, 25, 25, "Q"); + qdial->tooltip("Bandwidth/Resonance"); + qdial->box(FL_ROUND_UP_BOX); + qdial->color(FL_BACKGROUND_COLOR); + qdial->selection_color(FL_INACTIVE_COLOR); + qdial->labeltype(FL_NORMAL_LABEL); + qdial->labelfont(1); + qdial->labelsize(10); + qdial->labelcolor(FL_FOREGROUND_COLOR); + qdial->maximum(127); + qdial->callback((Fl_Callback*)cb_qdial1); + qdial->align(FL_ALIGN_BOTTOM); + qdial->when(3); + } // WidgetPDial* qdial + { Fl_Counter* o = stagescounter = new Fl_Counter(40, 55, 30, 15, "Stages"); + stagescounter->tooltip("Additional filter stages"); + stagescounter->type(1); + stagescounter->labelfont(1); + stagescounter->labelsize(10); + stagescounter->minimum(1); + stagescounter->maximum(127); + stagescounter->step(1); + stagescounter->textfont(1); + stagescounter->textsize(11); + stagescounter->callback((Fl_Callback*)cb_stagescounter1); + o->bounds(0,MAX_FILTER_STAGES-1); + } // Fl_Counter* stagescounter + if (eff->geteffectpar(10)==0) o->deactivate(); + bandgroup->end(); + } // Fl_Group* bandgroup + { typechoice = new Fl_Choice(135, 15, 40, 15, "Type"); + typechoice->tooltip("Type"); + typechoice->down_box(FL_BORDER_BOX); + typechoice->labelfont(1); + typechoice->labelsize(10); + typechoice->textsize(10); + typechoice->callback((Fl_Callback*)cb_typechoice1); + typechoice->align(FL_ALIGN_TOP); + typechoice->when(FL_WHEN_RELEASE_ALWAYS); + typechoice->menu(menu_typechoice1); + } // Fl_Choice* typechoice + { EQGraph* o = eqgraph = new EQGraph(85, 35, 140, 55); + eqgraph->box(FL_BORDER_BOX); + eqgraph->color((Fl_Color)178); + eqgraph->selection_color(FL_BACKGROUND_COLOR); + eqgraph->labeltype(FL_NORMAL_LABEL); + eqgraph->labelfont(0); + eqgraph->labelsize(14); + eqgraph->labelcolor(FL_FOREGROUND_COLOR); + eqgraph->align(FL_ALIGN_CENTER); + eqgraph->when(FL_WHEN_RELEASE); + o->init(eff); + } // EQGraph* eqgraph + effeqwindow->end(); + } // Fl_Group* effeqwindow + return effeqwindow; +} + +Fl_Group* SimpleEffUI::make_dynamicfilter_window() { + { effdynamicfilterwindow = new Fl_Group(0, 0, 230, 95); + effdynamicfilterwindow->box(FL_PLASTIC_UP_BOX); + effdynamicfilterwindow->color((Fl_Color)221); + effdynamicfilterwindow->selection_color(FL_BACKGROUND_COLOR); + effdynamicfilterwindow->labeltype(FL_NO_LABEL); + effdynamicfilterwindow->labelfont(1); + effdynamicfilterwindow->labelsize(14); + effdynamicfilterwindow->labelcolor(FL_FOREGROUND_COLOR); + effdynamicfilterwindow->user_data((void*)(this)); + effdynamicfilterwindow->align(FL_ALIGN_TOP); + effdynamicfilterwindow->when(FL_WHEN_RELEASE); + { dfp = new Fl_Choice(10, 15, 90, 15, "Preset"); + dfp->down_box(FL_BORDER_BOX); + dfp->color((Fl_Color)14); + dfp->selection_color(FL_FOREGROUND_COLOR); + dfp->labelfont(1); + dfp->labelsize(10); + dfp->textfont(1); + dfp->textsize(10); + dfp->textcolor(7); + dfp->callback((Fl_Callback*)cb_dfpa); + dfp->align(FL_ALIGN_TOP_LEFT); + dfp->menu(menu_dfp1); + } // Fl_Choice* dfp + { Fl_Text_Display* o = new Fl_Text_Display(100, 10, 10, 20, "DynFilter"); + o->box(FL_NO_BOX); + o->labeltype(FL_EMBOSSED_LABEL); + o->labelfont(1); + o->labelsize(22); + o->align(FL_ALIGN_RIGHT); + } // Fl_Text_Display* o + { dfp0 = new WidgetPDial(10, 40, 30, 30, "Vol"); + dfp0->tooltip("Effect Volume"); + dfp0->box(FL_ROUND_UP_BOX); + dfp0->color(FL_BACKGROUND_COLOR); + dfp0->selection_color(FL_INACTIVE_COLOR); + dfp0->labeltype(FL_NORMAL_LABEL); + dfp0->labelfont(1); + dfp0->labelsize(11); + dfp0->labelcolor(FL_FOREGROUND_COLOR); + dfp0->maximum(127); + dfp0->callback((Fl_Callback*)cb_dfp01); + dfp0->align(FL_ALIGN_BOTTOM); + dfp0->when(FL_WHEN_CHANGED); + } // WidgetPDial* dfp0 + { dfp2 = new WidgetPDial(45, 40, 30, 30, "Freq"); + dfp2->tooltip("LFO frequency"); + dfp2->box(FL_ROUND_UP_BOX); + dfp2->color(FL_BACKGROUND_COLOR); + dfp2->selection_color(FL_INACTIVE_COLOR); + dfp2->labeltype(FL_NORMAL_LABEL); + dfp2->labelfont(1); + dfp2->labelsize(11); + dfp2->labelcolor(FL_FOREGROUND_COLOR); + dfp2->maximum(127); + dfp2->callback((Fl_Callback*)cb_dfp21); + dfp2->align(FL_ALIGN_BOTTOM); + dfp2->when(FL_WHEN_CHANGED); + } // WidgetPDial* dfp2 + { dfp6 = new WidgetPDial(80, 40, 30, 30, "LfoD"); + dfp6->tooltip("LFO depth"); + dfp6->box(FL_ROUND_UP_BOX); + dfp6->color(FL_BACKGROUND_COLOR); + dfp6->selection_color(FL_INACTIVE_COLOR); + dfp6->labeltype(FL_NORMAL_LABEL); + dfp6->labelfont(1); + dfp6->labelsize(11); + dfp6->labelcolor(FL_FOREGROUND_COLOR); + dfp6->maximum(127); + dfp6->callback((Fl_Callback*)cb_dfp61); + dfp6->align(FL_ALIGN_BOTTOM); + dfp6->when(FL_WHEN_CHANGED); + } // WidgetPDial* dfp6 + { Fl_Group* o = new Fl_Group(115, 40, 65, 45); + o->box(FL_BORDER_BOX); + o->color((Fl_Color)181); + { dfp7 = new WidgetPDial(120, 45, 25, 25, "A.S."); + dfp7->tooltip("how filter varies with amplitude"); + dfp7->box(FL_ROUND_UP_BOX); + dfp7->color(FL_BACKGROUND_COLOR); + dfp7->selection_color(FL_INACTIVE_COLOR); + dfp7->labeltype(FL_NORMAL_LABEL); + dfp7->labelfont(1); + dfp7->labelsize(11); + dfp7->labelcolor(FL_FOREGROUND_COLOR); + dfp7->maximum(127); + dfp7->callback((Fl_Callback*)cb_dfp71); + dfp7->align(FL_ALIGN_BOTTOM); + dfp7->when(FL_WHEN_CHANGED); + } // WidgetPDial* dfp7 + { dfp9 = new WidgetPDial(150, 45, 25, 25, "A.M"); + dfp9->tooltip("how quickly the filter varies with amplitude"); + dfp9->box(FL_ROUND_UP_BOX); + dfp9->color(FL_BACKGROUND_COLOR); + dfp9->selection_color(FL_INACTIVE_COLOR); + dfp9->labeltype(FL_NORMAL_LABEL); + dfp9->labelfont(1); + dfp9->labelsize(11); + dfp9->labelcolor(FL_FOREGROUND_COLOR); + dfp9->maximum(127); + dfp9->callback((Fl_Callback*)cb_dfp91); + dfp9->align(FL_ALIGN_BOTTOM); + dfp9->when(FL_WHEN_CHANGED); + } // WidgetPDial* dfp9 + o->end(); + } // Fl_Group* o + effdynamicfilterwindow->end(); + } // Fl_Group* effdynamicfilterwindow + return effdynamicfilterwindow; +} + +void SimpleEffUI::init(EffectMgr *eff_) { + eff=eff_; + +make_null_window(); +make_reverb_window(); +make_echo_window(); +make_chorus_window(); +make_phaser_window(); +make_alienwah_window(); +make_distorsion_window(); +make_eq_window(); +make_dynamicfilter_window(); + +int px=this->parent()->x(); +int py=this->parent()->y(); + +effnullwindow->position(px,py); +effreverbwindow->position(px,py); +effechowindow->position(px,py); +effchoruswindow->position(px,py); +effphaserwindow->position(px,py); +effalienwahwindow->position(px,py); +effdistorsionwindow->position(px,py); +effeqwindow->position(px,py); +effdynamicfilterwindow->position(px,py); + +refresh(eff); +} + +void SimpleEffUI::refresh(EffectMgr *eff_) { + eff=eff_; +this->hide(); + +effnullwindow->hide(); +effreverbwindow->hide(); +effechowindow->hide(); +effchoruswindow->hide(); +effphaserwindow->hide(); +effalienwahwindow->hide(); +effdistorsionwindow->hide(); +effeqwindow->hide(); +effdynamicfilterwindow->hide(); + +eqband=0; + + +switch(eff->geteffect()){ + case 1: + revp->value(eff->getpreset()); + revp0->value(eff->geteffectpar(0));if (eff->insertion!=0) revp0->label("D/W"); + revp2->value(eff->geteffectpar(2)); + revp3->value(eff->geteffectpar(3)); + revp9->value(eff->geteffectpar(9)); + effreverbwindow->show(); + break; + case 2: + echop->value(eff->getpreset()); + echop0->value(eff->geteffectpar(0));if (eff->insertion!=0) echop0->label("D/W"); + echop2->value(eff->geteffectpar(2)); + echop5->value(eff->geteffectpar(5)); + effechowindow->show(); + break; + case 3: + chorusp->value(eff->getpreset()); + chorusp0->value(eff->geteffectpar(0));if (eff->insertion!=0) chorusp0->label("D/W"); + chorusp2->value(eff->geteffectpar(2)); + chorusp6->value(eff->geteffectpar(6)); + chorusp7->value(eff->geteffectpar(7)); + chorusp8->value(eff->geteffectpar(8)); + effchoruswindow->show(); + break; + case 4: + phaserp->value(eff->getpreset()); + phaserp0->value(eff->geteffectpar(0));if (eff->insertion!=0) phaserp0->label("D/W"); + phaserp2->value(eff->geteffectpar(2)); + phaserp5->value(eff->geteffectpar(5)); + phaserp6->value(eff->geteffectpar(6)); + phaserp7->value(eff->geteffectpar(7)); + phaserp8->value(eff->geteffectpar(8)); + effphaserwindow->show(); + break; + case 5: + awp->value(eff->getpreset()); + awp0->value(eff->geteffectpar(0));if (eff->insertion!=0) awp0->label("D/W"); + awp2->value(eff->geteffectpar(2)); + awp6->value(eff->geteffectpar(6)); + awp8->value(eff->geteffectpar(8)); + effalienwahwindow->show(); + break; + case 6: + distp->value(eff->getpreset()); + distp0->value(eff->geteffectpar(0));if (eff->insertion!=0) distp0->label("D/W"); + distp3->value(eff->geteffectpar(3)); + distp4->value(eff->geteffectpar(4)); + distp5->value(eff->geteffectpar(5)); + distp7->value(eff->geteffectpar(7)); + effdistorsionwindow->show(); + break; + case 7: + bandcounter->value(eqband); + bandcounter->do_callback(); + typechoice->value(eff->geteffectpar(10)); + eqgraph->redraw(); + freqdial->value(eff->geteffectpar(11)); + gaindial->value(eff->geteffectpar(12)); + if (eff->geteffectpar(10)<6) gaindial->deactivate(); + qdial->value(eff->geteffectpar(13)); + stagescounter->value(eff->geteffectpar(14)); + eqgraph->init(eff); + effeqwindow->show(); + break; + case 8: + dfp->value(eff->getpreset()); + dfp0->value(eff->geteffectpar(0));if (eff->insertion!=0) dfp0->label("D/W"); + dfp2->value(eff->geteffectpar(2)); + dfp6->value(eff->geteffectpar(6)); + dfp7->value(eff->geteffectpar(7)); + dfp9->value(eff->geteffectpar(9)); + + + effdynamicfilterwindow->show(); + break; + default:effnullwindow->show(); + break; +}; + +this->show(); +} + +void SimpleEffUI::refresh() { + refresh(eff); +} diff --git a/plugins/zynaddsubfx/src/UI/EffUI.fl b/plugins/zynaddsubfx/src/UI/EffUI.fl new file mode 100644 index 000000000..e2712f107 --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/EffUI.fl @@ -0,0 +1,2308 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0107 +header_name {.h} +code_name {.cc} +decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} + +decl {//License: GNU GPL version 2 or later} {} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include "../globals.h"} {public +} + +decl {\#include "WidgetPDial.h"} {public +} + +decl {\#include "EnvelopeUI.h"} {public +} + +decl {\#include "FilterUI.h"} {public +} + +decl {\#include "../Misc/Util.h"} {public +} + +decl {\#include "../Effects/EffectMgr.h"} {public +} + +decl {\#include "PresetsUI.h"} {public +} + +class EQGraph {selected : {public Fl_Box} +} { + Function {EQGraph(int x,int y, int w, int h, const char *label=0):Fl_Box(x,y,w,h,label)} {} { + code {eff=NULL; +maxdB=30;} {} + } + Function {init(EffectMgr *eff_)} {} { + code {eff=eff_; +oldx=-1; +khzval=-1;} {} + } + Function {draw_freq_line(REALTYPE freq,int type)} {} { + code {fl_color(FL_GRAY); +REALTYPE freqx=getfreqpos(freq); +switch(type){ + case 0:if (active_r()) fl_color(FL_WHITE); + else fl_color(205,205,205); + fl_line_style(FL_SOLID); + break; + case 1:fl_line_style(FL_DOT);break; + case 2:fl_line_style(FL_DASH);break; +}; + + +if ((freqx>0.0)&&(freqx<1.0)) + fl_line(x()+(int) (freqx*w()),y(), + x()+(int) (freqx*w()),y()+h());} {} + } + Function {draw()} {} { + code {int ox=x(),oy=y(),lx=w(),ly=h(),i,iy,oiy; +REALTYPE freqx; + +if (active_r()) fl_color(0,70,150); + else fl_color(80,120,160); +fl_rectf(ox,oy,lx,ly); + + +//draw the lines +fl_color(FL_GRAY); + +fl_line_style(FL_SOLID); +fl_line(ox+2,oy+ly/2,ox+lx-2,oy+ly/2); + +freqx=getfreqpos(1000.0); +if ((freqx>0.0)&&(freqx<1.0)) + fl_line(ox+(int) (freqx*lx),oy, + ox+(int) (freqx*lx),oy+ly); + +for (i=1;i<10;i++){ + if(i==1){ + draw_freq_line(i*100.0,0); + draw_freq_line(i*1000.0,0); + }else + if (i==5){ + draw_freq_line(i*10.0,2); + draw_freq_line(i*100.0,2); + draw_freq_line(i*1000.0,2); + }else{ + draw_freq_line(i*10.0,1); + draw_freq_line(i*100.0,1); + draw_freq_line(i*1000.0,1); + }; +}; + +draw_freq_line(10000.0,0); +draw_freq_line(20000.0,1); + + +fl_line_style(FL_DOT); +int GY=6;if (lySAMPLE_RATE/2) break; + iy=getresponse(ly,frq); + if ((oiy>=0) && (oiy=0) && (iygetEQfreqresponse(freq); +int idbresp=(int) ((dbresp/maxdB+1.0)*maxy/2.0); + + +//fprintf(stderr,"%.5f\\n",(dbresp/maxdB+1.0)*maxy/2.0); + + +return(idbresp);} {} + } + Function {getfreqx(REALTYPE x)} {return_type REALTYPE + } { + code {if (x>1.0) x=1.0; +return(20.0*pow((REALTYPE)1000.0,x));} {} + } + Function {getfreqpos(REALTYPE freq)} {return_type REALTYPE + } { + code {if (freq<0.00001) freq=0.00001; +return(log(freq/20.0)/log(1000.0));} {} + } + decl {int oldx,oldy;} {} + decl {REALTYPE khzval;} {public + } + decl {EffectMgr *eff;} {} + decl {int maxdB;} {} +} + +class EffUI {: {public Fl_Group,public PresetsUI_} +} { + Function {EffUI(int x,int y, int w, int h, const char *label=0):Fl_Group(x,y,w,h,label)} {} { + code {eff=NULL; +filterwindow=NULL;} {} + } + Function {~EffUI()} {} { + code {effnullwindow->hide();//delete (effnullwindow); +effreverbwindow->hide();//delete (effreverbwindow); +effechowindow->hide();//delete (effechowindow); +effchoruswindow->hide();//delete (effchoruswindow); +effphaserwindow->hide();//delete (effphaserwindow); +effalienwahwindow->hide();//delete (effalienwahwindow); +effdistorsionwindow->hide();//delete (effdistorsionwindow); +effeqwindow->hide();//delete (effeqwindow); +effdynamicfilterwindow->hide();//delete (effdynamicfilterwindow); + +if (filterwindow!=NULL){ + filterwindow->hide(); + delete(filterwindow); +};} {} + } + Function {make_null_window()} {} { + Fl_Window effnullwindow { + xywh {287 379 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide + class Fl_Group + } { + Fl_Text_Display {} { + label {No Effect} + xywh {120 35 10 20} box NO_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 22 labelcolor 43 align 8 + } + } + } + Function {make_reverb_window()} {} { + Fl_Window effreverbwindow { + xywh {343 337 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide + class Fl_Group + } { + Fl_Text_Display {} { + label {Reverb } + xywh {275 10 10 20} box NO_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 22 align 8 + } + Fl_Choice revp { + label Preset + callback {eff->changepreset((int)o->value()); + +refresh(eff);} + xywh {10 15 90 15} down_box BORDER_BOX color 14 selection_color 0 labelfont 1 labelsize 10 align 5 textfont 1 textsize 10 textcolor 7 + } { + MenuItem {} { + label {Cathedral 1} + xywh {10 10 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Cathedral 2} + xywh {20 20 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Cathedral 3} + xywh {30 30 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Hall 1} + xywh {40 40 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Hall 2} + xywh {50 50 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Room 1} + xywh {60 60 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Room 2} + xywh {70 70 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label Basement + xywh {80 80 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label Tunnel + xywh {90 90 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Echoed 1} + xywh {100 100 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Echoed 2} + xywh {110 110 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Very Long 1} + xywh {120 120 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Very Long 2} + xywh {130 130 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + } + Fl_Choice revp10 { + label Type + callback {eff->seteffectpar(10,(int) o->value());} + xywh {110 15 75 15} down_box BORDER_BOX color 14 labelfont 1 labelsize 10 align 5 textfont 1 textsize 10 textcolor 7 + } { + MenuItem {} { + label Random + xywh {20 20 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label Freeverb + xywh {30 30 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + } + Fl_Dial revp0 { + label Vol + callback {eff->seteffectpar(0,(int) o->value());} + tooltip {Effect Volume} xywh {10 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial revp1 { + label Pan + callback {eff->seteffectpar(1,(int) o->value());} + xywh {45 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial revp2 { + label Time + callback {eff->seteffectpar(2,(int) o->value());} + tooltip {Duration of Effect} xywh {80 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial revp3 { + label {I.del} + callback {eff->seteffectpar(3,(int) o->value());} + tooltip {Initial Delay} xywh {120 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 when 4 maximum 127 + class WidgetPDial + } + Fl_Dial revp4 { + label {I.delfb} + callback {eff->seteffectpar(4,(int) o->value());} + tooltip {Initial Delay Feedback} xywh {155 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial revp5 { + label {R.delay} + callback {eff->seteffectpar(5,(int) o->value());} + xywh {200 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 when 4 maximum 127 deactivate + class WidgetPDial + } + Fl_Dial revp6 { + label {E/R} + callback {eff->seteffectpar(6,(int) o->value());} + xywh {235 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 deactivate + class WidgetPDial + } + Fl_Dial revp7 { + label LPF + callback {eff->seteffectpar(7,(int) o->value());} + tooltip {Low Pass Filter} xywh {270 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial revp8 { + label HPF + callback {eff->seteffectpar(8,(int) o->value());} + tooltip {High Pass Filter} xywh {305 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial revp9 { + label Damp + callback {eff->seteffectpar(9,(int) o->value());} + tooltip Dampening xywh {340 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 minimum 64 maximum 127 step 1 + class WidgetPDial + } + Fl_Dial revp11 { + label {R.S.} + callback {int x=64; +if (Fl::event_button1()) x=(int)o->value(); + else o->value(x); +eff->seteffectpar(11,x);} + tooltip RoomSize xywh {190 10 25 25} box ROUND_UP_BOX labelfont 1 labelsize 8 align 8 minimum 1 maximum 127 step 1 + class WidgetPDial + } + } + } + Function {make_echo_window()} {} { + Fl_Window effechowindow { + xywh {318 364 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide + class Fl_Group + } { + Fl_Choice echop { + label Preset + callback {eff->changepreset((int)o->value()); +refresh(eff);} + xywh {11 15 95 15} down_box BORDER_BOX color 14 selection_color 0 labelfont 1 labelsize 10 align 5 textfont 1 textsize 10 textcolor 7 + } { + MenuItem {} { + label {Echo 1} + xywh {20 20 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Echo 2} + xywh {30 30 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Echo 3} + xywh {40 40 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Simple Echo} + xywh {50 50 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label Canyon + xywh {60 60 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Panning Echo 1} + xywh {70 70 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Panning Echo 2} + xywh {80 80 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Panning Echo 3} + xywh {90 90 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Feedback Echo} + xywh {100 100 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + } + Fl_Text_Display {} { + label Echo + xywh {295 10 10 20} box NO_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 22 align 8 + } + Fl_Dial echop0 { + label Vol + callback {eff->seteffectpar(0,(int) o->value());} + tooltip {Effect Volume} xywh {10 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial echop1 { + label Pan + callback {eff->seteffectpar(1,(int) o->value());} + xywh {45 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial echop2 { + label Delay + callback {eff->seteffectpar(2,(int) o->value());} + xywh {80 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 when 4 maximum 127 + class WidgetPDial + } + Fl_Dial echop3 { + label {LRdl.} + callback {eff->seteffectpar(3,(int) o->value());} + tooltip {Delay Between L/R} xywh {120 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 when 4 maximum 127 + class WidgetPDial + } + Fl_Dial echop4 { + label {LRc.} + callback {eff->seteffectpar(4,(int) o->value());} + tooltip {L/R Crossover} xywh {155 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial echop5 { + label {Fb.} + callback {eff->seteffectpar(5,(int) o->value());} + tooltip Feedback xywh {195 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial echop6 { + label Damp + callback {eff->seteffectpar(6,(int) o->value());} + tooltip Dampening xywh {235 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + } + } + Function {make_chorus_window()} {} { + Fl_Window effchoruswindow { + xywh {372 287 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide + class Fl_Group + } { + Fl_Choice chorusp { + label Preset + callback {eff->changepreset((int)o->value()); +refresh(eff);} + xywh {10 15 90 15} down_box BORDER_BOX color 14 selection_color 0 labelfont 1 labelsize 10 align 5 textfont 1 textsize 10 textcolor 7 + } { + MenuItem {} { + label {Chorus 1} + xywh {20 20 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Chorus 2} + xywh {30 30 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Chorus 3} + xywh {40 40 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Celeste 1} + xywh {50 50 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Celeste 2} + xywh {60 60 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Flange 1} + xywh {70 70 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Flange 2} + xywh {80 80 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Flange 3} + xywh {90 90 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Flange 4} + xywh {100 100 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Flange 5} + xywh {110 110 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + } + Fl_Text_Display {} { + label Chorus + xywh {265 10 10 20} box NO_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 22 align 8 + } + Fl_Dial chorusp0 { + label Vol + callback {eff->seteffectpar(0,(int) o->value());} + xywh {10 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial chorusp1 { + label Pan + callback {eff->seteffectpar(1,(int) o->value());} + xywh {45 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial chorusp2 { + label Freq + callback {eff->seteffectpar(2,(int) o->value());} + tooltip {LFO Frequency} xywh {85 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial chorusp3 { + label Rnd + callback {eff->seteffectpar(3,(int) o->value());} + tooltip {LFO Randomness} xywh {120 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 when 4 maximum 127 + class WidgetPDial + } + Fl_Dial chorusp5 { + label {St.df} + callback {eff->seteffectpar(5,(int) o->value());} + tooltip {L/R Phase Shift} xywh {200 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial chorusp6 { + label Dpth + callback {eff->seteffectpar(6,(int) o->value());} + tooltip {LFO Depth} xywh {235 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial chorusp7 { + label Delay + callback {eff->seteffectpar(7,(int) o->value());} + xywh {270 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial chorusp8 { + label Fb + callback {eff->seteffectpar(8,(int) o->value());} + tooltip Feedback xywh {305 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial chorusp9 { + label {L/R} + callback {eff->seteffectpar(9,(int) o->value());} + tooltip {Channel Routing} xywh {340 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Check_Button {} { + label Flange + callback {eff->seteffectpar(10,(int) o->value());} + xywh {120 10 55 20} box THIN_UP_BOX down_box DOWN_BOX color 230 labelfont 1 labelsize 10 hide deactivate + code0 {o->value(eff->geteffectpar(10));} + } + Fl_Check_Button chorusp11 { + label Substract + callback {eff->seteffectpar(11,(int) o->value());} + tooltip {inverts the output} xywh {185 10 70 20} box THIN_UP_BOX down_box DOWN_BOX color 230 labelfont 1 labelsize 10 + } + Fl_Choice chorusp4 { + label {LFO type} + callback {eff->seteffectpar(4,(int) o->value());} + tooltip {LFO function} xywh {155 50 40 15} down_box BORDER_BOX labelfont 1 labelsize 10 align 130 textsize 8 + } { + MenuItem {} { + label SINE + xywh {15 15 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label TRI + xywh {25 25 100 20} labelfont 1 labelsize 10 + } + } + } + } + Function {make_phaser_window()} {} { + Fl_Window effphaserwindow { + xywh {389 213 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide + class Fl_Group + } { + Fl_Choice phaserp { + label Preset + callback {eff->changepreset((int)o->value()); +refresh(eff);} + xywh {10 15 90 15} down_box BORDER_BOX color 14 selection_color 0 labelfont 1 labelsize 10 align 5 textfont 1 textsize 10 textcolor 7 + } { + MenuItem {} { + label {Phaser 1} + xywh {30 30 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Phaser 2} + xywh {40 40 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Phaser 3} + xywh {50 50 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Phaser 4} + xywh {60 60 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Phaser 5} + xywh {70 70 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Phaser 6} + xywh {80 80 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + } + Fl_Text_Display {} { + label Phaser + xywh {275 10 10 20} box NO_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 22 align 8 + } + Fl_Dial phaserp0 { + label Vol + callback {eff->seteffectpar(0,(int) o->value());} + tooltip {Effect Volume} xywh {10 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial phaserp1 { + label Pan + callback {eff->seteffectpar(1,(int) o->value());} + xywh {45 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial phaserp2 { + label Freq + callback {eff->seteffectpar(2,(int) o->value());} + tooltip {LFO frequency} xywh {85 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial phaserp3 { + label Rnd + callback {eff->seteffectpar(3,(int) o->value());} + tooltip {LFO randomness} xywh {120 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 when 4 maximum 127 + class WidgetPDial + } + Fl_Dial phaserp5 { + label {St.df} + callback {eff->seteffectpar(5,(int) o->value());} + tooltip {Left/Right Channel Phase Shift} xywh {200 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial phaserp6 { + label Dpth + callback {eff->seteffectpar(6,(int) o->value());} + tooltip {LFO Depth} xywh {235 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial phaserp7 { + label Fb + callback {eff->seteffectpar(7,(int) o->value());} + tooltip Feedback xywh {270 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial phaserp9 { + label {L/R} + callback {eff->seteffectpar(9,(int) o->value());} + tooltip {Channel Routing} xywh {345 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Check_Button phaserp10 { + label Substract + callback {eff->seteffectpar(10,(int) o->value());} + tooltip {inverts output} xywh {185 10 74 20} box THIN_UP_BOX down_box DOWN_BOX color 230 labelfont 1 labelsize 10 + } + Fl_Choice phaserp4 { + label {LFO type} + callback {eff->seteffectpar(4,(int) o->value());} + tooltip {LFO function} xywh {155 50 40 15} down_box BORDER_BOX labelfont 1 labelsize 10 align 130 textsize 8 + } { + MenuItem {} { + label SINE + xywh {15 15 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label TRI + xywh {25 25 100 20} labelfont 1 labelsize 10 + } + } + Fl_Counter phaserp8 { + label Stages + callback {eff->seteffectpar(8,(int) o->value());} + xywh {305 55 35 15} type Simple labelfont 1 labelsize 11 minimum 0 maximum 127 step 1 + code0 {o->range(1,MAX_PHASER_STAGES);} + } + Fl_Dial phaserp11 { + label Phase + callback {eff->seteffectpar(11,(int) o->value());} + xywh {155 10 25 25} box ROUND_UP_BOX labelfont 1 labelsize 10 maximum 127 + class WidgetPDial + } + } + } + Function {make_alienwah_window()} {} { + Fl_Window effalienwahwindow { + xywh {538 250 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide + class Fl_Group + } { + Fl_Choice awp { + label Preset + callback {eff->changepreset((int)o->value()); +refresh(eff);} + xywh {10 15 90 15} down_box BORDER_BOX color 14 selection_color 0 labelfont 1 labelsize 10 align 5 textfont 1 textsize 10 textcolor 7 + } { + MenuItem {} { + label {Alienwah 1} + xywh {40 40 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Alienwah 2} + xywh {50 50 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Alienwah 3} + xywh {60 60 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Alienwah 4} + xywh {70 70 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + } + Fl_Text_Display {} { + label AlienWah + xywh {245 10 10 20} box NO_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 22 align 8 + } + Fl_Dial awp0 { + label Vol + callback {eff->seteffectpar(0,(int) o->value());} + tooltip {Effect Volume} xywh {10 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial awp1 { + label Pan + callback {eff->seteffectpar(1,(int) o->value());} + xywh {45 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial awp2 { + label Freq + callback {eff->seteffectpar(2,(int) o->value());} + tooltip {LFO Frequency} xywh {85 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial awp3 { + label Rnd + callback {eff->seteffectpar(3,(int) o->value());} + tooltip {LFO Randomness} xywh {120 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 when 4 maximum 127 + class WidgetPDial + } + Fl_Dial awp5 { + label {St.df} + callback {eff->seteffectpar(5,(int) o->value());} + tooltip {Left/Right Channel Phase Shift} xywh {200 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial awp6 { + label Dpth + callback {eff->seteffectpar(6,(int) o->value());} + tooltip Depth xywh {235 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial awp7 { + label Fb + callback {eff->seteffectpar(7,(int) o->value());} + tooltip Feedback xywh {270 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial awp9 { + label {L/R} + callback {eff->seteffectpar(9,(int) o->value());} + xywh {345 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Choice awp4 { + label {LFO type} + callback {eff->seteffectpar(4,(int) o->value());} + tooltip {LFO function} xywh {155 50 40 15} down_box BORDER_BOX labelfont 1 labelsize 10 align 130 textsize 8 + } { + MenuItem {} { + label SINE + xywh {15 15 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label TRI + xywh {25 25 100 20} labelfont 1 labelsize 10 + } + } + Fl_Dial awp10 { + label Phase + callback {eff->seteffectpar(10,(int) o->value());} + xywh {160 5 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Counter awp8 { + label Delay + callback {eff->seteffectpar(8,(int) o->value());} + xywh {305 55 35 15} type Simple labelfont 1 labelsize 11 minimum 0 maximum 127 step 1 + code0 {o->range(1,MAX_ALIENWAH_DELAY);} + } + } + } + Function {make_distorsion_window()} {} { + Fl_Window effdistorsionwindow { + xywh {409 143 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide + class Fl_Group + } { + Fl_Choice distp { + label Preset + callback {eff->changepreset((int)o->value()); +refresh(eff);} + xywh {11 15 95 15} down_box BORDER_BOX color 14 selection_color 0 labelfont 1 labelsize 10 align 5 textfont 1 textsize 10 textcolor 7 + } { + MenuItem {} { + label {Overdrive 1} + xywh {20 20 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Overdrive 2} + xywh {30 30 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {A. Exciter 1} + xywh {40 40 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {A. Exciter 2} + xywh {50 50 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Guitar Amp} + xywh {50 50 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label Quantisize + xywh {60 60 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + } + Fl_Text_Display {} { + label Distortion + xywh {230 10 10 20} box NO_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 22 align 8 + } + Fl_Dial distp0 { + label Vol + callback {eff->seteffectpar(0,(int) o->value());} + tooltip {Effect Volume} xywh {10 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial distp1 { + label Pan + callback {eff->seteffectpar(1,(int) o->value());} + xywh {45 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial distp2 { + label {LRc.} + callback {eff->seteffectpar(2,(int) o->value());} + tooltip {L/R Mix} xywh {80 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 when 4 maximum 127 + class WidgetPDial + } + Fl_Dial distp3 { + label Drive + callback {eff->seteffectpar(3,(int) o->value());} + tooltip {Input Amplification} xywh {120 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 when 4 maximum 127 + class WidgetPDial + } + Fl_Dial distp4 { + label Level + callback {eff->seteffectpar(4,(int) o->value());} + tooltip {Output Amplification} xywh {155 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial distp7 { + label LPF + callback {eff->seteffectpar(7,(int) o->value());} + tooltip {Low Pass Filter} xywh {285 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial distp8 { + label HPF + callback {eff->seteffectpar(8,(int) o->value());} + tooltip {High Pass Filter} xywh {320 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Choice distp5 { + label Type + callback {eff->seteffectpar(5,(int) o->value());} + xywh {190 50 60 20} box UP_BOX down_box BORDER_BOX labelfont 1 labelsize 11 align 2 textsize 10 + } { + MenuItem {} { + label Atan + xywh {55 55 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Asym1 + xywh {65 65 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Pow + xywh {75 75 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Sine + xywh {85 85 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Qnts + xywh {95 95 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Zigzg + xywh {105 105 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Lmt + xywh {115 115 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label LmtU + xywh {125 125 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label LmtL + xywh {135 135 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label ILmt + xywh {147 147 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Clip + xywh {157 157 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Asym2 + xywh {75 75 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Pow2 + xywh {85 85 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Sgm + xywh {95 95 100 20} labelfont 1 labelsize 10 + } + } + Fl_Check_Button distp6 { + label {Neg.} + callback {eff->seteffectpar(6,(int) o->value());} + xywh {260 55 15 15} down_box DOWN_BOX labelfont 1 labelsize 11 align 2 + } + Fl_Check_Button distp9 { + label {St.} + callback {eff->seteffectpar(9,(int) o->value());} + tooltip Stereo xywh {355 60 15 15} down_box DOWN_BOX labelfont 1 labelsize 11 align 2 + } + Fl_Check_Button distp10 { + label PF + callback {eff->seteffectpar(10,(int) o->value());} + tooltip {Applies the filters(before or after) the distorsion} xywh {355 44 15 15} down_box DOWN_BOX labelfont 1 labelsize 11 align 1 + } + } + } + Function {make_eq_window()} {} { + Fl_Window effeqwindow { + xywh {258 307 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide + class Fl_Group + } { + Fl_Text_Display {} { + label EQ + xywh {320 10 15 20} box NO_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 22 align 8 + } + Fl_Dial eqp0 { + label Gain + callback {eff->seteffectpar(0,(int) o->value()); +eqgraph->redraw();} + xywh {10 35 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Counter bandcounter { + label {B.} + callback {eqband=(int) o->value(); +int npb=eqband*5+10; + +int type=eff->geteffectpar(npb); +typechoice->value(type); + +if (type>6) gaindial->activate(); + else gaindial->deactivate(); + +if (type==0) bandgroup->deactivate(); +else bandgroup->activate(); + +int freq=eff->geteffectpar(npb+1); +freqdial->value(freq); + +int gain=eff->geteffectpar(npb+2); +gaindial->value(gain); + +int q=eff->geteffectpar(npb+3); +qdial->value(q); + +int dbl=eff->geteffectpar(npb+4); +stagescounter->value(dbl);} + tooltip {Band no.} xywh {240 20 45 15} type Simple labelfont 1 labelsize 11 align 1 minimum 0 maximum 1 step 1 textfont 1 textsize 11 + code0 {o->bounds(0,MAX_EQ_BANDS-1);} + } + Fl_Group bandgroup { + xywh {245 40 130 50} box ENGRAVED_FRAME + code0 {if (eff->geteffectpar(10)==0) o->deactivate();} + } { + Fl_Dial freqdial { + label Freq + callback {int np=eqband*5+11; +eff->seteffectpar(np,(int) o->value()); +eqgraph->redraw();} + xywh {250 50 25 25} box ROUND_UP_BOX labelfont 1 labelsize 10 when 3 maximum 127 + class WidgetPDial + } + Fl_Dial gaindial { + label Gain + callback {int np=eqband*5+12; +eff->seteffectpar(np,(int) o->value()); +eqgraph->redraw();} + xywh {280 50 25 25} box ROUND_UP_BOX labelfont 1 labelsize 10 when 3 maximum 127 step 1 + class WidgetPDial + } + Fl_Dial qdial { + label Q + callback {int np=eqband*5+13; +eff->seteffectpar(np,(int) o->value()); +eqgraph->redraw();} + tooltip {Resonance/Bandwidth} xywh {310 50 25 25} box ROUND_UP_BOX labelfont 1 labelsize 10 when 3 maximum 127 + class WidgetPDial + } + Fl_Counter stagescounter { + label {St.} + callback {int np=eqband*5+14; +eff->seteffectpar(np,(int) o->value()); +eqgraph->redraw();} + tooltip {Additional filter stages} xywh {340 60 30 15} type Simple labelfont 1 labelsize 10 minimum 1 maximum 127 step 1 textfont 1 textsize 11 + code0 {o->bounds(0,MAX_FILTER_STAGES-1);} + } + } + Fl_Choice typechoice { + label {T.} + callback {int np=eqband*5+10; +eff->seteffectpar(np,(int) o->value()); +bandcounter->do_callback(); +eqgraph->redraw();} + tooltip Type xywh {290 20 40 15} down_box BORDER_BOX labelfont 1 labelsize 10 align 1 when 6 textsize 10 + } { + MenuItem {} { + label OFF + xywh {0 0 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Lp1 + xywh {10 10 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Hp1 + xywh {20 20 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Lp2 + xywh {30 30 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Hp2 + xywh {40 40 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Bp2 + xywh {50 50 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label N2 + xywh {60 60 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Pk + xywh {80 80 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label LSh + xywh {70 70 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label HSh + xywh {80 80 100 20} labelfont 1 labelsize 10 + } + } + Fl_Box eqgraph { + xywh {45 10 190 75} box BORDER_BOX color 178 + code0 {o->init(eff);} + class EQGraph + } + } + } + Function {make_dynamicfilter_window()} {} { + Fl_Window effdynamicfilterwindow { + xywh {570 56 380 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide + class Fl_Group + } { + Fl_Choice dfp { + label Preset + callback {eff->changepreset((int)o->value()); +refresh(eff);} + xywh {10 15 90 15} down_box BORDER_BOX color 14 selection_color 0 labelfont 1 labelsize 10 align 5 textfont 1 textsize 10 textcolor 7 + } { + MenuItem {} { + label WahWah + xywh {30 30 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label AutoWah + xywh {40 40 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label Sweep + xywh {50 50 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label VocalMorph1 + xywh {50 50 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label VocalMorph2 + xywh {60 60 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + } + Fl_Text_Display {} { + label DynFilter + xywh {245 10 10 20} box NO_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 22 align 8 + } + Fl_Dial dfp0 { + label Vol + callback {eff->seteffectpar(0,(int) o->value());} + tooltip {Effect Volume} xywh {10 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial dfp1 { + label Pan + callback {eff->seteffectpar(1,(int) o->value());} + xywh {45 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial dfp2 { + label Freq + callback {eff->seteffectpar(2,(int) o->value());} + tooltip {LFO Frequency} xywh {85 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial dfp3 { + label Rnd + callback {eff->seteffectpar(3,(int) o->value());} + tooltip {LFO Randomness} xywh {120 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 when 4 maximum 127 + class WidgetPDial + } + Fl_Dial dfp5 { + label {St.df} + callback {eff->seteffectpar(5,(int) o->value());} + tooltip {Left/Right Channel Phase Shift} xywh {200 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial dfp6 { + label LfoD + callback {eff->seteffectpar(6,(int) o->value());} + tooltip {LFO Depth} xywh {235 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Choice dfp4 { + label {LFO type} + callback {eff->seteffectpar(4,(int) o->value());} + tooltip {LFO function} xywh {155 50 40 15} down_box BORDER_BOX labelfont 1 labelsize 10 align 130 textsize 8 + } { + MenuItem {} { + label SINE + xywh {15 15 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label TRI + xywh {25 25 100 20} labelfont 1 labelsize 10 + } + } + Fl_Button {} { + label Filter + callback {filterwindow->show();} + xywh {115 10 55 25} box PLASTIC_THIN_UP_BOX + } + Fl_Group {} { + xywh {270 40 105 45} box BORDER_BOX color 181 + } { + Fl_Dial dfp7 { + label {A.S.} + callback {eff->seteffectpar(7,(int) o->value());} + tooltip {Filter vs Amplitude} xywh {275 45 25 25} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial dfp9 { + label {A.M} + callback {eff->seteffectpar(9,(int) o->value());} + tooltip {rate that amplitude changes the filter} xywh {305 45 25 25} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Check_Button dfp8 { + label {A.Inv.} + callback {eff->seteffectpar(8,(int) o->value());} + tooltip {enable for filter frequency to lower with higher input amplitude} xywh {345 55 15 15} down_box DOWN_BOX labelfont 1 labelsize 11 align 2 + } + } + } + } + Function {make_filter_window()} {} { + Fl_Window filterwindow { + label {Filter Parameters for DynFilter Eff.} + xywh {212 170 290 110} type Double hide + } { + Fl_Group {} { + label {DynFilter effect - Filter} + xywh {5 5 275 75} box FLAT_BOX color 50 align 144 + code0 {o->init(eff->filterpars,NULL,NULL);} + code1 {o->use_for_dynamic_filter();} + class FilterUI + } {} + Fl_Button {} { + label Close + callback {filterwindow->hide();} + xywh {105 85 70 20} box THIN_UP_BOX + } + } + } + Function {init(EffectMgr *eff_)} {} { + code {eff=eff_; + +make_null_window(); +make_reverb_window(); +make_echo_window(); +make_chorus_window(); +make_phaser_window(); +make_alienwah_window(); +make_distorsion_window(); +make_eq_window(); +make_dynamicfilter_window(); + +int px=this->parent()->x(); +int py=this->parent()->y(); + +effnullwindow->position(px,py); +effreverbwindow->position(px,py); +effechowindow->position(px,py); +effchoruswindow->position(px,py); +effphaserwindow->position(px,py); +effalienwahwindow->position(px,py); +effdistorsionwindow->position(px,py); +effeqwindow->position(px,py); +effdynamicfilterwindow->position(px,py); + +refresh(eff);} {} + } + Function {refresh(EffectMgr *eff_)} {} { + code {eff=eff_; +this->hide(); + +effnullwindow->hide(); +effreverbwindow->hide(); +effechowindow->hide(); +effchoruswindow->hide(); +effphaserwindow->hide(); +effalienwahwindow->hide(); +effdistorsionwindow->hide(); +effeqwindow->hide(); +effdynamicfilterwindow->hide(); + +eqband=0; + +if (filterwindow!=NULL){ + filterwindow->hide(); + delete(filterwindow); + filterwindow=NULL; +}; + +switch(eff->geteffect()){ + case 1: + revp->value(eff->getpreset()); + revp0->value(eff->geteffectpar(0));if (eff->insertion!=0) revp0->label("D/W"); + revp1->value(eff->geteffectpar(1)); + revp2->value(eff->geteffectpar(2)); + revp3->value(eff->geteffectpar(3)); + revp4->value(eff->geteffectpar(4)); + revp5->value(eff->geteffectpar(5)); + revp6->value(eff->geteffectpar(6)); + revp7->value(eff->geteffectpar(7)); + revp8->value(eff->geteffectpar(8)); + revp9->value(eff->geteffectpar(9)); + revp10->value(eff->geteffectpar(10)); + revp11->value(eff->geteffectpar(11)); + + effreverbwindow->show(); + break; + case 2: + echop->value(eff->getpreset()); + echop0->value(eff->geteffectpar(0));if (eff->insertion!=0) echop0->label("D/W"); + echop1->value(eff->geteffectpar(1)); + echop2->value(eff->geteffectpar(2)); + echop3->value(eff->geteffectpar(3)); + echop4->value(eff->geteffectpar(4)); + echop5->value(eff->geteffectpar(5)); + echop6->value(eff->geteffectpar(6)); + effechowindow->show(); + break; + case 3: + chorusp->value(eff->getpreset()); + chorusp0->value(eff->geteffectpar(0));if (eff->insertion!=0) chorusp0->label("D/W"); + chorusp1->value(eff->geteffectpar(1)); + chorusp2->value(eff->geteffectpar(2)); + chorusp3->value(eff->geteffectpar(3)); + chorusp4->value(eff->geteffectpar(4)); + chorusp5->value(eff->geteffectpar(5)); + chorusp6->value(eff->geteffectpar(6)); + chorusp7->value(eff->geteffectpar(7)); + chorusp8->value(eff->geteffectpar(8)); + chorusp9->value(eff->geteffectpar(9)); + chorusp11->value(eff->geteffectpar(11)); + effchoruswindow->show(); + break; + case 4: + phaserp->value(eff->getpreset()); + phaserp0->value(eff->geteffectpar(0));if (eff->insertion!=0) phaserp0->label("D/W"); + phaserp1->value(eff->geteffectpar(1)); + phaserp2->value(eff->geteffectpar(2)); + phaserp3->value(eff->geteffectpar(3)); + phaserp4->value(eff->geteffectpar(4)); + phaserp5->value(eff->geteffectpar(5)); + phaserp6->value(eff->geteffectpar(6)); + phaserp7->value(eff->geteffectpar(7)); + phaserp8->value(eff->geteffectpar(8)); + phaserp9->value(eff->geteffectpar(9)); + phaserp10->value(eff->geteffectpar(10)); + phaserp11->value(eff->geteffectpar(11)); + effphaserwindow->show(); + break; + case 5: + awp->value(eff->getpreset()); + awp0->value(eff->geteffectpar(0));if (eff->insertion!=0) awp0->label("D/W"); + awp1->value(eff->geteffectpar(1)); + awp2->value(eff->geteffectpar(2)); + awp3->value(eff->geteffectpar(3)); + awp4->value(eff->geteffectpar(4)); + awp5->value(eff->geteffectpar(5)); + awp6->value(eff->geteffectpar(6)); + awp7->value(eff->geteffectpar(7)); + awp8->value(eff->geteffectpar(8)); + awp9->value(eff->geteffectpar(9)); + awp10->value(eff->geteffectpar(10)); + + effalienwahwindow->show(); + break; + case 6: + distp->value(eff->getpreset()); + distp0->value(eff->geteffectpar(0));if (eff->insertion!=0) distp0->label("D/W"); + distp1->value(eff->geteffectpar(1)); + distp2->value(eff->geteffectpar(2)); + distp3->value(eff->geteffectpar(3)); + distp4->value(eff->geteffectpar(4)); + distp5->value(eff->geteffectpar(5)); + distp6->value(eff->geteffectpar(6)); + distp7->value(eff->geteffectpar(7)); + distp8->value(eff->geteffectpar(8)); + distp9->value(eff->geteffectpar(9)); + distp10->value(eff->geteffectpar(10)); + effdistorsionwindow->show(); + break; + case 7:eqband=0; + eqp0->value(eff->geteffectpar(0)); + bandcounter->value(eqband); + bandcounter->do_callback(); + typechoice->value(eff->geteffectpar(10)); + eqgraph->redraw(); + freqdial->value(eff->geteffectpar(11)); + gaindial->value(eff->geteffectpar(12)); + if (eff->geteffectpar(10)<6) gaindial->deactivate(); + qdial->value(eff->geteffectpar(13)); + stagescounter->value(eff->geteffectpar(14)); + eqgraph->init(eff); + effeqwindow->show(); + break; + case 8:make_filter_window(); + dfp->value(eff->getpreset()); + dfp0->value(eff->geteffectpar(0));if (eff->insertion!=0) dfp0->label("D/W"); + dfp1->value(eff->geteffectpar(1)); + dfp2->value(eff->geteffectpar(2)); + dfp3->value(eff->geteffectpar(3)); + dfp4->value(eff->geteffectpar(4)); + dfp5->value(eff->geteffectpar(5)); + dfp6->value(eff->geteffectpar(6)); + dfp7->value(eff->geteffectpar(7)); + dfp8->value(eff->geteffectpar(8)); + dfp9->value(eff->geteffectpar(9)); + + + effdynamicfilterwindow->show(); + break; + default:effnullwindow->show(); + break; +}; + +this->show();} {} + } + Function {refresh()} {} { + code {refresh(eff);} {} + } + decl {EffectMgr *eff;} {} + decl {int eqband;} {} +} + +class SimpleEffUI {: {public Fl_Group,public PresetsUI_} +} { + Function {SimpleEffUI(int x,int y, int w, int h, const char *label=0):Fl_Group(x,y,w,h,label)} {} { + code {eff=NULL;} {} + } + Function {~SimpleEffUI()} {} { + code {effnullwindow->hide();//delete (effnullwindow); +effreverbwindow->hide();//delete (effreverbwindow); +effechowindow->hide();//delete (effechowindow); +effchoruswindow->hide();//delete (effchoruswindow); +effphaserwindow->hide();//delete (effphaserwindow); +effalienwahwindow->hide();//delete (effalienwahwindow); +effdistorsionwindow->hide();//delete (effdistorsionwindow); +effeqwindow->hide();//delete (effeqwindow); +effdynamicfilterwindow->hide();//delete (effdynamicfilterwindow);} {} + } + Function {make_null_window()} {} { + Fl_Window effnullwindow { + xywh {539 150 230 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide + class Fl_Group + } { + Fl_Text_Display {} { + label {No Effect} + xywh {25 35 35 20} box NO_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 22 labelcolor 43 align 8 + } + } + } + Function {make_reverb_window()} {} { + Fl_Window effreverbwindow { + xywh {398 298 230 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide + class Fl_Group + } { + Fl_Text_Display {} { + label {Reverb } + xywh {115 10 20 20} box NO_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 22 align 8 + } + Fl_Choice revp { + label Preset + callback {eff->changepreset((int)o->value()); + +refresh(eff);} + xywh {10 15 90 15} down_box BORDER_BOX color 14 selection_color 0 labelfont 1 labelsize 10 align 5 textfont 1 textsize 10 textcolor 7 + } { + MenuItem {} { + label {Cathedral 1} + xywh {10 10 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Cathedral 2} + xywh {20 20 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Cathedral 3} + xywh {30 30 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Hall 1} + xywh {40 40 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Hall 2} + xywh {50 50 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Room 1} + xywh {60 60 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Room 2} + xywh {70 70 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label Basement + xywh {80 80 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label Tunnel + xywh {90 90 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Echoed 1} + xywh {100 100 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Echoed 2} + xywh {110 110 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Very Long 1} + xywh {120 120 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Very Long 2} + xywh {130 130 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + } + Fl_Dial revp0 { + label Vol + callback {eff->seteffectpar(0,(int) o->value());} + tooltip {Effect Volume} xywh {10 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial revp2 { + label Time + callback {eff->seteffectpar(2,(int) o->value());} + tooltip {Duration of Reverb} xywh {45 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial revp3 { + label {I.del} + callback {eff->seteffectpar(3,(int) o->value());} + tooltip {Initial Delay} xywh {85 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 when 4 maximum 127 + class WidgetPDial + } + Fl_Dial revp9 { + label Damp + callback {eff->seteffectpar(9,(int) o->value());} + tooltip Dampening xywh {120 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 minimum 64 maximum 127 step 1 + class WidgetPDial + } + } + } + Function {make_echo_window()} {} { + Fl_Window effechowindow { + xywh {243 350 230 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide + class Fl_Group + } { + Fl_Choice echop { + label Preset + callback {eff->changepreset((int)o->value()); +refresh(eff);} + xywh {11 15 95 15} down_box BORDER_BOX color 14 selection_color 0 labelfont 1 labelsize 10 align 5 textfont 1 textsize 10 textcolor 7 + } { + MenuItem {} { + label {Echo 1} + xywh {20 20 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Echo 2} + xywh {30 30 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Echo 3} + xywh {40 40 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Simple Echo} + xywh {50 50 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label Canyon + xywh {60 60 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Panning Echo 1} + xywh {70 70 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Panning Echo 2} + xywh {80 80 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Panning Echo 3} + xywh {90 90 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Feedback Echo} + xywh {100 100 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + } + Fl_Text_Display {} { + label Echo + xywh {145 10 10 20} box NO_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 22 align 8 + } + Fl_Dial echop0 { + label Vol + callback {eff->seteffectpar(0,(int) o->value());} + tooltip {Effect Volume} xywh {10 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial echop2 { + label Delay + callback {eff->seteffectpar(2,(int) o->value());} + xywh {45 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 when 4 maximum 127 + class WidgetPDial + } + Fl_Dial echop5 { + label {Fb.} + callback {eff->seteffectpar(5,(int) o->value());} + tooltip Feedback xywh {80 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + } + } + Function {make_chorus_window()} {} { + Fl_Window effchoruswindow { + xywh {234 353 230 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide + class Fl_Group + } { + Fl_Choice chorusp { + label Preset + callback {eff->changepreset((int)o->value()); +refresh(eff);} + xywh {10 15 90 15} down_box BORDER_BOX color 14 selection_color 0 labelfont 1 labelsize 10 align 5 textfont 1 textsize 10 textcolor 7 + } { + MenuItem {} { + label {Chorus 1} + xywh {20 20 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Chorus 2} + xywh {30 30 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Chorus 3} + xywh {40 40 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Celeste 1} + xywh {50 50 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Celeste 2} + xywh {60 60 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Flange 1} + xywh {70 70 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Flange 2} + xywh {80 80 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Flange 3} + xywh {90 90 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Flange 4} + xywh {100 100 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Flange 5} + xywh {110 110 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + } + Fl_Text_Display {} { + label Chorus + xywh {120 10 10 20} box NO_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 22 align 8 + } + Fl_Dial chorusp0 { + label Vol + callback {eff->seteffectpar(0,(int) o->value());} + tooltip {Effect Volume} xywh {10 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial chorusp2 { + label Freq + callback {eff->seteffectpar(2,(int) o->value());} + tooltip {LFO Frequency} xywh {45 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial chorusp6 { + label Dpth + callback {eff->seteffectpar(6,(int) o->value());} + tooltip Depth xywh {80 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial chorusp7 { + label Delay + callback {eff->seteffectpar(7,(int) o->value());} + xywh {115 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial chorusp8 { + label Fb + callback {eff->seteffectpar(8,(int) o->value());} + tooltip Feedback xywh {150 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Check_Button {} { + label Flange + callback {eff->seteffectpar(10,(int) o->value());} + xywh {120 10 55 20} box THIN_UP_BOX down_box DOWN_BOX color 230 labelfont 1 labelsize 10 hide deactivate + code0 {o->value(eff->geteffectpar(10));} + } + } + } + Function {make_phaser_window()} {} { + Fl_Window effphaserwindow { + xywh {661 430 230 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide + class Fl_Group + } { + Fl_Choice phaserp { + label Preset + callback {eff->changepreset((int)o->value()); +refresh(eff);} + xywh {10 15 90 15} down_box BORDER_BOX color 14 selection_color 0 labelfont 1 labelsize 10 align 5 textfont 1 textsize 10 textcolor 7 + } { + MenuItem {} { + label {Phaser 1} + xywh {30 30 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Phaser 2} + xywh {40 40 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Phaser 3} + xywh {50 50 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Phaser 4} + xywh {60 60 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Phaser 5} + xywh {70 70 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Phaser 6} + xywh {80 80 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + } + Fl_Text_Display {} { + label Phaser + xywh {125 10 10 20} box NO_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 22 align 8 + } + Fl_Dial phaserp0 { + label Vol + callback {eff->seteffectpar(0,(int) o->value());} + tooltip {Effect Volume} xywh {10 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial phaserp2 { + label Freq + callback {eff->seteffectpar(2,(int) o->value());} + tooltip {LFO frequency} xywh {45 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial phaserp5 { + label {St.df} + callback {eff->seteffectpar(5,(int) o->value());} + tooltip {Left/Right Channel Phase Shift} xywh {80 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial phaserp6 { + label Dpth + callback {eff->seteffectpar(6,(int) o->value());} + tooltip Depth xywh {115 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial phaserp7 { + label Fb + callback {eff->seteffectpar(7,(int) o->value());} + tooltip Feedback xywh {150 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Counter phaserp8 { + label Stages + callback {eff->seteffectpar(8,(int) o->value());} + xywh {185 55 35 15} type Simple labelfont 1 labelsize 11 minimum 0 maximum 127 step 1 + code0 {o->range(1,MAX_PHASER_STAGES);} + } + } + } + Function {make_alienwah_window()} {} { + Fl_Window effalienwahwindow { + xywh {367 170 230 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide + class Fl_Group + } { + Fl_Choice awp { + label Preset + callback {eff->changepreset((int)o->value()); +refresh(eff);} + xywh {10 15 90 15} down_box BORDER_BOX color 14 selection_color 0 labelfont 1 labelsize 10 align 5 textfont 1 textsize 10 textcolor 7 + } { + MenuItem {} { + label {Alienwah 1} + xywh {40 40 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Alienwah 2} + xywh {50 50 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Alienwah 3} + xywh {60 60 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Alienwah 4} + xywh {70 70 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + } + Fl_Text_Display {} { + label AlienWah + xywh {100 10 10 20} box NO_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 22 align 8 + } + Fl_Dial awp0 { + label Vol + callback {eff->seteffectpar(0,(int) o->value());} + tooltip {Effect Volume} xywh {10 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial awp2 { + label Freq + callback {eff->seteffectpar(2,(int) o->value());} + tooltip {LFO frequency} xywh {45 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial awp6 { + label Dpth + callback {eff->seteffectpar(6,(int) o->value());} + tooltip Depth xywh {85 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Counter awp8 { + label Delay + callback {eff->seteffectpar(8,(int) o->value());} + xywh {125 55 35 15} type Simple labelfont 1 labelsize 11 minimum 0 maximum 127 step 1 + code0 {o->range(1,MAX_ALIENWAH_DELAY);} + } + } + } + Function {make_distorsion_window()} {} { + Fl_Window effdistorsionwindow { + xywh {353 412 230 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide + class Fl_Group + } { + Fl_Choice distp { + label Preset + callback {eff->changepreset((int)o->value()); +refresh(eff);} + xywh {11 15 95 15} down_box BORDER_BOX color 14 selection_color 0 labelfont 1 labelsize 10 align 5 textfont 1 textsize 10 textcolor 7 + } { + MenuItem {} { + label {Overdrive 1} + xywh {20 20 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Overdrive 2} + xywh {30 30 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {A. Exciter 1} + xywh {40 40 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {A. Exciter 2} + xywh {50 50 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label {Guitar Amp} + xywh {50 50 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label Quantisize + xywh {60 60 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + } + Fl_Text_Display {} { + label Distortion + xywh {110 10 10 20} box NO_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 16 align 8 + } + Fl_Dial distp0 { + label Vol + callback {eff->seteffectpar(0,(int) o->value());} + tooltip {Effect Volume} xywh {10 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial distp3 { + label Drive + callback {eff->seteffectpar(3,(int) o->value());} + tooltip {Input amplification} xywh {45 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 when 4 maximum 127 + class WidgetPDial + } + Fl_Dial distp4 { + label Level + callback {eff->seteffectpar(4,(int) o->value());} + tooltip {Output Amplification} xywh {80 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial distp7 { + label LPF + callback {eff->seteffectpar(7,(int) o->value());} + tooltip {Low Pass Filter} xywh {190 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Choice distp5 { + label Type + callback {eff->seteffectpar(5,(int) o->value());} + xywh {120 50 60 20} box UP_BOX down_box BORDER_BOX labelfont 1 labelsize 11 align 2 textsize 10 + } { + MenuItem {} { + label Atan + xywh {55 55 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Asym1 + xywh {65 65 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Pow + xywh {75 75 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Sine + xywh {85 85 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Qnts + xywh {95 95 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Zigzg + xywh {105 105 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Lmt + xywh {115 115 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label LmtU + xywh {125 125 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label LmtL + xywh {135 135 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label ILmt + xywh {147 147 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Clip + xywh {157 157 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Asym2 + xywh {75 75 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Pow2 + xywh {85 85 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Sgm + xywh {95 95 100 20} labelfont 1 labelsize 10 + } + } + } + } + Function {make_eq_window()} {} { + Fl_Window effeqwindow { + xywh {318 309 230 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide + class Fl_Group + } { + Fl_Text_Display {} { + label EQ + xywh {170 5 15 25} box NO_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 22 align 8 + } + Fl_Counter bandcounter { + label Band + callback {eqband=(int) o->value(); +int npb=eqband*5+10; + +int type=eff->geteffectpar(npb); +typechoice->value(type); + +if (type>6) gaindial->activate(); + else gaindial->deactivate(); + +if (type==0) bandgroup->deactivate(); +else bandgroup->activate(); + +int freq=eff->geteffectpar(npb+1); +freqdial->value(freq); + +int gain=eff->geteffectpar(npb+2); +gaindial->value(gain); + +int q=eff->geteffectpar(npb+3); +qdial->value(q); + +int dbl=eff->geteffectpar(npb+4); +stagescounter->value(dbl);} + tooltip {Band no.} xywh {85 15 45 15} type Simple labelfont 1 labelsize 11 align 1 minimum 0 maximum 1 step 1 textfont 1 textsize 11 + code0 {o->bounds(0,MAX_EQ_BANDS-1);} + } + Fl_Group bandgroup { + xywh {5 5 75 85} box ENGRAVED_FRAME + code0 {if (eff->geteffectpar(10)==0) o->deactivate();} + } { + Fl_Dial freqdial { + label Freq + callback {int np=eqband*5+11; +eff->seteffectpar(np,(int) o->value()); +eqgraph->redraw();} + xywh {10 10 25 25} box ROUND_UP_BOX labelfont 1 labelsize 10 when 3 maximum 127 + class WidgetPDial + } + Fl_Dial gaindial { + label Gain + callback {int np=eqband*5+12; +eff->seteffectpar(np,(int) o->value()); +eqgraph->redraw();} + xywh {45 10 25 25} box ROUND_UP_BOX labelfont 1 labelsize 10 when 3 maximum 127 step 1 + class WidgetPDial + } + Fl_Dial qdial { + label Q + callback {int np=eqband*5+13; +eff->seteffectpar(np,(int) o->value()); +eqgraph->redraw();} + tooltip {Bandwidth/Resonance} xywh {10 50 25 25} box ROUND_UP_BOX labelfont 1 labelsize 10 when 3 maximum 127 + class WidgetPDial + } + Fl_Counter stagescounter { + label Stages + callback {int np=eqband*5+14; +eff->seteffectpar(np,(int) o->value()); +eqgraph->redraw();} + tooltip {Additional filter stages} xywh {40 55 30 15} type Simple labelfont 1 labelsize 10 minimum 1 maximum 127 step 1 textfont 1 textsize 11 + code0 {o->bounds(0,MAX_FILTER_STAGES-1);} + } + } + Fl_Choice typechoice { + label Type + callback {int np=eqband*5+10; +eff->seteffectpar(np,(int) o->value()); +bandcounter->do_callback(); +eqgraph->redraw();} + tooltip Type xywh {135 15 40 15} down_box BORDER_BOX labelfont 1 labelsize 10 align 1 when 6 textsize 10 + } { + MenuItem {} { + label OFF + xywh {10 10 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Lp1 + xywh {20 20 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Hp1 + xywh {30 30 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Lp2 + xywh {40 40 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Hp2 + xywh {50 50 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Bp2 + xywh {60 60 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label N2 + xywh {70 70 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Pk + xywh {90 90 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label LSh + xywh {80 80 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label HSh + xywh {90 90 100 20} labelfont 1 labelsize 10 + } + } + Fl_Box eqgraph { + xywh {85 35 140 55} box BORDER_BOX color 178 + code0 {o->init(eff);} + class EQGraph + } + } + } + Function {make_dynamicfilter_window()} {} { + Fl_Window effdynamicfilterwindow { + xywh {475 471 230 95} type Double box PLASTIC_UP_BOX color 221 labelfont 1 hide + class Fl_Group + } { + Fl_Choice dfp { + label Preset + callback {eff->changepreset((int)o->value()); +refresh(eff);} + xywh {10 15 90 15} down_box BORDER_BOX color 14 selection_color 0 labelfont 1 labelsize 10 align 5 textfont 1 textsize 10 textcolor 7 + } { + MenuItem {} { + label WahWah + xywh {30 30 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label AutoWah + xywh {40 40 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label Sweep + xywh {50 50 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label VocalMorph1 + xywh {50 50 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + MenuItem {} { + label VocalMorph2 + xywh {60 60 100 20} labelfont 1 labelsize 10 labelcolor 7 + } + } + Fl_Text_Display {} { + label DynFilter + xywh {100 10 10 20} box NO_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 22 align 8 + } + Fl_Dial dfp0 { + label Vol + callback {eff->seteffectpar(0,(int) o->value());} + tooltip {Effect Volume} xywh {10 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial dfp2 { + label Freq + callback {eff->seteffectpar(2,(int) o->value());} + tooltip {LFO frequency} xywh {45 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial dfp6 { + label LfoD + callback {eff->seteffectpar(6,(int) o->value());} + tooltip {LFO depth} xywh {80 40 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Group {} { + xywh {115 40 65 45} box BORDER_BOX color 181 + } { + Fl_Dial dfp7 { + label {A.S.} + callback {eff->seteffectpar(7,(int) o->value());} + tooltip {how filter varies with amplitude} xywh {120 45 25 25} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + Fl_Dial dfp9 { + label {A.M} + callback {eff->seteffectpar(9,(int) o->value());} + tooltip {how quickly the filter varies with amplitude} xywh {150 45 25 25} box ROUND_UP_BOX labelfont 1 labelsize 11 maximum 127 + class WidgetPDial + } + } + } + } + Function {init(EffectMgr *eff_)} {} { + code {eff=eff_; + +make_null_window(); +make_reverb_window(); +make_echo_window(); +make_chorus_window(); +make_phaser_window(); +make_alienwah_window(); +make_distorsion_window(); +make_eq_window(); +make_dynamicfilter_window(); + +int px=this->parent()->x(); +int py=this->parent()->y(); + +effnullwindow->position(px,py); +effreverbwindow->position(px,py); +effechowindow->position(px,py); +effchoruswindow->position(px,py); +effphaserwindow->position(px,py); +effalienwahwindow->position(px,py); +effdistorsionwindow->position(px,py); +effeqwindow->position(px,py); +effdynamicfilterwindow->position(px,py); + +refresh(eff);} {} + } + Function {refresh(EffectMgr *eff_)} {} { + code {eff=eff_; +this->hide(); + +effnullwindow->hide(); +effreverbwindow->hide(); +effechowindow->hide(); +effchoruswindow->hide(); +effphaserwindow->hide(); +effalienwahwindow->hide(); +effdistorsionwindow->hide(); +effeqwindow->hide(); +effdynamicfilterwindow->hide(); + +eqband=0; + + +switch(eff->geteffect()){ + case 1: + revp->value(eff->getpreset()); + revp0->value(eff->geteffectpar(0));if (eff->insertion!=0) revp0->label("D/W"); + revp2->value(eff->geteffectpar(2)); + revp3->value(eff->geteffectpar(3)); + revp9->value(eff->geteffectpar(9)); + effreverbwindow->show(); + break; + case 2: + echop->value(eff->getpreset()); + echop0->value(eff->geteffectpar(0));if (eff->insertion!=0) echop0->label("D/W"); + echop2->value(eff->geteffectpar(2)); + echop5->value(eff->geteffectpar(5)); + effechowindow->show(); + break; + case 3: + chorusp->value(eff->getpreset()); + chorusp0->value(eff->geteffectpar(0));if (eff->insertion!=0) chorusp0->label("D/W"); + chorusp2->value(eff->geteffectpar(2)); + chorusp6->value(eff->geteffectpar(6)); + chorusp7->value(eff->geteffectpar(7)); + chorusp8->value(eff->geteffectpar(8)); + effchoruswindow->show(); + break; + case 4: + phaserp->value(eff->getpreset()); + phaserp0->value(eff->geteffectpar(0));if (eff->insertion!=0) phaserp0->label("D/W"); + phaserp2->value(eff->geteffectpar(2)); + phaserp5->value(eff->geteffectpar(5)); + phaserp6->value(eff->geteffectpar(6)); + phaserp7->value(eff->geteffectpar(7)); + phaserp8->value(eff->geteffectpar(8)); + effphaserwindow->show(); + break; + case 5: + awp->value(eff->getpreset()); + awp0->value(eff->geteffectpar(0));if (eff->insertion!=0) awp0->label("D/W"); + awp2->value(eff->geteffectpar(2)); + awp6->value(eff->geteffectpar(6)); + awp8->value(eff->geteffectpar(8)); + effalienwahwindow->show(); + break; + case 6: + distp->value(eff->getpreset()); + distp0->value(eff->geteffectpar(0));if (eff->insertion!=0) distp0->label("D/W"); + distp3->value(eff->geteffectpar(3)); + distp4->value(eff->geteffectpar(4)); + distp5->value(eff->geteffectpar(5)); + distp7->value(eff->geteffectpar(7)); + effdistorsionwindow->show(); + break; + case 7: + bandcounter->value(eqband); + bandcounter->do_callback(); + typechoice->value(eff->geteffectpar(10)); + eqgraph->redraw(); + freqdial->value(eff->geteffectpar(11)); + gaindial->value(eff->geteffectpar(12)); + if (eff->geteffectpar(10)<6) gaindial->deactivate(); + qdial->value(eff->geteffectpar(13)); + stagescounter->value(eff->geteffectpar(14)); + eqgraph->init(eff); + effeqwindow->show(); + break; + case 8: + dfp->value(eff->getpreset()); + dfp0->value(eff->geteffectpar(0));if (eff->insertion!=0) dfp0->label("D/W"); + dfp2->value(eff->geteffectpar(2)); + dfp6->value(eff->geteffectpar(6)); + dfp7->value(eff->geteffectpar(7)); + dfp9->value(eff->geteffectpar(9)); + + + effdynamicfilterwindow->show(); + break; + default:effnullwindow->show(); + break; +}; + +this->show();} {} + } + Function {refresh()} {} { + code {refresh(eff);} {} + } + decl {EffectMgr *eff;} {} + decl {int eqband;} {} +} diff --git a/plugins/zynaddsubfx/src/UI/EffUI.h b/plugins/zynaddsubfx/src/UI/EffUI.h new file mode 100644 index 000000000..3f6edfb55 --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/EffUI.h @@ -0,0 +1,805 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0109 + +#ifndef EffUI_h +#define EffUI_h +#include +#include +#include +#include +#include "../globals.h" +#include "WidgetPDial.h" +#include "EnvelopeUI.h" +#include "FilterUI.h" +#include "../Misc/Util.h" +#include "../Effects/EffectMgr.h" +#include "PresetsUI.h" + +class EQGraph : public Fl_Box { +public: + EQGraph(int x,int y, int w, int h, const char *label=0); + void init(EffectMgr *eff_); + void draw_freq_line(REALTYPE freq,int type); + void draw(); + int getresponse(int maxy,REALTYPE freq); + REALTYPE getfreqx(REALTYPE x); + REALTYPE getfreqpos(REALTYPE freq); +private: + int oldx,oldy; +public: + REALTYPE khzval; +private: + EffectMgr *eff; + int maxdB; +}; +#include +#include +#include +#include +#include +#include +#include + +class EffUI : public Fl_Group,public PresetsUI_ { +public: + EffUI(int x,int y, int w, int h, const char *label=0); + ~EffUI(); + Fl_Group* make_null_window(); + Fl_Group *effnullwindow; + Fl_Group* make_reverb_window(); + Fl_Group *effreverbwindow; + Fl_Choice *revp; +private: + void cb_revp_i(Fl_Choice*, void*); + static void cb_revp(Fl_Choice*, void*); + static Fl_Menu_Item menu_revp[]; +public: + Fl_Choice *revp10; +private: + void cb_revp10_i(Fl_Choice*, void*); + static void cb_revp10(Fl_Choice*, void*); + static Fl_Menu_Item menu_revp10[]; +public: + WidgetPDial *revp0; +private: + void cb_revp0_i(WidgetPDial*, void*); + static void cb_revp0(WidgetPDial*, void*); +public: + WidgetPDial *revp1; +private: + void cb_revp1_i(WidgetPDial*, void*); + static void cb_revp1(WidgetPDial*, void*); +public: + WidgetPDial *revp2; +private: + void cb_revp2_i(WidgetPDial*, void*); + static void cb_revp2(WidgetPDial*, void*); +public: + WidgetPDial *revp3; +private: + void cb_revp3_i(WidgetPDial*, void*); + static void cb_revp3(WidgetPDial*, void*); +public: + WidgetPDial *revp4; +private: + void cb_revp4_i(WidgetPDial*, void*); + static void cb_revp4(WidgetPDial*, void*); +public: + WidgetPDial *revp5; +private: + void cb_revp5_i(WidgetPDial*, void*); + static void cb_revp5(WidgetPDial*, void*); +public: + WidgetPDial *revp6; +private: + void cb_revp6_i(WidgetPDial*, void*); + static void cb_revp6(WidgetPDial*, void*); +public: + WidgetPDial *revp7; +private: + void cb_revp7_i(WidgetPDial*, void*); + static void cb_revp7(WidgetPDial*, void*); +public: + WidgetPDial *revp8; +private: + void cb_revp8_i(WidgetPDial*, void*); + static void cb_revp8(WidgetPDial*, void*); +public: + WidgetPDial *revp9; +private: + void cb_revp9_i(WidgetPDial*, void*); + static void cb_revp9(WidgetPDial*, void*); +public: + WidgetPDial *revp11; +private: + void cb_revp11_i(WidgetPDial*, void*); + static void cb_revp11(WidgetPDial*, void*); +public: + Fl_Group* make_echo_window(); + Fl_Group *effechowindow; + Fl_Choice *echop; +private: + void cb_echop_i(Fl_Choice*, void*); + static void cb_echop(Fl_Choice*, void*); + static Fl_Menu_Item menu_echop[]; +public: + WidgetPDial *echop0; +private: + void cb_echop0_i(WidgetPDial*, void*); + static void cb_echop0(WidgetPDial*, void*); +public: + WidgetPDial *echop1; +private: + void cb_echop1_i(WidgetPDial*, void*); + static void cb_echop1(WidgetPDial*, void*); +public: + WidgetPDial *echop2; +private: + void cb_echop2_i(WidgetPDial*, void*); + static void cb_echop2(WidgetPDial*, void*); +public: + WidgetPDial *echop3; +private: + void cb_echop3_i(WidgetPDial*, void*); + static void cb_echop3(WidgetPDial*, void*); +public: + WidgetPDial *echop4; +private: + void cb_echop4_i(WidgetPDial*, void*); + static void cb_echop4(WidgetPDial*, void*); +public: + WidgetPDial *echop5; +private: + void cb_echop5_i(WidgetPDial*, void*); + static void cb_echop5(WidgetPDial*, void*); +public: + WidgetPDial *echop6; +private: + void cb_echop6_i(WidgetPDial*, void*); + static void cb_echop6(WidgetPDial*, void*); +public: + Fl_Group* make_chorus_window(); + Fl_Group *effchoruswindow; + Fl_Choice *chorusp; +private: + void cb_chorusp_i(Fl_Choice*, void*); + static void cb_chorusp(Fl_Choice*, void*); + static Fl_Menu_Item menu_chorusp[]; +public: + WidgetPDial *chorusp0; +private: + void cb_chorusp0_i(WidgetPDial*, void*); + static void cb_chorusp0(WidgetPDial*, void*); +public: + WidgetPDial *chorusp1; +private: + void cb_chorusp1_i(WidgetPDial*, void*); + static void cb_chorusp1(WidgetPDial*, void*); +public: + WidgetPDial *chorusp2; +private: + void cb_chorusp2_i(WidgetPDial*, void*); + static void cb_chorusp2(WidgetPDial*, void*); +public: + WidgetPDial *chorusp3; +private: + void cb_chorusp3_i(WidgetPDial*, void*); + static void cb_chorusp3(WidgetPDial*, void*); +public: + WidgetPDial *chorusp5; +private: + void cb_chorusp5_i(WidgetPDial*, void*); + static void cb_chorusp5(WidgetPDial*, void*); +public: + WidgetPDial *chorusp6; +private: + void cb_chorusp6_i(WidgetPDial*, void*); + static void cb_chorusp6(WidgetPDial*, void*); +public: + WidgetPDial *chorusp7; +private: + void cb_chorusp7_i(WidgetPDial*, void*); + static void cb_chorusp7(WidgetPDial*, void*); +public: + WidgetPDial *chorusp8; +private: + void cb_chorusp8_i(WidgetPDial*, void*); + static void cb_chorusp8(WidgetPDial*, void*); +public: + WidgetPDial *chorusp9; +private: + void cb_chorusp9_i(WidgetPDial*, void*); + static void cb_chorusp9(WidgetPDial*, void*); + void cb_Flange_i(Fl_Check_Button*, void*); + static void cb_Flange(Fl_Check_Button*, void*); +public: + Fl_Check_Button *chorusp11; +private: + void cb_chorusp11_i(Fl_Check_Button*, void*); + static void cb_chorusp11(Fl_Check_Button*, void*); +public: + Fl_Choice *chorusp4; +private: + void cb_chorusp4_i(Fl_Choice*, void*); + static void cb_chorusp4(Fl_Choice*, void*); + static Fl_Menu_Item menu_chorusp4[]; +public: + Fl_Group* make_phaser_window(); + Fl_Group *effphaserwindow; + Fl_Choice *phaserp; +private: + void cb_phaserp_i(Fl_Choice*, void*); + static void cb_phaserp(Fl_Choice*, void*); + static Fl_Menu_Item menu_phaserp[]; +public: + WidgetPDial *phaserp0; +private: + void cb_phaserp0_i(WidgetPDial*, void*); + static void cb_phaserp0(WidgetPDial*, void*); +public: + WidgetPDial *phaserp1; +private: + void cb_phaserp1_i(WidgetPDial*, void*); + static void cb_phaserp1(WidgetPDial*, void*); +public: + WidgetPDial *phaserp2; +private: + void cb_phaserp2_i(WidgetPDial*, void*); + static void cb_phaserp2(WidgetPDial*, void*); +public: + WidgetPDial *phaserp3; +private: + void cb_phaserp3_i(WidgetPDial*, void*); + static void cb_phaserp3(WidgetPDial*, void*); +public: + WidgetPDial *phaserp5; +private: + void cb_phaserp5_i(WidgetPDial*, void*); + static void cb_phaserp5(WidgetPDial*, void*); +public: + WidgetPDial *phaserp6; +private: + void cb_phaserp6_i(WidgetPDial*, void*); + static void cb_phaserp6(WidgetPDial*, void*); +public: + WidgetPDial *phaserp7; +private: + void cb_phaserp7_i(WidgetPDial*, void*); + static void cb_phaserp7(WidgetPDial*, void*); +public: + WidgetPDial *phaserp9; +private: + void cb_phaserp9_i(WidgetPDial*, void*); + static void cb_phaserp9(WidgetPDial*, void*); +public: + Fl_Check_Button *phaserp10; +private: + void cb_phaserp10_i(Fl_Check_Button*, void*); + static void cb_phaserp10(Fl_Check_Button*, void*); +public: + Fl_Choice *phaserp4; +private: + void cb_phaserp4_i(Fl_Choice*, void*); + static void cb_phaserp4(Fl_Choice*, void*); + static Fl_Menu_Item menu_phaserp4[]; +public: + Fl_Counter *phaserp8; +private: + void cb_phaserp8_i(Fl_Counter*, void*); + static void cb_phaserp8(Fl_Counter*, void*); +public: + WidgetPDial *phaserp11; +private: + void cb_phaserp11_i(WidgetPDial*, void*); + static void cb_phaserp11(WidgetPDial*, void*); +public: + Fl_Group* make_alienwah_window(); + Fl_Group *effalienwahwindow; + Fl_Choice *awp; +private: + void cb_awp_i(Fl_Choice*, void*); + static void cb_awp(Fl_Choice*, void*); + static Fl_Menu_Item menu_awp[]; +public: + WidgetPDial *awp0; +private: + void cb_awp0_i(WidgetPDial*, void*); + static void cb_awp0(WidgetPDial*, void*); +public: + WidgetPDial *awp1; +private: + void cb_awp1_i(WidgetPDial*, void*); + static void cb_awp1(WidgetPDial*, void*); +public: + WidgetPDial *awp2; +private: + void cb_awp2_i(WidgetPDial*, void*); + static void cb_awp2(WidgetPDial*, void*); +public: + WidgetPDial *awp3; +private: + void cb_awp3_i(WidgetPDial*, void*); + static void cb_awp3(WidgetPDial*, void*); +public: + WidgetPDial *awp5; +private: + void cb_awp5_i(WidgetPDial*, void*); + static void cb_awp5(WidgetPDial*, void*); +public: + WidgetPDial *awp6; +private: + void cb_awp6_i(WidgetPDial*, void*); + static void cb_awp6(WidgetPDial*, void*); +public: + WidgetPDial *awp7; +private: + void cb_awp7_i(WidgetPDial*, void*); + static void cb_awp7(WidgetPDial*, void*); +public: + WidgetPDial *awp9; +private: + void cb_awp9_i(WidgetPDial*, void*); + static void cb_awp9(WidgetPDial*, void*); +public: + Fl_Choice *awp4; +private: + void cb_awp4_i(Fl_Choice*, void*); + static void cb_awp4(Fl_Choice*, void*); + static Fl_Menu_Item menu_awp4[]; +public: + WidgetPDial *awp10; +private: + void cb_awp10_i(WidgetPDial*, void*); + static void cb_awp10(WidgetPDial*, void*); +public: + Fl_Counter *awp8; +private: + void cb_awp8_i(Fl_Counter*, void*); + static void cb_awp8(Fl_Counter*, void*); +public: + Fl_Group* make_distorsion_window(); + Fl_Group *effdistorsionwindow; + Fl_Choice *distp; +private: + void cb_distp_i(Fl_Choice*, void*); + static void cb_distp(Fl_Choice*, void*); + static Fl_Menu_Item menu_distp[]; +public: + WidgetPDial *distp0; +private: + void cb_distp0_i(WidgetPDial*, void*); + static void cb_distp0(WidgetPDial*, void*); +public: + WidgetPDial *distp1; +private: + void cb_distp1_i(WidgetPDial*, void*); + static void cb_distp1(WidgetPDial*, void*); +public: + WidgetPDial *distp2; +private: + void cb_distp2_i(WidgetPDial*, void*); + static void cb_distp2(WidgetPDial*, void*); +public: + WidgetPDial *distp3; +private: + void cb_distp3_i(WidgetPDial*, void*); + static void cb_distp3(WidgetPDial*, void*); +public: + WidgetPDial *distp4; +private: + void cb_distp4_i(WidgetPDial*, void*); + static void cb_distp4(WidgetPDial*, void*); +public: + WidgetPDial *distp7; +private: + void cb_distp7_i(WidgetPDial*, void*); + static void cb_distp7(WidgetPDial*, void*); +public: + WidgetPDial *distp8; +private: + void cb_distp8_i(WidgetPDial*, void*); + static void cb_distp8(WidgetPDial*, void*); +public: + Fl_Choice *distp5; +private: + void cb_distp5_i(Fl_Choice*, void*); + static void cb_distp5(Fl_Choice*, void*); + static Fl_Menu_Item menu_distp5[]; +public: + Fl_Check_Button *distp6; +private: + void cb_distp6_i(Fl_Check_Button*, void*); + static void cb_distp6(Fl_Check_Button*, void*); +public: + Fl_Check_Button *distp9; +private: + void cb_distp9_i(Fl_Check_Button*, void*); + static void cb_distp9(Fl_Check_Button*, void*); +public: + Fl_Check_Button *distp10; +private: + void cb_distp10_i(Fl_Check_Button*, void*); + static void cb_distp10(Fl_Check_Button*, void*); +public: + Fl_Group* make_eq_window(); + Fl_Group *effeqwindow; + WidgetPDial *eqp0; +private: + void cb_eqp0_i(WidgetPDial*, void*); + static void cb_eqp0(WidgetPDial*, void*); +public: + Fl_Counter *bandcounter; +private: + void cb_bandcounter_i(Fl_Counter*, void*); + static void cb_bandcounter(Fl_Counter*, void*); +public: + Fl_Group *bandgroup; + WidgetPDial *freqdial; +private: + void cb_freqdial_i(WidgetPDial*, void*); + static void cb_freqdial(WidgetPDial*, void*); +public: + WidgetPDial *gaindial; +private: + void cb_gaindial_i(WidgetPDial*, void*); + static void cb_gaindial(WidgetPDial*, void*); +public: + WidgetPDial *qdial; +private: + void cb_qdial_i(WidgetPDial*, void*); + static void cb_qdial(WidgetPDial*, void*); +public: + Fl_Counter *stagescounter; +private: + void cb_stagescounter_i(Fl_Counter*, void*); + static void cb_stagescounter(Fl_Counter*, void*); +public: + Fl_Choice *typechoice; +private: + void cb_typechoice_i(Fl_Choice*, void*); + static void cb_typechoice(Fl_Choice*, void*); + static Fl_Menu_Item menu_typechoice[]; +public: + EQGraph *eqgraph; + Fl_Group* make_dynamicfilter_window(); + Fl_Group *effdynamicfilterwindow; + Fl_Choice *dfp; +private: + void cb_dfp_i(Fl_Choice*, void*); + static void cb_dfp(Fl_Choice*, void*); + static Fl_Menu_Item menu_dfp[]; +public: + WidgetPDial *dfp0; +private: + void cb_dfp0_i(WidgetPDial*, void*); + static void cb_dfp0(WidgetPDial*, void*); +public: + WidgetPDial *dfp1; +private: + void cb_dfp1_i(WidgetPDial*, void*); + static void cb_dfp1(WidgetPDial*, void*); +public: + WidgetPDial *dfp2; +private: + void cb_dfp2_i(WidgetPDial*, void*); + static void cb_dfp2(WidgetPDial*, void*); +public: + WidgetPDial *dfp3; +private: + void cb_dfp3_i(WidgetPDial*, void*); + static void cb_dfp3(WidgetPDial*, void*); +public: + WidgetPDial *dfp5; +private: + void cb_dfp5_i(WidgetPDial*, void*); + static void cb_dfp5(WidgetPDial*, void*); +public: + WidgetPDial *dfp6; +private: + void cb_dfp6_i(WidgetPDial*, void*); + static void cb_dfp6(WidgetPDial*, void*); +public: + Fl_Choice *dfp4; +private: + void cb_dfp4_i(Fl_Choice*, void*); + static void cb_dfp4(Fl_Choice*, void*); + static Fl_Menu_Item menu_dfp4[]; + void cb_Filter_i(Fl_Button*, void*); + static void cb_Filter(Fl_Button*, void*); +public: + WidgetPDial *dfp7; +private: + void cb_dfp7_i(WidgetPDial*, void*); + static void cb_dfp7(WidgetPDial*, void*); +public: + WidgetPDial *dfp9; +private: + void cb_dfp9_i(WidgetPDial*, void*); + static void cb_dfp9(WidgetPDial*, void*); +public: + Fl_Check_Button *dfp8; +private: + void cb_dfp8_i(Fl_Check_Button*, void*); + static void cb_dfp8(Fl_Check_Button*, void*); +public: + Fl_Double_Window* make_filter_window(); + Fl_Double_Window *filterwindow; +private: + void cb_Close_i(Fl_Button*, void*); + static void cb_Close(Fl_Button*, void*); +public: + void init(EffectMgr *eff_); + void refresh(EffectMgr *eff_); + void refresh(); +private: + EffectMgr *eff; + int eqband; +}; + +class SimpleEffUI : public Fl_Group,public PresetsUI_ { +public: + SimpleEffUI(int x,int y, int w, int h, const char *label=0); + ~SimpleEffUI(); + Fl_Group* make_null_window(); + Fl_Group *effnullwindow; + Fl_Group* make_reverb_window(); + Fl_Group *effreverbwindow; + Fl_Choice *revp; +private: + void cb_revpa_i(Fl_Choice*, void*); + static void cb_revpa(Fl_Choice*, void*); + static Fl_Menu_Item menu_revp1[]; +public: + WidgetPDial *revp0; +private: + void cb_revp01_i(WidgetPDial*, void*); + static void cb_revp01(WidgetPDial*, void*); +public: + WidgetPDial *revp2; +private: + void cb_revp21_i(WidgetPDial*, void*); + static void cb_revp21(WidgetPDial*, void*); +public: + WidgetPDial *revp3; +private: + void cb_revp31_i(WidgetPDial*, void*); + static void cb_revp31(WidgetPDial*, void*); +public: + WidgetPDial *revp9; +private: + void cb_revp91_i(WidgetPDial*, void*); + static void cb_revp91(WidgetPDial*, void*); +public: + Fl_Group* make_echo_window(); + Fl_Group *effechowindow; + Fl_Choice *echop; +private: + void cb_echop7_i(Fl_Choice*, void*); + static void cb_echop7(Fl_Choice*, void*); + static Fl_Menu_Item menu_echop1[]; +public: + WidgetPDial *echop0; +private: + void cb_echop01_i(WidgetPDial*, void*); + static void cb_echop01(WidgetPDial*, void*); +public: + WidgetPDial *echop2; +private: + void cb_echop21_i(WidgetPDial*, void*); + static void cb_echop21(WidgetPDial*, void*); +public: + WidgetPDial *echop5; +private: + void cb_echop51_i(WidgetPDial*, void*); + static void cb_echop51(WidgetPDial*, void*); +public: + Fl_Group* make_chorus_window(); + Fl_Group *effchoruswindow; + Fl_Choice *chorusp; +private: + void cb_choruspa_i(Fl_Choice*, void*); + static void cb_choruspa(Fl_Choice*, void*); + static Fl_Menu_Item menu_chorusp1[]; +public: + WidgetPDial *chorusp0; +private: + void cb_chorusp01_i(WidgetPDial*, void*); + static void cb_chorusp01(WidgetPDial*, void*); +public: + WidgetPDial *chorusp2; +private: + void cb_chorusp21_i(WidgetPDial*, void*); + static void cb_chorusp21(WidgetPDial*, void*); +public: + WidgetPDial *chorusp6; +private: + void cb_chorusp61_i(WidgetPDial*, void*); + static void cb_chorusp61(WidgetPDial*, void*); +public: + WidgetPDial *chorusp7; +private: + void cb_chorusp71_i(WidgetPDial*, void*); + static void cb_chorusp71(WidgetPDial*, void*); +public: + WidgetPDial *chorusp8; +private: + void cb_chorusp81_i(WidgetPDial*, void*); + static void cb_chorusp81(WidgetPDial*, void*); + void cb_Flange1_i(Fl_Check_Button*, void*); + static void cb_Flange1(Fl_Check_Button*, void*); +public: + Fl_Group* make_phaser_window(); + Fl_Group *effphaserwindow; + Fl_Choice *phaserp; +private: + void cb_phaserpa_i(Fl_Choice*, void*); + static void cb_phaserpa(Fl_Choice*, void*); + static Fl_Menu_Item menu_phaserp1[]; +public: + WidgetPDial *phaserp0; +private: + void cb_phaserp01_i(WidgetPDial*, void*); + static void cb_phaserp01(WidgetPDial*, void*); +public: + WidgetPDial *phaserp2; +private: + void cb_phaserp21_i(WidgetPDial*, void*); + static void cb_phaserp21(WidgetPDial*, void*); +public: + WidgetPDial *phaserp5; +private: + void cb_phaserp51_i(WidgetPDial*, void*); + static void cb_phaserp51(WidgetPDial*, void*); +public: + WidgetPDial *phaserp6; +private: + void cb_phaserp61_i(WidgetPDial*, void*); + static void cb_phaserp61(WidgetPDial*, void*); +public: + WidgetPDial *phaserp7; +private: + void cb_phaserp71_i(WidgetPDial*, void*); + static void cb_phaserp71(WidgetPDial*, void*); +public: + Fl_Counter *phaserp8; +private: + void cb_phaserp81_i(Fl_Counter*, void*); + static void cb_phaserp81(Fl_Counter*, void*); +public: + Fl_Group* make_alienwah_window(); + Fl_Group *effalienwahwindow; + Fl_Choice *awp; +private: + void cb_awpa_i(Fl_Choice*, void*); + static void cb_awpa(Fl_Choice*, void*); + static Fl_Menu_Item menu_awp1[]; +public: + WidgetPDial *awp0; +private: + void cb_awp01_i(WidgetPDial*, void*); + static void cb_awp01(WidgetPDial*, void*); +public: + WidgetPDial *awp2; +private: + void cb_awp21_i(WidgetPDial*, void*); + static void cb_awp21(WidgetPDial*, void*); +public: + WidgetPDial *awp6; +private: + void cb_awp61_i(WidgetPDial*, void*); + static void cb_awp61(WidgetPDial*, void*); +public: + Fl_Counter *awp8; +private: + void cb_awp81_i(Fl_Counter*, void*); + static void cb_awp81(Fl_Counter*, void*); +public: + Fl_Group* make_distorsion_window(); + Fl_Group *effdistorsionwindow; + Fl_Choice *distp; +private: + void cb_distpa_i(Fl_Choice*, void*); + static void cb_distpa(Fl_Choice*, void*); + static Fl_Menu_Item menu_distp1[]; +public: + WidgetPDial *distp0; +private: + void cb_distp01_i(WidgetPDial*, void*); + static void cb_distp01(WidgetPDial*, void*); +public: + WidgetPDial *distp3; +private: + void cb_distp31_i(WidgetPDial*, void*); + static void cb_distp31(WidgetPDial*, void*); +public: + WidgetPDial *distp4; +private: + void cb_distp41_i(WidgetPDial*, void*); + static void cb_distp41(WidgetPDial*, void*); +public: + WidgetPDial *distp7; +private: + void cb_distp71_i(WidgetPDial*, void*); + static void cb_distp71(WidgetPDial*, void*); +public: + Fl_Choice *distp5; +private: + void cb_distp51_i(Fl_Choice*, void*); + static void cb_distp51(Fl_Choice*, void*); + static Fl_Menu_Item menu_distp51[]; +public: + Fl_Group* make_eq_window(); + Fl_Group *effeqwindow; + Fl_Counter *bandcounter; +private: + void cb_bandcounter1_i(Fl_Counter*, void*); + static void cb_bandcounter1(Fl_Counter*, void*); +public: + Fl_Group *bandgroup; + WidgetPDial *freqdial; +private: + void cb_freqdial1_i(WidgetPDial*, void*); + static void cb_freqdial1(WidgetPDial*, void*); +public: + WidgetPDial *gaindial; +private: + void cb_gaindial1_i(WidgetPDial*, void*); + static void cb_gaindial1(WidgetPDial*, void*); +public: + WidgetPDial *qdial; +private: + void cb_qdial1_i(WidgetPDial*, void*); + static void cb_qdial1(WidgetPDial*, void*); +public: + Fl_Counter *stagescounter; +private: + void cb_stagescounter1_i(Fl_Counter*, void*); + static void cb_stagescounter1(Fl_Counter*, void*); +public: + Fl_Choice *typechoice; +private: + void cb_typechoice1_i(Fl_Choice*, void*); + static void cb_typechoice1(Fl_Choice*, void*); + static Fl_Menu_Item menu_typechoice1[]; +public: + EQGraph *eqgraph; + Fl_Group* make_dynamicfilter_window(); + Fl_Group *effdynamicfilterwindow; + Fl_Choice *dfp; +private: + void cb_dfpa_i(Fl_Choice*, void*); + static void cb_dfpa(Fl_Choice*, void*); + static Fl_Menu_Item menu_dfp1[]; +public: + WidgetPDial *dfp0; +private: + void cb_dfp01_i(WidgetPDial*, void*); + static void cb_dfp01(WidgetPDial*, void*); +public: + WidgetPDial *dfp2; +private: + void cb_dfp21_i(WidgetPDial*, void*); + static void cb_dfp21(WidgetPDial*, void*); +public: + WidgetPDial *dfp6; +private: + void cb_dfp61_i(WidgetPDial*, void*); + static void cb_dfp61(WidgetPDial*, void*); +public: + WidgetPDial *dfp7; +private: + void cb_dfp71_i(WidgetPDial*, void*); + static void cb_dfp71(WidgetPDial*, void*); +public: + WidgetPDial *dfp9; +private: + void cb_dfp91_i(WidgetPDial*, void*); + static void cb_dfp91(WidgetPDial*, void*); +public: + void init(EffectMgr *eff_); + void refresh(EffectMgr *eff_); + void refresh(); +private: + EffectMgr *eff; + int eqband; +}; +#endif diff --git a/plugins/zynaddsubfx/src/UI/EnvelopeUI.cc b/plugins/zynaddsubfx/src/UI/EnvelopeUI.cc new file mode 100644 index 000000000..e7fa3516e --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/EnvelopeUI.cc @@ -0,0 +1,1525 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0109 + +#include "EnvelopeUI.h" +//Copyright (c) 2002-2005 Nasca Octavian Paul +//License: GNU GPL version 2 or later + +EnvelopeFreeEdit::EnvelopeFreeEdit(int x,int y, int w, int h, const char *label):Fl_Box(x,y,w,h,label) { + env=NULL; +pair=NULL; +} + +void EnvelopeFreeEdit::init(EnvelopeParams *env_) { + env=env_; +oldx=-1; +currentpoint=-1; +cpx=0; +lastpoint=-1; +} + +void EnvelopeFreeEdit::setpair(Fl_Box *pair_) { + pair=pair_; +} + +int EnvelopeFreeEdit::getpointx(int n) { + int lx=w()-10; +int npoints=env->Penvpoints; + +float sum=0; +for (int i=1;igetdt(i)+1; + +float sumbefore=0;//the sum of all points before the computed point +for (int i=1;i<=n;i++) sumbefore+=env->getdt(i)+1; + +return((int) (sumbefore/(REALTYPE) sum*lx)); +} + +int EnvelopeFreeEdit::getpointy(int n) { + int ly=h()-10; + +return((int) ((1.0-env->Penvval[n]/127.0)*ly)); +} + +int EnvelopeFreeEdit::getnearest(int x,int y) { + x-=5;y-=5; + +int nearestpoint=0; +int nearestval=1000000;//a big value +for (int i=0;iPenvpoints;i++){ + int distance=abs(x-getpointx(i))+abs(y-getpointy(i)); + if (distancePfreemode==0) env->converttofree(); +int npoints=env->Penvpoints; + +if (active_r()) fl_color(FL_BLACK); + else fl_color(90,90,90); +if (!active_r()) currentpoint=-1; + +fl_rectf(ox,oy,lx,ly); + +ox+=5;oy+=5;lx-=10;ly-=10; + +//draw the lines +fl_color(FL_GRAY); + +fl_line_style(FL_SOLID); +fl_line(ox+2,oy+ly/2,ox+lx-2,oy+ly/2); + +//draws the evelope points and lines +Fl_Color alb=FL_WHITE; +if (!active_r()) alb=fl_rgb_color(180,180,180); +fl_color(alb); +int oldxx=0,xx=0,oldyy=0,yy=getpointy(0); +fl_rectf(ox-3,oy+yy-3,6,6); +for (int i=1;i=0){ + fl_color(FL_CYAN); + fl_rectf(ox+getpointx(lastpoint)-5,oy+getpointy(lastpoint)-5,10,10); +}; + +//draw the sustain position +if (env->Penvsustain>0){ + fl_color(FL_YELLOW); + xx=getpointx(env->Penvsustain); + fl_line(ox+xx,oy+0,ox+xx,oy+ly); +}; + +//Show the envelope duration and the current line duration +fl_font(FL_HELVETICA|FL_BOLD,10); +float time=0.0; +if (currentpoint<=0){ + fl_color(alb); + for (int i=1;igetdt(i); +} else { + fl_color(255,0,0); + time=env->getdt(currentpoint); +}; +char tmpstr[20]; +if (time<1000.0) snprintf((char *)&tmpstr,20,"%.1fms",time); + else snprintf((char *)&tmpstr,20,"%.2fs",time/1000.0); +fl_draw(tmpstr,ox+lx-20,oy+ly-10,20,10,FL_ALIGN_RIGHT,NULL,0); +} + +int EnvelopeFreeEdit::handle(int event) { + int x_=Fl::event_x()-x(); +int y_=Fl::event_y()-y(); + +if (event==FL_PUSH) { + currentpoint=getnearest(x_,y_); + cpx=x_; + cpdt=env->Penvdt[currentpoint]; + lastpoint=currentpoint; + redraw(); + if (pair!=NULL) pair->redraw(); +}; + +if (event==FL_RELEASE){ + currentpoint=-1; + redraw(); + if (pair!=NULL) pair->redraw(); +}; + +if ((event==FL_DRAG)&&(currentpoint>=0)){ + int ny=127-(int) (y_*127.0/h()); + if (ny<0) ny=0;if (ny>127) ny=127; + env->Penvval[currentpoint]=ny; + + int dx=(int)((x_-cpx)*0.1); + int newdt=cpdt+dx; + if (newdt<0) newdt=0;if (newdt>127) newdt=127; + if (currentpoint!=0) env->Penvdt[currentpoint]=newdt; + else env->Penvdt[currentpoint]=0; + + redraw(); + if (pair!=NULL) pair->redraw(); +}; + + +return(1); +} + +void EnvelopeUI::cb_addpoint_i(Fl_Button*, void*) { + int curpoint=freeedit->lastpoint; +if (curpoint<0) return; +//if (curpoint>=env->Penvpoints-1) return; +if (env->Penvpoints>=MAX_ENVELOPE_POINTS) return; + +for (int i=env->Penvpoints;i>=curpoint+1;i--){ + env->Penvdt[i]=env->Penvdt[i-1]; + env->Penvval[i]=env->Penvval[i-1]; +}; + +if (curpoint==0) { + env->Penvdt[1]=64; +}; + +env->Penvpoints++; +if (curpoint<=env->Penvsustain) env->Penvsustain++; + +freeedit->lastpoint+=1; +freeedit->redraw(); +envfree->redraw(); + +sustaincounter->value(env->Penvsustain); +sustaincounter->maximum(env->Penvpoints-2); +} +void EnvelopeUI::cb_addpoint(Fl_Button* o, void* v) { + ((EnvelopeUI*)(o->parent()->user_data()))->cb_addpoint_i(o,v); +} + +void EnvelopeUI::cb_deletepoint_i(Fl_Button*, void*) { + int curpoint=freeedit->lastpoint; +if (curpoint<1) return; +if (curpoint>=env->Penvpoints-1) return; +if (env->Penvpoints<=3) return; + +for (int i=curpoint+1;iPenvpoints;i++){ + env->Penvdt[i-1]=env->Penvdt[i]; + env->Penvval[i-1]=env->Penvval[i]; +}; + +env->Penvpoints--; + +if (curpoint<=env->Penvsustain) env->Penvsustain--; + + +freeedit->lastpoint-=1; +freeedit->redraw(); +envfree->redraw(); + +sustaincounter->value(env->Penvsustain); +sustaincounter->maximum(env->Penvpoints-2); +} +void EnvelopeUI::cb_deletepoint(Fl_Button* o, void* v) { + ((EnvelopeUI*)(o->parent()->user_data()))->cb_deletepoint_i(o,v); +} + +void EnvelopeUI::cb_freemodebutton_i(Fl_Light_Button*, void*) { + reinit(); + +freeedit->lastpoint=-1; +freeedit->redraw(); +} +void EnvelopeUI::cb_freemodebutton(Fl_Light_Button* o, void* v) { + ((EnvelopeUI*)(o->parent()->user_data()))->cb_freemodebutton_i(o,v); +} + +void EnvelopeUI::cb_forcedreleasecheck_i(Fl_Check_Button* o, void*) { + env->Pforcedrelease=(int)o->value(); +} +void EnvelopeUI::cb_forcedreleasecheck(Fl_Check_Button* o, void* v) { + ((EnvelopeUI*)(o->parent()->user_data()))->cb_forcedreleasecheck_i(o,v); +} + +void EnvelopeUI::cb_envstretchdial_i(WidgetPDial* o, void*) { + env->Penvstretch=(int)o->value(); +} +void EnvelopeUI::cb_envstretchdial(WidgetPDial* o, void* v) { + ((EnvelopeUI*)(o->parent()->user_data()))->cb_envstretchdial_i(o,v); +} + +void EnvelopeUI::cb_Close_i(Fl_Button*, void*) { + freemodeeditwindow->hide(); +} +void EnvelopeUI::cb_Close(Fl_Button* o, void* v) { + ((EnvelopeUI*)(o->parent()->user_data()))->cb_Close_i(o,v); +} + +void EnvelopeUI::cb_linearenvelopecheck_i(Fl_Check_Button* o, void*) { + env->Plinearenvelope=(int)o->value(); +} +void EnvelopeUI::cb_linearenvelopecheck(Fl_Check_Button* o, void* v) { + ((EnvelopeUI*)(o->parent()->user_data()))->cb_linearenvelopecheck_i(o,v); +} + +void EnvelopeUI::cb_sustaincounter_i(Fl_Counter* o, void*) { + env->Penvsustain=(int) o->value(); +freeedit->redraw(); +envfree->redraw(); +} +void EnvelopeUI::cb_sustaincounter(Fl_Counter* o, void* v) { + ((EnvelopeUI*)(o->parent()->user_data()))->cb_sustaincounter_i(o,v); +} + +void EnvelopeUI::cb_C_i(Fl_Button*, void*) { + presetsui->copy(env); +} +void EnvelopeUI::cb_C(Fl_Button* o, void* v) { + ((EnvelopeUI*)(o->parent()->user_data()))->cb_C_i(o,v); +} + +void EnvelopeUI::cb_P_i(Fl_Button*, void*) { + presetsui->paste(env,this); +} +void EnvelopeUI::cb_P(Fl_Button* o, void* v) { + ((EnvelopeUI*)(o->parent()->user_data()))->cb_P_i(o,v); +} + +void EnvelopeUI::cb_e1adt_i(WidgetPDial* o, void*) { + env->PA_dt=(int)o->value(); +freeedit->redraw(); +} +void EnvelopeUI::cb_e1adt(WidgetPDial* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e1adt_i(o,v); +} + +void EnvelopeUI::cb_e1ddt_i(WidgetPDial* o, void*) { + env->PD_dt=(int)o->value(); +freeedit->redraw(); +} +void EnvelopeUI::cb_e1ddt(WidgetPDial* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e1ddt_i(o,v); +} + +void EnvelopeUI::cb_e1rdt_i(WidgetPDial* o, void*) { + env->PR_dt=(int)o->value(); +freeedit->redraw(); +} +void EnvelopeUI::cb_e1rdt(WidgetPDial* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e1rdt_i(o,v); +} + +void EnvelopeUI::cb_e1sval_i(WidgetPDial* o, void*) { + env->PS_val=(int)o->value(); +freeedit->redraw(); +} +void EnvelopeUI::cb_e1sval(WidgetPDial* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e1sval_i(o,v); +} + +void EnvelopeUI::cb_e1forcedrelease_i(Fl_Check_Button* o, void*) { + env->Pforcedrelease=(int)o->value(); +} +void EnvelopeUI::cb_e1forcedrelease(Fl_Check_Button* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e1forcedrelease_i(o,v); +} + +void EnvelopeUI::cb_e1envstretch_i(WidgetPDial* o, void*) { + env->Penvstretch=(int)o->value(); +} +void EnvelopeUI::cb_e1envstretch(WidgetPDial* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e1envstretch_i(o,v); +} + +void EnvelopeUI::cb_E_i(Fl_Button*, void*) { + freemodeeditwindow->show(); +} +void EnvelopeUI::cb_E(Fl_Button* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_E_i(o,v); +} + +void EnvelopeUI::cb_e1linearenvelope_i(Fl_Check_Button* o, void*) { + env->Plinearenvelope=(int)o->value(); +} +void EnvelopeUI::cb_e1linearenvelope(Fl_Check_Button* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e1linearenvelope_i(o,v); +} + +void EnvelopeUI::cb_C1_i(Fl_Button*, void*) { + presetsui->copy(env); +} +void EnvelopeUI::cb_C1(Fl_Button* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_C1_i(o,v); +} + +void EnvelopeUI::cb_P1_i(Fl_Button*, void*) { + presetsui->paste(env,this); +} +void EnvelopeUI::cb_P1(Fl_Button* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_P1_i(o,v); +} + +void EnvelopeUI::cb_e2aval_i(WidgetPDial* o, void*) { + env->PA_val=(int)o->value(); +freeedit->redraw(); +} +void EnvelopeUI::cb_e2aval(WidgetPDial* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e2aval_i(o,v); +} + +void EnvelopeUI::cb_e2adt_i(WidgetPDial* o, void*) { + env->PA_dt=(int)o->value(); +freeedit->redraw(); +} +void EnvelopeUI::cb_e2adt(WidgetPDial* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e2adt_i(o,v); +} + +void EnvelopeUI::cb_e2rval_i(WidgetPDial* o, void*) { + env->PR_val=(int)o->value(); +freeedit->redraw(); +} +void EnvelopeUI::cb_e2rval(WidgetPDial* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e2rval_i(o,v); +} + +void EnvelopeUI::cb_e2rdt_i(WidgetPDial* o, void*) { + env->PR_dt=(int)o->value(); +freeedit->redraw(); +} +void EnvelopeUI::cb_e2rdt(WidgetPDial* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e2rdt_i(o,v); +} + +void EnvelopeUI::cb_e2envstretch_i(WidgetPDial* o, void*) { + env->Penvstretch=(int)o->value(); +} +void EnvelopeUI::cb_e2envstretch(WidgetPDial* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e2envstretch_i(o,v); +} + +void EnvelopeUI::cb_e2forcedrelease_i(Fl_Check_Button* o, void*) { + env->Pforcedrelease=(int)o->value(); +} +void EnvelopeUI::cb_e2forcedrelease(Fl_Check_Button* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e2forcedrelease_i(o,v); +} + +void EnvelopeUI::cb_C2_i(Fl_Button*, void*) { + presetsui->copy(env); +} +void EnvelopeUI::cb_C2(Fl_Button* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_C2_i(o,v); +} + +void EnvelopeUI::cb_P2_i(Fl_Button*, void*) { + presetsui->paste(env,this); +} +void EnvelopeUI::cb_P2(Fl_Button* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_P2_i(o,v); +} + +void EnvelopeUI::cb_E1_i(Fl_Button*, void*) { + freemodeeditwindow->show(); +} +void EnvelopeUI::cb_E1(Fl_Button* o, void* v) { + ((EnvelopeUI*)(o->parent()->user_data()))->cb_E1_i(o,v); +} + +void EnvelopeUI::cb_e3aval_i(WidgetPDial* o, void*) { + env->PA_val=(int)o->value(); +freeedit->redraw(); +} +void EnvelopeUI::cb_e3aval(WidgetPDial* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e3aval_i(o,v); +} + +void EnvelopeUI::cb_e3adt_i(WidgetPDial* o, void*) { + env->PA_dt=(int)o->value(); +freeedit->redraw(); +} +void EnvelopeUI::cb_e3adt(WidgetPDial* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e3adt_i(o,v); +} + +void EnvelopeUI::cb_e3dval_i(WidgetPDial* o, void*) { + env->PD_val=(int)o->value(); +freeedit->redraw(); +} +void EnvelopeUI::cb_e3dval(WidgetPDial* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e3dval_i(o,v); +} + +void EnvelopeUI::cb_e3ddt_i(WidgetPDial* o, void*) { + env->PD_dt=(int)o->value(); +freeedit->redraw(); +} +void EnvelopeUI::cb_e3ddt(WidgetPDial* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e3ddt_i(o,v); +} + +void EnvelopeUI::cb_e3rdt_i(WidgetPDial* o, void*) { + env->PR_dt=(int)o->value(); +freeedit->redraw(); +} +void EnvelopeUI::cb_e3rdt(WidgetPDial* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e3rdt_i(o,v); +} + +void EnvelopeUI::cb_e3rval_i(WidgetPDial* o, void*) { + env->PR_val=(int)o->value(); +freeedit->redraw(); +} +void EnvelopeUI::cb_e3rval(WidgetPDial* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e3rval_i(o,v); +} + +void EnvelopeUI::cb_e3envstretch_i(WidgetPDial* o, void*) { + env->Penvstretch=(int)o->value(); +} +void EnvelopeUI::cb_e3envstretch(WidgetPDial* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e3envstretch_i(o,v); +} + +void EnvelopeUI::cb_e3forcedrelease_i(Fl_Check_Button* o, void*) { + env->Pforcedrelease=(int)o->value(); +} +void EnvelopeUI::cb_e3forcedrelease(Fl_Check_Button* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e3forcedrelease_i(o,v); +} + +void EnvelopeUI::cb_E2_i(Fl_Button*, void*) { + freemodeeditwindow->show(); +} +void EnvelopeUI::cb_E2(Fl_Button* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_E2_i(o,v); +} + +void EnvelopeUI::cb_C3_i(Fl_Button*, void*) { + presetsui->copy(env); +} +void EnvelopeUI::cb_C3(Fl_Button* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_C3_i(o,v); +} + +void EnvelopeUI::cb_P3_i(Fl_Button*, void*) { + presetsui->paste(env,this); +} +void EnvelopeUI::cb_P3(Fl_Button* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_P3_i(o,v); +} + +void EnvelopeUI::cb_e4aval_i(WidgetPDial* o, void*) { + env->PA_val=(int)o->value(); +freeedit->redraw(); +} +void EnvelopeUI::cb_e4aval(WidgetPDial* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e4aval_i(o,v); +} + +void EnvelopeUI::cb_e4adt_i(WidgetPDial* o, void*) { + env->PA_dt=(int)o->value(); +freeedit->redraw(); +} +void EnvelopeUI::cb_e4adt(WidgetPDial* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e4adt_i(o,v); +} + +void EnvelopeUI::cb_e4rval_i(WidgetPDial* o, void*) { + env->PR_val=(int)o->value(); +freeedit->redraw(); +} +void EnvelopeUI::cb_e4rval(WidgetPDial* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e4rval_i(o,v); +} + +void EnvelopeUI::cb_e4rdt_i(WidgetPDial* o, void*) { + env->PR_dt=(int)o->value(); +freeedit->redraw(); +} +void EnvelopeUI::cb_e4rdt(WidgetPDial* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e4rdt_i(o,v); +} + +void EnvelopeUI::cb_e4envstretch_i(WidgetPDial* o, void*) { + env->Penvstretch=(int)o->value(); +} +void EnvelopeUI::cb_e4envstretch(WidgetPDial* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e4envstretch_i(o,v); +} + +void EnvelopeUI::cb_e4forcedrelease_i(Fl_Check_Button* o, void*) { + env->Pforcedrelease=(int)o->value(); +} +void EnvelopeUI::cb_e4forcedrelease(Fl_Check_Button* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e4forcedrelease_i(o,v); +} + +void EnvelopeUI::cb_C4_i(Fl_Button*, void*) { + presetsui->copy(env); +} +void EnvelopeUI::cb_C4(Fl_Button* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_C4_i(o,v); +} + +void EnvelopeUI::cb_P4_i(Fl_Button*, void*) { + presetsui->paste(env,this); +} +void EnvelopeUI::cb_P4(Fl_Button* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_P4_i(o,v); +} + +void EnvelopeUI::cb_E3_i(Fl_Button*, void*) { + freemodeeditwindow->show(); +} +void EnvelopeUI::cb_E3(Fl_Button* o, void* v) { + ((EnvelopeUI*)(o->parent()->user_data()))->cb_E3_i(o,v); +} + +void EnvelopeUI::cb_freeeditsmall_i(EnvelopeFreeEdit*, void*) { + envfree->redraw(); +} +void EnvelopeUI::cb_freeeditsmall(EnvelopeFreeEdit* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_freeeditsmall_i(o,v); +} + +void EnvelopeUI::cb_E4_i(Fl_Button*, void*) { + freemodeeditwindow->show(); +} +void EnvelopeUI::cb_E4(Fl_Button* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_E4_i(o,v); +} + +void EnvelopeUI::cb_C5_i(Fl_Button*, void*) { + presetsui->copy(env); +} +void EnvelopeUI::cb_C5(Fl_Button* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_C5_i(o,v); +} + +void EnvelopeUI::cb_P5_i(Fl_Button*, void*) { + presetsui->paste(env,this); +} +void EnvelopeUI::cb_P5(Fl_Button* o, void* v) { + ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_P5_i(o,v); +} + +EnvelopeUI::EnvelopeUI(int x,int y, int w, int h, const char *label):Fl_Group(x,y,w,h,label) { + env=NULL; +freemodeeditwindow=NULL; +envADSR=NULL; +envASR=NULL; +envADSRfilter=NULL; +envASRbw=NULL; +envfree=NULL; +} + +EnvelopeUI::~EnvelopeUI() { + envwindow->hide(); +hide(); +freemodeeditwindow->hide(); +delete (freemodeeditwindow); +} + +Fl_Double_Window* EnvelopeUI::make_freemode_edit_window() { + { freemodeeditwindow = new Fl_Double_Window(575, 180, "Envelope"); + freemodeeditwindow->user_data((void*)(this)); + { EnvelopeFreeEdit* o = freeedit = new EnvelopeFreeEdit(5, 5, 565, 145, "Envelope"); + freeedit->box(FL_FLAT_BOX); + freeedit->color(FL_FOREGROUND_COLOR); + freeedit->selection_color(FL_BACKGROUND_COLOR); + freeedit->labeltype(FL_NORMAL_LABEL); + freeedit->labelfont(0); + freeedit->labelsize(14); + freeedit->labelcolor(FL_FOREGROUND_COLOR); + freeedit->align(FL_ALIGN_CENTER); + freeedit->when(FL_WHEN_RELEASE); + o->init(env); + } // EnvelopeFreeEdit* freeedit + { Fl_Button* o = addpoint = new Fl_Button(115, 155, 80, 20, "Add point"); + addpoint->box(FL_THIN_UP_BOX); + addpoint->callback((Fl_Callback*)cb_addpoint); + if (env->Pfreemode==0) o->hide(); + } // Fl_Button* addpoint + { Fl_Button* o = deletepoint = new Fl_Button(200, 155, 80, 20, "Delete point"); + deletepoint->box(FL_THIN_UP_BOX); + deletepoint->callback((Fl_Callback*)cb_deletepoint); + if (env->Pfreemode==0) o->hide(); + } // Fl_Button* deletepoint + { freemodebutton = new Fl_Light_Button(10, 155, 95, 25, "FreeMode"); + freemodebutton->tooltip("Enable or disable the freemode"); + freemodebutton->box(FL_PLASTIC_UP_BOX); + freemodebutton->callback((Fl_Callback*)cb_freemodebutton); + } // Fl_Light_Button* freemodebutton + { Fl_Check_Button* o = forcedreleasecheck = new Fl_Check_Button(410, 165, 40, 15, "frcR"); + forcedreleasecheck->tooltip("Forced Relase"); + forcedreleasecheck->down_box(FL_DOWN_BOX); + forcedreleasecheck->labelsize(10); + forcedreleasecheck->callback((Fl_Callback*)cb_forcedreleasecheck); + o->value(env->Pforcedrelease); + if (env->Pfreemode==0) o->hide(); + } // Fl_Check_Button* forcedreleasecheck + { WidgetPDial* o = envstretchdial = new WidgetPDial(380, 155, 25, 25, "Str."); + envstretchdial->tooltip("Envelope stretch (on lower notes make the envelope longer)"); + envstretchdial->box(FL_ROUND_UP_BOX); + envstretchdial->color(FL_BACKGROUND_COLOR); + envstretchdial->selection_color(FL_INACTIVE_COLOR); + envstretchdial->labeltype(FL_NORMAL_LABEL); + envstretchdial->labelfont(0); + envstretchdial->labelsize(10); + envstretchdial->labelcolor(FL_FOREGROUND_COLOR); + envstretchdial->maximum(127); + envstretchdial->step(1); + envstretchdial->callback((Fl_Callback*)cb_envstretchdial); + envstretchdial->align(FL_ALIGN_LEFT); + envstretchdial->when(FL_WHEN_CHANGED); + o->value(env->Penvstretch); + if (env->Pfreemode==0) o->hide(); + } // WidgetPDial* envstretchdial + { Fl_Button* o = new Fl_Button(510, 155, 60, 25, "Close"); + o->box(FL_THIN_UP_BOX); + o->callback((Fl_Callback*)cb_Close); + } // Fl_Button* o + { Fl_Check_Button* o = linearenvelopecheck = new Fl_Check_Button(410, 151, 30, 15, "L"); + linearenvelopecheck->tooltip("Linear Envelope"); + linearenvelopecheck->down_box(FL_DOWN_BOX); + linearenvelopecheck->labelsize(10); + linearenvelopecheck->callback((Fl_Callback*)cb_linearenvelopecheck); + o->value(env->Plinearenvelope); + if ((env->Pfreemode==0)||(env->Envmode>2)) o->hide(); + } // Fl_Check_Button* linearenvelopecheck + { Fl_Counter* o = sustaincounter = new Fl_Counter(315, 155, 40, 15, "Sust"); + sustaincounter->tooltip("Sustain (0 is disabled)"); + sustaincounter->type(1); + sustaincounter->labelsize(11); + sustaincounter->minimum(0); + sustaincounter->maximum(127); + sustaincounter->step(1); + sustaincounter->callback((Fl_Callback*)cb_sustaincounter); + sustaincounter->align(FL_ALIGN_LEFT); + o->value(env->Penvsustain); + if (env->Pfreemode==0) o->hide(); + o->maximum(env->Penvpoints-2); + } // Fl_Counter* sustaincounter + { Fl_Button* o = new Fl_Button(465, 160, 15, 15, "C"); + o->box(FL_THIN_UP_BOX); + o->color((Fl_Color)179); + o->labelfont(1); + o->labelsize(10); + o->labelcolor(FL_BACKGROUND2_COLOR); + o->callback((Fl_Callback*)cb_C); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(482, 160, 15, 15, "P"); + o->box(FL_THIN_UP_BOX); + o->color((Fl_Color)179); + o->labelfont(1); + o->labelsize(10); + o->labelcolor(FL_BACKGROUND2_COLOR); + o->callback((Fl_Callback*)cb_P); + } // Fl_Button* o + freemodeeditwindow->end(); + } // Fl_Double_Window* freemodeeditwindow + return freemodeeditwindow; +} + +Fl_Group* EnvelopeUI::make_ADSR_window() { + { envADSR = new Fl_Group(0, 0, 205, 70); + envADSR->box(FL_FLAT_BOX); + envADSR->color(FL_LIGHT1); + envADSR->selection_color(FL_BACKGROUND_COLOR); + envADSR->labeltype(FL_NO_LABEL); + envADSR->labelfont(1); + envADSR->labelsize(14); + envADSR->labelcolor(FL_FOREGROUND_COLOR); + envADSR->user_data((void*)(this)); + envADSR->align(FL_ALIGN_TOP); + envADSR->when(FL_WHEN_RELEASE); + { Fl_Group* o = new Fl_Group(0, 0, 205, 70, "Amplitude Envelope"); + o->box(FL_PLASTIC_UP_BOX); + o->color(FL_CYAN); + o->labeltype(FL_ENGRAVED_LABEL); + o->labelsize(10); + o->align(FL_ALIGN_TOP|FL_ALIGN_INSIDE); + { WidgetPDial* o = e1adt = new WidgetPDial(5, 20, 30, 30, "A.dt"); + e1adt->tooltip("Attack time"); + e1adt->box(FL_ROUND_UP_BOX); + e1adt->color(FL_BACKGROUND_COLOR); + e1adt->selection_color(FL_INACTIVE_COLOR); + e1adt->labeltype(FL_NORMAL_LABEL); + e1adt->labelfont(0); + e1adt->labelsize(10); + e1adt->labelcolor(FL_FOREGROUND_COLOR); + e1adt->maximum(127); + e1adt->step(1); + e1adt->callback((Fl_Callback*)cb_e1adt); + e1adt->align(FL_ALIGN_BOTTOM); + e1adt->when(FL_WHEN_CHANGED); + o->value(env->PA_dt); + } // WidgetPDial* e1adt + { WidgetPDial* o = e1ddt = new WidgetPDial(40, 20, 30, 30, "D.dt"); + e1ddt->tooltip("Decay time"); + e1ddt->box(FL_ROUND_UP_BOX); + e1ddt->color(FL_BACKGROUND_COLOR); + e1ddt->selection_color(FL_INACTIVE_COLOR); + e1ddt->labeltype(FL_NORMAL_LABEL); + e1ddt->labelfont(0); + e1ddt->labelsize(10); + e1ddt->labelcolor(FL_FOREGROUND_COLOR); + e1ddt->maximum(127); + e1ddt->step(1); + e1ddt->callback((Fl_Callback*)cb_e1ddt); + e1ddt->align(FL_ALIGN_BOTTOM); + e1ddt->when(FL_WHEN_CHANGED); + o->value(env->PD_dt); + } // WidgetPDial* e1ddt + { WidgetPDial* o = e1rdt = new WidgetPDial(110, 20, 30, 30, "R.dt"); + e1rdt->tooltip("Release time"); + e1rdt->box(FL_ROUND_UP_BOX); + e1rdt->color(FL_BACKGROUND_COLOR); + e1rdt->selection_color(FL_INACTIVE_COLOR); + e1rdt->labeltype(FL_NORMAL_LABEL); + e1rdt->labelfont(0); + e1rdt->labelsize(10); + e1rdt->labelcolor(FL_FOREGROUND_COLOR); + e1rdt->maximum(127); + e1rdt->step(1); + e1rdt->callback((Fl_Callback*)cb_e1rdt); + e1rdt->align(FL_ALIGN_BOTTOM); + e1rdt->when(FL_WHEN_CHANGED); + o->value(env->PR_dt); + } // WidgetPDial* e1rdt + { WidgetPDial* o = e1sval = new WidgetPDial(75, 20, 30, 30, "S.val"); + e1sval->tooltip("Sustain value"); + e1sval->box(FL_ROUND_UP_BOX); + e1sval->color(FL_BACKGROUND_COLOR); + e1sval->selection_color(FL_INACTIVE_COLOR); + e1sval->labeltype(FL_NORMAL_LABEL); + e1sval->labelfont(0); + e1sval->labelsize(10); + e1sval->labelcolor(FL_FOREGROUND_COLOR); + e1sval->maximum(127); + e1sval->step(1); + e1sval->callback((Fl_Callback*)cb_e1sval); + e1sval->align(FL_ALIGN_BOTTOM); + e1sval->when(FL_WHEN_CHANGED); + o->value(env->PS_val); + } // WidgetPDial* e1sval + { Fl_Check_Button* o = e1forcedrelease = new Fl_Check_Button(180, 35, 20, 15, "frcR"); + e1forcedrelease->tooltip("Forced Relase"); + e1forcedrelease->down_box(FL_DOWN_BOX); + e1forcedrelease->labelsize(10); + e1forcedrelease->callback((Fl_Callback*)cb_e1forcedrelease); + e1forcedrelease->align(FL_ALIGN_BOTTOM_LEFT); + o->value(env->Pforcedrelease); + } // Fl_Check_Button* e1forcedrelease + { WidgetPDial* o = e1envstretch = new WidgetPDial(145, 25, 25, 25, "Stretch"); + e1envstretch->tooltip("Envelope stretch (on lower notes makes the envelope longer)"); + e1envstretch->box(FL_ROUND_UP_BOX); + e1envstretch->color(FL_BACKGROUND_COLOR); + e1envstretch->selection_color(FL_INACTIVE_COLOR); + e1envstretch->labeltype(FL_NORMAL_LABEL); + e1envstretch->labelfont(0); + e1envstretch->labelsize(10); + e1envstretch->labelcolor(FL_FOREGROUND_COLOR); + e1envstretch->maximum(127); + e1envstretch->step(1); + e1envstretch->callback((Fl_Callback*)cb_e1envstretch); + e1envstretch->align(FL_ALIGN_BOTTOM); + e1envstretch->when(FL_WHEN_CHANGED); + o->value(env->Penvstretch); + } // WidgetPDial* e1envstretch + { Fl_Button* o = new Fl_Button(185, 5, 15, 15, "E"); + o->tooltip("Envelope window"); + o->box(FL_PLASTIC_UP_BOX); + o->labelfont(1); + o->labelsize(10); + o->callback((Fl_Callback*)cb_E); + } // Fl_Button* o + { Fl_Check_Button* o = e1linearenvelope = new Fl_Check_Button(180, 20, 15, 15, "L"); + e1linearenvelope->tooltip("The evelope is linear"); + e1linearenvelope->down_box(FL_DOWN_BOX); + e1linearenvelope->labelsize(10); + e1linearenvelope->callback((Fl_Callback*)cb_e1linearenvelope); + e1linearenvelope->align(FL_ALIGN_LEFT); + o->value(env->Plinearenvelope); + } // Fl_Check_Button* e1linearenvelope + { Fl_Button* o = new Fl_Button(150, 5, 15, 15, "C"); + o->box(FL_THIN_UP_BOX); + o->color((Fl_Color)179); + o->labelfont(1); + o->labelsize(10); + o->labelcolor(FL_BACKGROUND2_COLOR); + o->callback((Fl_Callback*)cb_C1); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(167, 5, 15, 15, "P"); + o->box(FL_THIN_UP_BOX); + o->color((Fl_Color)179); + o->labelfont(1); + o->labelsize(10); + o->labelcolor(FL_BACKGROUND2_COLOR); + o->callback((Fl_Callback*)cb_P1); + } // Fl_Button* o + o->end(); + } // Fl_Group* o + envADSR->end(); + } // Fl_Group* envADSR + return envADSR; +} + +Fl_Group* EnvelopeUI::make_ASR_window() { + { envASR = new Fl_Group(0, 0, 210, 70); + envASR->box(FL_FLAT_BOX); + envASR->color(FL_BACKGROUND_COLOR); + envASR->selection_color(FL_BACKGROUND_COLOR); + envASR->labeltype(FL_NO_LABEL); + envASR->labelfont(0); + envASR->labelsize(14); + envASR->labelcolor(FL_FOREGROUND_COLOR); + envASR->user_data((void*)(this)); + envASR->align(FL_ALIGN_TOP); + envASR->when(FL_WHEN_RELEASE); + { Fl_Group* o = new Fl_Group(0, 0, 210, 70, "Frequency Envelope"); + o->box(FL_PLASTIC_UP_BOX); + o->color(FL_CYAN); + o->labeltype(FL_ENGRAVED_LABEL); + o->labelsize(10); + o->align(FL_ALIGN_TOP|FL_ALIGN_INSIDE); + { WidgetPDial* o = e2aval = new WidgetPDial(5, 20, 30, 30, "A.val"); + e2aval->tooltip("Starting value"); + e2aval->box(FL_ROUND_UP_BOX); + e2aval->color(FL_BACKGROUND_COLOR); + e2aval->selection_color(FL_INACTIVE_COLOR); + e2aval->labeltype(FL_NORMAL_LABEL); + e2aval->labelfont(0); + e2aval->labelsize(10); + e2aval->labelcolor(FL_FOREGROUND_COLOR); + e2aval->maximum(127); + e2aval->step(1); + e2aval->callback((Fl_Callback*)cb_e2aval); + e2aval->align(FL_ALIGN_BOTTOM); + e2aval->when(FL_WHEN_CHANGED); + o->value(env->PA_val); + } // WidgetPDial* e2aval + { WidgetPDial* o = e2adt = new WidgetPDial(40, 20, 30, 30, "A.dt"); + e2adt->tooltip("Attack time"); + e2adt->box(FL_ROUND_UP_BOX); + e2adt->color(FL_BACKGROUND_COLOR); + e2adt->selection_color(FL_INACTIVE_COLOR); + e2adt->labeltype(FL_NORMAL_LABEL); + e2adt->labelfont(0); + e2adt->labelsize(10); + e2adt->labelcolor(FL_FOREGROUND_COLOR); + e2adt->maximum(127); + e2adt->step(1); + e2adt->callback((Fl_Callback*)cb_e2adt); + e2adt->align(FL_ALIGN_BOTTOM); + e2adt->when(FL_WHEN_CHANGED); + o->value(env->PA_dt); + } // WidgetPDial* e2adt + { WidgetPDial* o = e2rval = new WidgetPDial(110, 20, 30, 30, "R.val"); + e2rval->tooltip("Release value"); + e2rval->box(FL_ROUND_UP_BOX); + e2rval->color(FL_BACKGROUND_COLOR); + e2rval->selection_color(FL_INACTIVE_COLOR); + e2rval->labeltype(FL_NORMAL_LABEL); + e2rval->labelfont(0); + e2rval->labelsize(10); + e2rval->labelcolor(FL_FOREGROUND_COLOR); + e2rval->maximum(127); + e2rval->step(1); + e2rval->callback((Fl_Callback*)cb_e2rval); + e2rval->align(FL_ALIGN_BOTTOM); + e2rval->when(FL_WHEN_CHANGED); + o->value(env->PR_val); + } // WidgetPDial* e2rval + { WidgetPDial* o = e2rdt = new WidgetPDial(75, 20, 30, 30, "R.dt"); + e2rdt->tooltip("Release time"); + e2rdt->box(FL_ROUND_UP_BOX); + e2rdt->color(FL_BACKGROUND_COLOR); + e2rdt->selection_color(FL_INACTIVE_COLOR); + e2rdt->labeltype(FL_NORMAL_LABEL); + e2rdt->labelfont(0); + e2rdt->labelsize(10); + e2rdt->labelcolor(FL_FOREGROUND_COLOR); + e2rdt->maximum(127); + e2rdt->step(1); + e2rdt->callback((Fl_Callback*)cb_e2rdt); + e2rdt->align(FL_ALIGN_BOTTOM); + e2rdt->when(FL_WHEN_CHANGED); + o->value(env->PR_dt); + } // WidgetPDial* e2rdt + { WidgetPDial* o = e2envstretch = new WidgetPDial(145, 25, 25, 25, "Stretch"); + e2envstretch->tooltip("Envelope stretch (on lower notes makes the envelope longer)"); + e2envstretch->box(FL_ROUND_UP_BOX); + e2envstretch->color(FL_BACKGROUND_COLOR); + e2envstretch->selection_color(FL_INACTIVE_COLOR); + e2envstretch->labeltype(FL_NORMAL_LABEL); + e2envstretch->labelfont(0); + e2envstretch->labelsize(10); + e2envstretch->labelcolor(FL_FOREGROUND_COLOR); + e2envstretch->maximum(127); + e2envstretch->step(1); + e2envstretch->callback((Fl_Callback*)cb_e2envstretch); + e2envstretch->align(FL_ALIGN_BOTTOM); + e2envstretch->when(FL_WHEN_CHANGED); + o->value(env->Penvstretch); + } // WidgetPDial* e2envstretch + { Fl_Check_Button* o = e2forcedrelease = new Fl_Check_Button(180, 25, 15, 25, "frcR"); + e2forcedrelease->tooltip("Forced release"); + e2forcedrelease->down_box(FL_DOWN_BOX); + e2forcedrelease->labelsize(10); + e2forcedrelease->callback((Fl_Callback*)cb_e2forcedrelease); + e2forcedrelease->align(FL_ALIGN_BOTTOM_LEFT); + o->value(env->Pforcedrelease); + } // Fl_Check_Button* e2forcedrelease + { Fl_Button* o = new Fl_Button(155, 5, 15, 15, "C"); + o->box(FL_THIN_UP_BOX); + o->color((Fl_Color)179); + o->labelfont(1); + o->labelsize(10); + o->labelcolor(FL_BACKGROUND2_COLOR); + o->callback((Fl_Callback*)cb_C2); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(172, 5, 15, 15, "P"); + o->box(FL_THIN_UP_BOX); + o->color((Fl_Color)179); + o->labelfont(1); + o->labelsize(10); + o->labelcolor(FL_BACKGROUND2_COLOR); + o->callback((Fl_Callback*)cb_P2); + } // Fl_Button* o + o->end(); + } // Fl_Group* o + { Fl_Button* o = new Fl_Button(190, 5, 15, 15, "E"); + o->tooltip("Envelope window"); + o->box(FL_PLASTIC_UP_BOX); + o->labelfont(1); + o->labelsize(10); + o->callback((Fl_Callback*)cb_E1); + } // Fl_Button* o + envASR->end(); + } // Fl_Group* envASR + return envASR; +} + +Fl_Group* EnvelopeUI::make_ADSRfilter_window() { + { envADSRfilter = new Fl_Group(0, 0, 275, 70); + envADSRfilter->box(FL_FLAT_BOX); + envADSRfilter->color(FL_LIGHT1); + envADSRfilter->selection_color(FL_BACKGROUND_COLOR); + envADSRfilter->labeltype(FL_NO_LABEL); + envADSRfilter->labelfont(1); + envADSRfilter->labelsize(14); + envADSRfilter->labelcolor(FL_FOREGROUND_COLOR); + envADSRfilter->user_data((void*)(this)); + envADSRfilter->align(FL_ALIGN_TOP); + envADSRfilter->when(FL_WHEN_RELEASE); + { Fl_Group* o = new Fl_Group(0, 0, 275, 70, "Filter Envelope"); + o->box(FL_PLASTIC_UP_BOX); + o->color(FL_CYAN); + o->labeltype(FL_ENGRAVED_LABEL); + o->labelsize(10); + o->align(FL_ALIGN_TOP|FL_ALIGN_INSIDE); + { WidgetPDial* o = e3aval = new WidgetPDial(5, 20, 30, 30, "A.val"); + e3aval->tooltip("Starting value"); + e3aval->box(FL_ROUND_UP_BOX); + e3aval->color(FL_BACKGROUND_COLOR); + e3aval->selection_color(FL_INACTIVE_COLOR); + e3aval->labeltype(FL_NORMAL_LABEL); + e3aval->labelfont(0); + e3aval->labelsize(10); + e3aval->labelcolor(FL_FOREGROUND_COLOR); + e3aval->maximum(127); + e3aval->step(1); + e3aval->callback((Fl_Callback*)cb_e3aval); + e3aval->align(FL_ALIGN_BOTTOM); + e3aval->when(FL_WHEN_CHANGED); + o->value(env->PA_val); + } // WidgetPDial* e3aval + { WidgetPDial* o = e3adt = new WidgetPDial(40, 20, 30, 30, "A.dt"); + e3adt->tooltip("Attack time"); + e3adt->box(FL_ROUND_UP_BOX); + e3adt->color(FL_BACKGROUND_COLOR); + e3adt->selection_color(FL_INACTIVE_COLOR); + e3adt->labeltype(FL_NORMAL_LABEL); + e3adt->labelfont(0); + e3adt->labelsize(10); + e3adt->labelcolor(FL_FOREGROUND_COLOR); + e3adt->maximum(127); + e3adt->step(1); + e3adt->callback((Fl_Callback*)cb_e3adt); + e3adt->align(FL_ALIGN_BOTTOM); + e3adt->when(FL_WHEN_CHANGED); + o->value(env->PA_dt); + } // WidgetPDial* e3adt + { WidgetPDial* o = e3dval = new WidgetPDial(75, 20, 30, 30, "D.val"); + e3dval->tooltip("decay value"); + e3dval->box(FL_ROUND_UP_BOX); + e3dval->color(FL_BACKGROUND_COLOR); + e3dval->selection_color(FL_INACTIVE_COLOR); + e3dval->labeltype(FL_NORMAL_LABEL); + e3dval->labelfont(0); + e3dval->labelsize(10); + e3dval->labelcolor(FL_FOREGROUND_COLOR); + e3dval->maximum(127); + e3dval->step(1); + e3dval->callback((Fl_Callback*)cb_e3dval); + e3dval->align(FL_ALIGN_BOTTOM); + e3dval->when(FL_WHEN_CHANGED); + o->value(env->PD_val); + } // WidgetPDial* e3dval + { WidgetPDial* o = e3ddt = new WidgetPDial(110, 20, 30, 30, "D.dt"); + e3ddt->tooltip("decay time"); + e3ddt->box(FL_ROUND_UP_BOX); + e3ddt->color(FL_BACKGROUND_COLOR); + e3ddt->selection_color(FL_INACTIVE_COLOR); + e3ddt->labeltype(FL_NORMAL_LABEL); + e3ddt->labelfont(0); + e3ddt->labelsize(10); + e3ddt->labelcolor(FL_FOREGROUND_COLOR); + e3ddt->maximum(127); + e3ddt->step(1); + e3ddt->callback((Fl_Callback*)cb_e3ddt); + e3ddt->align(FL_ALIGN_BOTTOM); + e3ddt->when(FL_WHEN_CHANGED); + o->value(env->PD_dt); + } // WidgetPDial* e3ddt + { WidgetPDial* o = e3rdt = new WidgetPDial(145, 20, 30, 30, "R.dt"); + e3rdt->tooltip("Release time"); + e3rdt->box(FL_ROUND_UP_BOX); + e3rdt->color(FL_BACKGROUND_COLOR); + e3rdt->selection_color(FL_INACTIVE_COLOR); + e3rdt->labeltype(FL_NORMAL_LABEL); + e3rdt->labelfont(0); + e3rdt->labelsize(10); + e3rdt->labelcolor(FL_FOREGROUND_COLOR); + e3rdt->maximum(127); + e3rdt->step(1); + e3rdt->callback((Fl_Callback*)cb_e3rdt); + e3rdt->align(FL_ALIGN_BOTTOM); + e3rdt->when(FL_WHEN_CHANGED); + o->value(env->PR_dt); + } // WidgetPDial* e3rdt + { WidgetPDial* o = e3rval = new WidgetPDial(180, 20, 30, 30, "R.val"); + e3rval->tooltip("Release value"); + e3rval->box(FL_ROUND_UP_BOX); + e3rval->color(FL_BACKGROUND_COLOR); + e3rval->selection_color(FL_INACTIVE_COLOR); + e3rval->labeltype(FL_NORMAL_LABEL); + e3rval->labelfont(0); + e3rval->labelsize(10); + e3rval->labelcolor(FL_FOREGROUND_COLOR); + e3rval->maximum(127); + e3rval->step(1); + e3rval->callback((Fl_Callback*)cb_e3rval); + e3rval->align(FL_ALIGN_BOTTOM); + e3rval->when(FL_WHEN_CHANGED); + o->value(env->PR_val); + } // WidgetPDial* e3rval + { WidgetPDial* o = e3envstretch = new WidgetPDial(215, 25, 25, 25, "Stretch"); + e3envstretch->tooltip("Envelope stretch (on lower notes makes the envelope longer)"); + e3envstretch->box(FL_ROUND_UP_BOX); + e3envstretch->color(FL_BACKGROUND_COLOR); + e3envstretch->selection_color(FL_INACTIVE_COLOR); + e3envstretch->labeltype(FL_NORMAL_LABEL); + e3envstretch->labelfont(0); + e3envstretch->labelsize(10); + e3envstretch->labelcolor(FL_FOREGROUND_COLOR); + e3envstretch->maximum(127); + e3envstretch->step(1); + e3envstretch->callback((Fl_Callback*)cb_e3envstretch); + e3envstretch->align(FL_ALIGN_BOTTOM); + e3envstretch->when(FL_WHEN_CHANGED); + o->value(env->Penvstretch); + } // WidgetPDial* e3envstretch + { Fl_Check_Button* o = e3forcedrelease = new Fl_Check_Button(250, 30, 15, 20, "frcR"); + e3forcedrelease->tooltip("Forced Relase"); + e3forcedrelease->down_box(FL_DOWN_BOX); + e3forcedrelease->labelsize(10); + e3forcedrelease->callback((Fl_Callback*)cb_e3forcedrelease); + e3forcedrelease->align(FL_ALIGN_BOTTOM_LEFT); + o->value(env->Pforcedrelease); + } // Fl_Check_Button* e3forcedrelease + { Fl_Button* o = new Fl_Button(255, 5, 15, 15, "E"); + o->box(FL_PLASTIC_UP_BOX); + o->labelfont(1); + o->labelsize(10); + o->callback((Fl_Callback*)cb_E2); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(220, 5, 15, 15, "C"); + o->box(FL_THIN_UP_BOX); + o->color((Fl_Color)179); + o->labelfont(1); + o->labelsize(10); + o->labelcolor(FL_BACKGROUND2_COLOR); + o->callback((Fl_Callback*)cb_C3); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(237, 5, 15, 15, "P"); + o->box(FL_THIN_UP_BOX); + o->color((Fl_Color)179); + o->labelfont(1); + o->labelsize(10); + o->labelcolor(FL_BACKGROUND2_COLOR); + o->callback((Fl_Callback*)cb_P3); + } // Fl_Button* o + o->end(); + } // Fl_Group* o + envADSRfilter->end(); + } // Fl_Group* envADSRfilter + return envADSRfilter; +} + +Fl_Group* EnvelopeUI::make_ASRbw_window() { + { envASRbw = new Fl_Group(0, 0, 210, 70); + envASRbw->box(FL_FLAT_BOX); + envASRbw->color(FL_BACKGROUND_COLOR); + envASRbw->selection_color(FL_BACKGROUND_COLOR); + envASRbw->labeltype(FL_NO_LABEL); + envASRbw->labelfont(0); + envASRbw->labelsize(14); + envASRbw->labelcolor(FL_FOREGROUND_COLOR); + envASRbw->user_data((void*)(this)); + envASRbw->align(FL_ALIGN_TOP); + envASRbw->when(FL_WHEN_RELEASE); + { Fl_Group* o = new Fl_Group(0, 0, 210, 70, "BandWidth Envelope"); + o->box(FL_PLASTIC_UP_BOX); + o->color(FL_CYAN); + o->labeltype(FL_ENGRAVED_LABEL); + o->labelsize(10); + o->align(FL_ALIGN_TOP|FL_ALIGN_INSIDE); + { WidgetPDial* o = e4aval = new WidgetPDial(5, 20, 30, 30, "A.val"); + e4aval->tooltip("Starting value"); + e4aval->box(FL_ROUND_UP_BOX); + e4aval->color(FL_BACKGROUND_COLOR); + e4aval->selection_color(FL_INACTIVE_COLOR); + e4aval->labeltype(FL_NORMAL_LABEL); + e4aval->labelfont(0); + e4aval->labelsize(10); + e4aval->labelcolor(FL_FOREGROUND_COLOR); + e4aval->maximum(127); + e4aval->step(1); + e4aval->callback((Fl_Callback*)cb_e4aval); + e4aval->align(FL_ALIGN_BOTTOM); + e4aval->when(FL_WHEN_CHANGED); + o->value(env->PA_val); + } // WidgetPDial* e4aval + { WidgetPDial* o = e4adt = new WidgetPDial(40, 20, 30, 30, "A.dt"); + e4adt->tooltip("Attack time"); + e4adt->box(FL_ROUND_UP_BOX); + e4adt->color(FL_BACKGROUND_COLOR); + e4adt->selection_color(FL_INACTIVE_COLOR); + e4adt->labeltype(FL_NORMAL_LABEL); + e4adt->labelfont(0); + e4adt->labelsize(10); + e4adt->labelcolor(FL_FOREGROUND_COLOR); + e4adt->maximum(127); + e4adt->step(1); + e4adt->callback((Fl_Callback*)cb_e4adt); + e4adt->align(FL_ALIGN_BOTTOM); + e4adt->when(FL_WHEN_CHANGED); + o->value(env->PA_dt); + } // WidgetPDial* e4adt + { WidgetPDial* o = e4rval = new WidgetPDial(110, 20, 30, 30, "R.val"); + e4rval->tooltip("Release value"); + e4rval->box(FL_ROUND_UP_BOX); + e4rval->color(FL_BACKGROUND_COLOR); + e4rval->selection_color(FL_INACTIVE_COLOR); + e4rval->labeltype(FL_NORMAL_LABEL); + e4rval->labelfont(0); + e4rval->labelsize(10); + e4rval->labelcolor(FL_FOREGROUND_COLOR); + e4rval->maximum(127); + e4rval->step(1); + e4rval->callback((Fl_Callback*)cb_e4rval); + e4rval->align(FL_ALIGN_BOTTOM); + e4rval->when(FL_WHEN_CHANGED); + o->value(env->PR_val); + } // WidgetPDial* e4rval + { WidgetPDial* o = e4rdt = new WidgetPDial(75, 20, 30, 30, "R.dt"); + e4rdt->tooltip("Release time"); + e4rdt->box(FL_ROUND_UP_BOX); + e4rdt->color(FL_BACKGROUND_COLOR); + e4rdt->selection_color(FL_INACTIVE_COLOR); + e4rdt->labeltype(FL_NORMAL_LABEL); + e4rdt->labelfont(0); + e4rdt->labelsize(10); + e4rdt->labelcolor(FL_FOREGROUND_COLOR); + e4rdt->maximum(127); + e4rdt->step(1); + e4rdt->callback((Fl_Callback*)cb_e4rdt); + e4rdt->align(FL_ALIGN_BOTTOM); + e4rdt->when(FL_WHEN_CHANGED); + o->value(env->PR_dt); + } // WidgetPDial* e4rdt + { WidgetPDial* o = e4envstretch = new WidgetPDial(145, 25, 25, 25, "Stretch"); + e4envstretch->tooltip("Envelope stretch (on lower notes makes the envelope longer)"); + e4envstretch->box(FL_ROUND_UP_BOX); + e4envstretch->color(FL_BACKGROUND_COLOR); + e4envstretch->selection_color(FL_INACTIVE_COLOR); + e4envstretch->labeltype(FL_NORMAL_LABEL); + e4envstretch->labelfont(0); + e4envstretch->labelsize(10); + e4envstretch->labelcolor(FL_FOREGROUND_COLOR); + e4envstretch->maximum(127); + e4envstretch->step(1); + e4envstretch->callback((Fl_Callback*)cb_e4envstretch); + e4envstretch->align(FL_ALIGN_BOTTOM); + e4envstretch->when(FL_WHEN_CHANGED); + o->value(env->Penvstretch); + } // WidgetPDial* e4envstretch + { Fl_Check_Button* o = e4forcedrelease = new Fl_Check_Button(180, 25, 15, 25, "frcR"); + e4forcedrelease->tooltip("Forced release"); + e4forcedrelease->down_box(FL_DOWN_BOX); + e4forcedrelease->labelsize(10); + e4forcedrelease->callback((Fl_Callback*)cb_e4forcedrelease); + e4forcedrelease->align(FL_ALIGN_BOTTOM_LEFT); + o->value(env->Pforcedrelease); + } // Fl_Check_Button* e4forcedrelease + { Fl_Button* o = new Fl_Button(155, 5, 15, 15, "C"); + o->box(FL_THIN_UP_BOX); + o->color((Fl_Color)179); + o->labelfont(1); + o->labelsize(10); + o->labelcolor(FL_BACKGROUND2_COLOR); + o->callback((Fl_Callback*)cb_C4); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(172, 5, 15, 15, "P"); + o->box(FL_THIN_UP_BOX); + o->color((Fl_Color)179); + o->labelfont(1); + o->labelsize(10); + o->labelcolor(FL_BACKGROUND2_COLOR); + o->callback((Fl_Callback*)cb_P4); + } // Fl_Button* o + o->end(); + } // Fl_Group* o + { Fl_Button* o = new Fl_Button(190, 5, 15, 15, "E"); + o->box(FL_PLASTIC_UP_BOX); + o->labelfont(1); + o->labelsize(10); + o->callback((Fl_Callback*)cb_E3); + } // Fl_Button* o + envASRbw->end(); + } // Fl_Group* envASRbw + return envASRbw; +} + +Fl_Group* EnvelopeUI::make_free_window() { + { envfree = new Fl_Group(0, 0, 205, 70); + envfree->box(FL_FLAT_BOX); + envfree->color(FL_LIGHT1); + envfree->selection_color(FL_BACKGROUND_COLOR); + envfree->labeltype(FL_NO_LABEL); + envfree->labelfont(1); + envfree->labelsize(14); + envfree->labelcolor(FL_FOREGROUND_COLOR); + envfree->user_data((void*)(this)); + envfree->align(FL_ALIGN_TOP); + envfree->when(FL_WHEN_RELEASE); + { envfreegroup = new Fl_Group(0, 0, 205, 70, "Amplitude Envelope"); + envfreegroup->box(FL_PLASTIC_UP_BOX); + envfreegroup->color(FL_CYAN); + envfreegroup->labeltype(FL_ENGRAVED_LABEL); + envfreegroup->labelsize(10); + envfreegroup->align(FL_ALIGN_TOP|FL_ALIGN_INSIDE); + { EnvelopeFreeEdit* o = freeeditsmall = new EnvelopeFreeEdit(5, 20, 195, 45, "Envelope"); + freeeditsmall->box(FL_FLAT_BOX); + freeeditsmall->color(FL_FOREGROUND_COLOR); + freeeditsmall->selection_color(FL_BACKGROUND_COLOR); + freeeditsmall->labeltype(FL_NORMAL_LABEL); + freeeditsmall->labelfont(0); + freeeditsmall->labelsize(14); + freeeditsmall->labelcolor(FL_FOREGROUND_COLOR); + freeeditsmall->callback((Fl_Callback*)cb_freeeditsmall); + freeeditsmall->align(FL_ALIGN_CENTER); + freeeditsmall->when(FL_WHEN_RELEASE); + Fl_Group::current()->resizable(freeeditsmall); + o->init(env); + } // EnvelopeFreeEdit* freeeditsmall + { Fl_Button* o = new Fl_Button(185, 5, 15, 15, "E"); + o->box(FL_PLASTIC_UP_BOX); + o->labelfont(1); + o->labelsize(10); + o->callback((Fl_Callback*)cb_E4); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(150, 5, 15, 15, "C"); + o->box(FL_THIN_UP_BOX); + o->color((Fl_Color)179); + o->labelfont(1); + o->labelsize(10); + o->labelcolor(FL_BACKGROUND2_COLOR); + o->callback((Fl_Callback*)cb_C5); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(167, 5, 15, 15, "P"); + o->box(FL_THIN_UP_BOX); + o->color((Fl_Color)179); + o->labelfont(1); + o->labelsize(10); + o->labelcolor(FL_BACKGROUND2_COLOR); + o->callback((Fl_Callback*)cb_P5); + } // Fl_Button* o + envfreegroup->end(); + Fl_Group::current()->resizable(envfreegroup); + } // Fl_Group* envfreegroup + envfree->end(); + } // Fl_Group* envfree + return envfree; +} + +void EnvelopeUI::init(EnvelopeParams *env_) { + env=env_; +make_ADSR_window(); +make_ASR_window(); +make_ADSRfilter_window(); +make_ASRbw_window(); +make_free_window(); + +make_freemode_edit_window(); + +envwindow=NULL; +if (env->Envmode==3) envfreegroup->label("Frequency Envelope"); +if (env->Envmode==4) envfreegroup->label("Filter Envelope"); +if (env->Envmode==5) envfreegroup->label("Bandwidth Envelope"); + +freemodeeditwindow->label(this->label()); + + +freeeditsmall->setpair(freeedit); +freeedit->setpair(freeeditsmall); + + +refresh(); +} + +void EnvelopeUI::reinit() { + if (env->Pfreemode!=0){ + int answer=fl_choice("Disable the free mode of the Envelope?","No","Yes",NULL); + if (env->Pfreemode!=0) freemodebutton->value(1); + else freemodebutton->value(0); + if (answer==0) return; +}; + +if (env->Pfreemode==0) env->Pfreemode=1; + else env->Pfreemode=0; + +hide(); +int winx=freemodeeditwindow->x(); +int winy=freemodeeditwindow->y(); + +freemodeeditwindow->hide(); + +envwindow->hide(); +Fl_Group *par=envwindow->parent(); +par->hide(); + + +refresh(); +envwindow->show(); +par->redraw(); + +par->show(); +show(); +freemodeeditwindow->position(winx,winy); +freemodeeditwindow->show(); + +if (env->Pfreemode!=0) { + freemodebutton->value(1); + addpoint->show(); + deletepoint->show(); + forcedreleasecheck->show(); +}else{ + freemodebutton->value(0); + addpoint->hide(); + deletepoint->hide(); + forcedreleasecheck->hide(); +}; +} + +void EnvelopeUI::refresh() { + freemodebutton->value(env->Pfreemode); + +sustaincounter->value(env->Penvsustain); +if (env->Pfreemode==0) sustaincounter->hide(); + else sustaincounter->show(); +sustaincounter->maximum(env->Penvpoints-2); + +envstretchdial->value(env->Penvstretch); +if (env->Pfreemode==0) envstretchdial->hide(); + else envstretchdial->show(); + +linearenvelopecheck->value(env->Plinearenvelope); +if ((env->Pfreemode==0)||(env->Envmode>2)) linearenvelopecheck->hide(); + else linearenvelopecheck->show(); + +forcedreleasecheck->value(env->Pforcedrelease); +if (env->Pfreemode==0) forcedreleasecheck->hide(); + +freeedit->redraw(); + + +if (env->Pfreemode==0){ + switch(env->Envmode){ + case(1): + case(2): + e1adt->value(env->PA_dt); + e1ddt->value(env->PD_dt); + e1sval->value(env->PS_val); + e1rdt->value(env->PR_dt); + e1envstretch->value(env->Penvstretch); + e1linearenvelope->value(env->Plinearenvelope); + e1forcedrelease->value(env->Pforcedrelease); + break; + case(3): + e2aval->value(env->PA_val); + e2adt->value(env->PA_dt); + e2rdt->value(env->PR_dt); + e2rval->value(env->PR_val); + e2envstretch->value(env->Penvstretch); + e2forcedrelease->value(env->Pforcedrelease); + break; + case(4): + e3aval->value(env->PA_val); + e3adt->value(env->PA_dt); + e3dval->value(env->PD_val); + e3ddt->value(env->PD_dt); + e3rdt->value(env->PR_dt); + e3rval->value(env->PR_val); + e3envstretch->value(env->Penvstretch); + e3forcedrelease->value(env->Pforcedrelease); + break; + case(5): + e4aval->value(env->PA_val); + e4adt->value(env->PA_dt); + e4rdt->value(env->PR_dt); + e4rval->value(env->PR_val); + e4envstretch->value(env->Penvstretch); + e4forcedrelease->value(env->Pforcedrelease); + break; + default: + break; + }; +}else{ + envfree->redraw(); +}; + + +envADSR->hide(); +envASR->hide(); +envADSRfilter->hide(); +envASRbw->hide(); +envfree->hide(); + +if (env->Pfreemode==0){ + switch(env->Envmode){ + case(1): + case(2): + envwindow=envADSR; + break; + case(3): + envwindow=envASR; + break; + case(4): + envwindow=envADSRfilter; + break; + case(5): + envwindow=envASRbw; + break; + default: + break; + }; +}else{ + envwindow=envfree; +}; + +envwindow->resize(this->x(),this->y(),this->w(),this->h()); + +envwindow->show(); +} diff --git a/plugins/zynaddsubfx/src/UI/EnvelopeUI.fl b/plugins/zynaddsubfx/src/UI/EnvelopeUI.fl new file mode 100644 index 000000000..eef5ad643 --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/EnvelopeUI.fl @@ -0,0 +1,851 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0106 +header_name {.h} +code_name {.cc} +decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} + +decl {//License: GNU GPL version 2 or later} {} + +decl {\#include "WidgetPDial.h"} {public +} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include "../globals.h"} {public +} + +decl {\#include } {public +} + +decl {\#include "../Params/EnvelopeParams.h"} {public +} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include "PresetsUI.h"} {public +} + +class EnvelopeFreeEdit {: {public Fl_Box} +} { + Function {EnvelopeFreeEdit(int x,int y, int w, int h, const char *label=0):Fl_Box(x,y,w,h,label)} {} { + code {env=NULL; +pair=NULL;} {} + } + Function {init(EnvelopeParams *env_)} {} { + code {env=env_; +oldx=-1; +currentpoint=-1; +cpx=0; +lastpoint=-1;} {} + } + Function {setpair(Fl_Box *pair_)} {} { + code {pair=pair_;} {} + } + Function {getpointx(int n)} {return_type int + } { + code {int lx=w()-10; +int npoints=env->Penvpoints; + +float sum=0; +for (int i=1;igetdt(i)+1; + +float sumbefore=0;//the sum of all points before the computed point +for (int i=1;i<=n;i++) sumbefore+=env->getdt(i)+1; + +return((int) (sumbefore/(REALTYPE) sum*lx));} {} + } + Function {getpointy(int n)} {return_type int + } { + code {int ly=h()-10; + +return((int) ((1.0-env->Penvval[n]/127.0)*ly));} {} + } + Function {getnearest(int x,int y)} {return_type int + } { + code {x-=5;y-=5; + +int nearestpoint=0; +int nearestval=1000000;//a big value +for (int i=0;iPenvpoints;i++){ + int distance=abs(x-getpointx(i))+abs(y-getpointy(i)); + if (distancePfreemode==0) env->converttofree(); +int npoints=env->Penvpoints; + +if (active_r()) fl_color(FL_BLACK); + else fl_color(90,90,90); +if (!active_r()) currentpoint=-1; + +fl_rectf(ox,oy,lx,ly); + +ox+=5;oy+=5;lx-=10;ly-=10; + +//draw the lines +fl_color(FL_GRAY); + +fl_line_style(FL_SOLID); +fl_line(ox+2,oy+ly/2,ox+lx-2,oy+ly/2); + +//draws the evelope points and lines +Fl_Color alb=FL_WHITE; +if (!active_r()) alb=fl_rgb_color(180,180,180); +fl_color(alb); +int oldxx=0,xx=0,oldyy=0,yy=getpointy(0); +fl_rectf(ox-3,oy+yy-3,6,6); +for (int i=1;i=0){ + fl_color(FL_CYAN); + fl_rectf(ox+getpointx(lastpoint)-5,oy+getpointy(lastpoint)-5,10,10); +}; + +//draw the sustain position +if (env->Penvsustain>0){ + fl_color(FL_YELLOW); + xx=getpointx(env->Penvsustain); + fl_line(ox+xx,oy+0,ox+xx,oy+ly); +}; + +//Show the envelope duration and the current line duration +fl_font(FL_HELVETICA|FL_BOLD,10); +float time=0.0; +if (currentpoint<=0){ + fl_color(alb); + for (int i=1;igetdt(i); +} else { + fl_color(255,0,0); + time=env->getdt(currentpoint); +}; +char tmpstr[20]; +if (time<1000.0) snprintf((char *)&tmpstr,20,"%.1fms",time); + else snprintf((char *)&tmpstr,20,"%.2fs",time/1000.0); +fl_draw(tmpstr,ox+lx-20,oy+ly-10,20,10,FL_ALIGN_RIGHT,NULL,0);} {} + } + Function {handle(int event)} {return_type int + } { + code {int x_=Fl::event_x()-x(); +int y_=Fl::event_y()-y(); + +if (event==FL_PUSH) { + currentpoint=getnearest(x_,y_); + cpx=x_; + cpdt=env->Penvdt[currentpoint]; + lastpoint=currentpoint; + redraw(); + if (pair!=NULL) pair->redraw(); +}; + +if (event==FL_RELEASE){ + currentpoint=-1; + redraw(); + if (pair!=NULL) pair->redraw(); +}; + +if ((event==FL_DRAG)&&(currentpoint>=0)){ + int ny=127-(int) (y_*127.0/h()); + if (ny<0) ny=0;if (ny>127) ny=127; + env->Penvval[currentpoint]=ny; + + int dx=(int)((x_-cpx)*0.1); + int newdt=cpdt+dx; + if (newdt<0) newdt=0;if (newdt>127) newdt=127; + if (currentpoint!=0) env->Penvdt[currentpoint]=newdt; + else env->Penvdt[currentpoint]=0; + + redraw(); + if (pair!=NULL) pair->redraw(); +}; + + +return(1);} {} + } + decl {Fl_Box *pair;} {} + decl {EnvelopeParams *env;} {} + decl {int oldx,oldy;} {} + decl {int currentpoint,cpx,cpdt;} {} + decl {int lastpoint;} {public + } +} + +class EnvelopeUI {: {public Fl_Group,PresetsUI_} +} { + Function {EnvelopeUI(int x,int y, int w, int h, const char *label=0):Fl_Group(x,y,w,h,label)} {} { + code {env=NULL; +freemodeeditwindow=NULL; +envADSR=NULL; +envASR=NULL; +envADSRfilter=NULL; +envASRbw=NULL; +envfree=NULL;} {} + } + Function {~EnvelopeUI()} {} { + code {envwindow->hide(); +hide(); +freemodeeditwindow->hide(); +delete (freemodeeditwindow);} {} + } + Function {make_freemode_edit_window()} {} { + Fl_Window freemodeeditwindow { + label Envelope + xywh {60 308 575 180} type Double hide + } { + Fl_Box freeedit { + label Envelope + xywh {5 5 565 145} box FLAT_BOX color 0 + code0 {o->init(env);} + class EnvelopeFreeEdit + } + Fl_Button addpoint { + label {Add point} + callback {int curpoint=freeedit->lastpoint; +if (curpoint<0) return; +//if (curpoint>=env->Penvpoints-1) return; +if (env->Penvpoints>=MAX_ENVELOPE_POINTS) return; + +for (int i=env->Penvpoints;i>=curpoint+1;i--){ + env->Penvdt[i]=env->Penvdt[i-1]; + env->Penvval[i]=env->Penvval[i-1]; +}; + +if (curpoint==0) { + env->Penvdt[1]=64; +}; + +env->Penvpoints++; +if (curpoint<=env->Penvsustain) env->Penvsustain++; + +freeedit->lastpoint+=1; +freeedit->redraw(); +envfree->redraw(); + +sustaincounter->value(env->Penvsustain); +sustaincounter->maximum(env->Penvpoints-2);} + xywh {115 155 80 20} box THIN_UP_BOX + code0 {if (env->Pfreemode==0) o->hide();} + } + Fl_Button deletepoint { + label {Delete point} + callback {int curpoint=freeedit->lastpoint; +if (curpoint<1) return; +if (curpoint>=env->Penvpoints-1) return; +if (env->Penvpoints<=3) return; + +for (int i=curpoint+1;iPenvpoints;i++){ + env->Penvdt[i-1]=env->Penvdt[i]; + env->Penvval[i-1]=env->Penvval[i]; +}; + +env->Penvpoints--; + +if (curpoint<=env->Penvsustain) env->Penvsustain--; + + +freeedit->lastpoint-=1; +freeedit->redraw(); +envfree->redraw(); + +sustaincounter->value(env->Penvsustain); +sustaincounter->maximum(env->Penvpoints-2);} + xywh {200 155 80 20} box THIN_UP_BOX + code0 {if (env->Pfreemode==0) o->hide();} + } + Fl_Light_Button freemodebutton { + label FreeMode + callback {reinit(); + +freeedit->lastpoint=-1; +freeedit->redraw();} + tooltip {Enable or disable the freemode} xywh {10 155 95 25} box PLASTIC_UP_BOX + } + Fl_Check_Button forcedreleasecheck { + label frcR + callback {env->Pforcedrelease=(int)o->value();} + tooltip {Forced Relase} xywh {410 165 40 15} down_box DOWN_BOX labelsize 10 + code0 {o->value(env->Pforcedrelease);} + code1 {if (env->Pfreemode==0) o->hide();} + } + Fl_Dial envstretchdial { + label {Str.} + callback {env->Penvstretch=(int)o->value();} + tooltip {Envelope stretch (on lower notes make the envelope longer)} xywh {380 155 25 25} box ROUND_UP_BOX labelsize 10 align 4 maximum 127 step 1 + code0 {o->value(env->Penvstretch);} + code1 {if (env->Pfreemode==0) o->hide();} + class WidgetPDial + } + Fl_Button {} { + label Close + callback {freemodeeditwindow->hide();} + xywh {510 155 60 25} box THIN_UP_BOX + } + Fl_Check_Button linearenvelopecheck { + label L + callback {env->Plinearenvelope=(int)o->value();} + tooltip {Linear Envelope} xywh {410 151 30 15} down_box DOWN_BOX labelsize 10 + code0 {o->value(env->Plinearenvelope);} + code1 {if ((env->Pfreemode==0)||(env->Envmode>2)) o->hide();} + } + Fl_Counter sustaincounter { + label Sust + callback {env->Penvsustain=(int) o->value(); +freeedit->redraw(); +envfree->redraw();} + tooltip {Sustain (0 is disabled)} xywh {315 155 40 15} type Simple labelsize 11 align 4 minimum 0 maximum 127 step 1 + code0 {o->value(env->Penvsustain);} + code1 {if (env->Pfreemode==0) o->hide();} + code2 {o->maximum(env->Penvpoints-2);} + } + Fl_Button {} { + label C + callback {presetsui->copy(env);} + xywh {465 160 15 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 10 labelcolor 7 + } + Fl_Button {} { + label P + callback {presetsui->paste(env,this);} + xywh {482 160 15 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 10 labelcolor 7 + } + } + } + Function {make_ADSR_window()} {} { + Fl_Window envADSR { + xywh {108 336 205 70} type Double color 50 labelfont 1 hide + class Fl_Group + } { + Fl_Group {} { + label {Amplitude Envelope} + xywh {0 0 205 70} box PLASTIC_UP_BOX color 223 labeltype ENGRAVED_LABEL labelsize 10 align 17 + } { + Fl_Dial e1adt { + label {A.dt} + callback {env->PA_dt=(int)o->value(); +freeedit->redraw();} + tooltip {Attack time} xywh {5 20 30 30} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + code0 {o->value(env->PA_dt);} + class WidgetPDial + } + Fl_Dial e1ddt { + label {D.dt} + callback {env->PD_dt=(int)o->value(); +freeedit->redraw();} + tooltip {Decay time} xywh {40 20 30 30} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + code0 {o->value(env->PD_dt);} + class WidgetPDial + } + Fl_Dial e1rdt { + label {R.dt} + callback {env->PR_dt=(int)o->value(); +freeedit->redraw();} + tooltip {Release time} xywh {110 20 30 30} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + code0 {o->value(env->PR_dt);} + class WidgetPDial + } + Fl_Dial e1sval { + label {S.val} + callback {env->PS_val=(int)o->value(); +freeedit->redraw();} + tooltip {Sustain value} xywh {75 20 30 30} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + code0 {o->value(env->PS_val);} + class WidgetPDial + } + Fl_Check_Button e1forcedrelease { + label frcR + callback {env->Pforcedrelease=(int)o->value();} + tooltip {Forced Relase} xywh {180 35 20 15} down_box DOWN_BOX labelsize 10 align 6 + code0 {o->value(env->Pforcedrelease);} + } + Fl_Dial e1envstretch { + label Stretch + callback {env->Penvstretch=(int)o->value();} + tooltip {Envelope stretch (on lower notes makes the envelope longer)} xywh {145 25 25 25} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + code0 {o->value(env->Penvstretch);} + class WidgetPDial + } + Fl_Button {} { + label E + callback {freemodeeditwindow->show();} + tooltip {Envelope window} xywh {185 5 15 15} box PLASTIC_UP_BOX labelfont 1 labelsize 10 + } + Fl_Check_Button e1linearenvelope { + label L + callback {env->Plinearenvelope=(int)o->value();} + tooltip {The evelope is linear} xywh {180 20 15 15} down_box DOWN_BOX labelsize 10 align 4 + code0 {o->value(env->Plinearenvelope);} + } + Fl_Button {} { + label C + callback {presetsui->copy(env);} + xywh {150 5 15 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 10 labelcolor 7 + } + Fl_Button {} { + label P + callback {presetsui->paste(env,this);} + xywh {167 5 15 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 10 labelcolor 7 + } + } + } + } + Function {make_ASR_window()} {} { + Fl_Window envASR { + xywh {71 320 210 70} type Double hide + class Fl_Group + } { + Fl_Group {} { + label {Frequency Envelope} + xywh {0 0 210 70} box PLASTIC_UP_BOX color 223 labeltype ENGRAVED_LABEL labelsize 10 align 17 + } { + Fl_Dial e2aval { + label {A.val} + callback {env->PA_val=(int)o->value(); +freeedit->redraw();} + tooltip {Starting value} xywh {5 20 30 30} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + code0 {o->value(env->PA_val);} + class WidgetPDial + } + Fl_Dial e2adt { + label {A.dt} + callback {env->PA_dt=(int)o->value(); +freeedit->redraw();} + tooltip {Attack time} xywh {40 20 30 30} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + code0 {o->value(env->PA_dt);} + class WidgetPDial + } + Fl_Dial e2rval { + label {R.val} + callback {env->PR_val=(int)o->value(); +freeedit->redraw();} + tooltip {Release value} xywh {110 20 30 30} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + code0 {o->value(env->PR_val);} + class WidgetPDial + } + Fl_Dial e2rdt { + label {R.dt} + callback {env->PR_dt=(int)o->value(); +freeedit->redraw();} + tooltip {Release time} xywh {75 20 30 30} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + code0 {o->value(env->PR_dt);} + class WidgetPDial + } + Fl_Dial e2envstretch { + label Stretch + callback {env->Penvstretch=(int)o->value();} + tooltip {Envelope stretch (on lower notes makes the envelope longer)} xywh {145 25 25 25} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + code0 {o->value(env->Penvstretch);} + class WidgetPDial + } + Fl_Check_Button e2forcedrelease { + label frcR + callback {env->Pforcedrelease=(int)o->value();} + tooltip {Forced release} xywh {180 25 15 25} down_box DOWN_BOX labelsize 10 align 6 + code0 {o->value(env->Pforcedrelease);} + } + Fl_Button {} { + label C + callback {presetsui->copy(env);} + xywh {155 5 15 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 10 labelcolor 7 + } + Fl_Button {} { + label P + callback {presetsui->paste(env,this);} + xywh {172 5 15 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 10 labelcolor 7 + } + } + Fl_Button {} { + label E + callback {freemodeeditwindow->show();} + tooltip {Envelope window} xywh {190 5 15 15} box PLASTIC_UP_BOX labelfont 1 labelsize 10 + } + } + } + Function {make_ADSRfilter_window()} {} { + Fl_Window envADSRfilter { + xywh {87 143 275 70} type Double color 50 labelfont 1 hide + class Fl_Group + } { + Fl_Group {} { + label {Filter Envelope} + xywh {0 0 275 70} box PLASTIC_UP_BOX color 223 labeltype ENGRAVED_LABEL labelsize 10 align 17 + } { + Fl_Dial e3aval { + label {A.val} + callback {env->PA_val=(int)o->value(); +freeedit->redraw();} + tooltip {Starting value} xywh {5 20 30 30} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + code0 {o->value(env->PA_val);} + class WidgetPDial + } + Fl_Dial e3adt { + label {A.dt} + callback {env->PA_dt=(int)o->value(); +freeedit->redraw();} + tooltip {Attack time} xywh {40 20 30 30} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + code0 {o->value(env->PA_dt);} + class WidgetPDial + } + Fl_Dial e3dval { + label {D.val} + callback {env->PD_val=(int)o->value(); +freeedit->redraw();} + tooltip {decay value} xywh {75 20 30 30} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + code0 {o->value(env->PD_val);} + class WidgetPDial + } + Fl_Dial e3ddt { + label {D.dt} + callback {env->PD_dt=(int)o->value(); +freeedit->redraw();} + tooltip {decay time} xywh {110 20 30 30} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + code0 {o->value(env->PD_dt);} + class WidgetPDial + } + Fl_Dial e3rdt { + label {R.dt} + callback {env->PR_dt=(int)o->value(); +freeedit->redraw();} + tooltip {Release time} xywh {145 20 30 30} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + code0 {o->value(env->PR_dt);} + class WidgetPDial + } + Fl_Dial e3rval { + label {R.val} + callback {env->PR_val=(int)o->value(); +freeedit->redraw();} + tooltip {Release value} xywh {180 20 30 30} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + code0 {o->value(env->PR_val);} + class WidgetPDial + } + Fl_Dial e3envstretch { + label Stretch + callback {env->Penvstretch=(int)o->value();} + tooltip {Envelope stretch (on lower notes makes the envelope longer)} xywh {215 25 25 25} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + code0 {o->value(env->Penvstretch);} + class WidgetPDial + } + Fl_Check_Button e3forcedrelease { + label frcR + callback {env->Pforcedrelease=(int)o->value();} + tooltip {Forced Relase} xywh {250 30 15 20} down_box DOWN_BOX labelsize 10 align 6 + code0 {o->value(env->Pforcedrelease);} + } + Fl_Button {} { + label E + callback {freemodeeditwindow->show();} + xywh {255 5 15 15} box PLASTIC_UP_BOX labelfont 1 labelsize 10 + } + Fl_Button {} { + label C + callback {presetsui->copy(env);} + xywh {220 5 15 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 10 labelcolor 7 + } + Fl_Button {} { + label P + callback {presetsui->paste(env,this);} + xywh {237 5 15 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 10 labelcolor 7 + } + } + } + } + Function {make_ASRbw_window()} {} { + Fl_Window envASRbw { + xywh {224 539 210 70} type Double hide + class Fl_Group + } { + Fl_Group {} { + label {BandWidth Envelope} + xywh {0 0 210 70} box PLASTIC_UP_BOX color 223 labeltype ENGRAVED_LABEL labelsize 10 align 17 + } { + Fl_Dial e4aval { + label {A.val} + callback {env->PA_val=(int)o->value(); +freeedit->redraw();} + tooltip {Starting value} xywh {5 20 30 30} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + code0 {o->value(env->PA_val);} + class WidgetPDial + } + Fl_Dial e4adt { + label {A.dt} + callback {env->PA_dt=(int)o->value(); +freeedit->redraw();} + tooltip {Attack time} xywh {40 20 30 30} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + code0 {o->value(env->PA_dt);} + class WidgetPDial + } + Fl_Dial e4rval { + label {R.val} + callback {env->PR_val=(int)o->value(); +freeedit->redraw();} + tooltip {Release value} xywh {110 20 30 30} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + code0 {o->value(env->PR_val);} + class WidgetPDial + } + Fl_Dial e4rdt { + label {R.dt} + callback {env->PR_dt=(int)o->value(); +freeedit->redraw();} + tooltip {Release time} xywh {75 20 30 30} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + code0 {o->value(env->PR_dt);} + class WidgetPDial + } + Fl_Dial e4envstretch { + label Stretch + callback {env->Penvstretch=(int)o->value();} + tooltip {Envelope stretch (on lower notes makes the envelope longer)} xywh {145 25 25 25} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + code0 {o->value(env->Penvstretch);} + class WidgetPDial + } + Fl_Check_Button e4forcedrelease { + label frcR + callback {env->Pforcedrelease=(int)o->value();} + tooltip {Forced release} xywh {180 25 15 25} down_box DOWN_BOX labelsize 10 align 6 + code0 {o->value(env->Pforcedrelease);} + } + Fl_Button {} { + label C + callback {presetsui->copy(env);} + xywh {155 5 15 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 10 labelcolor 7 + } + Fl_Button {} { + label P + callback {presetsui->paste(env,this);} + xywh {172 5 15 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 10 labelcolor 7 + } + } + Fl_Button {} { + label E + callback {freemodeeditwindow->show();} + xywh {190 5 15 15} box PLASTIC_UP_BOX labelfont 1 labelsize 10 + } + } + } + Function {make_free_window()} {} { + Fl_Window envfree { + xywh {373 413 205 70} type Double color 50 labelfont 1 hide resizable + class Fl_Group + } { + Fl_Group envfreegroup { + label {Amplitude Envelope} + xywh {0 0 205 70} box PLASTIC_UP_BOX color 223 labeltype ENGRAVED_LABEL labelsize 10 align 17 resizable + } { + Fl_Box freeeditsmall { + label Envelope + callback {envfree->redraw();} + xywh {5 20 195 45} box FLAT_BOX color 0 resizable + code0 {o->init(env);} + class EnvelopeFreeEdit + } + Fl_Button {} { + label E + callback {freemodeeditwindow->show();} + xywh {185 5 15 15} box PLASTIC_UP_BOX labelfont 1 labelsize 10 + } + Fl_Button {} { + label C + callback {presetsui->copy(env);} + xywh {150 5 15 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 10 labelcolor 7 + } + Fl_Button {} { + label P + callback {presetsui->paste(env,this);} + xywh {167 5 15 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 10 labelcolor 7 + } + } + } + } + Function {init(EnvelopeParams *env_)} {} { + code {env=env_; +make_ADSR_window(); +make_ASR_window(); +make_ADSRfilter_window(); +make_ASRbw_window(); +make_free_window(); + +make_freemode_edit_window(); + +envwindow=NULL; +if (env->Envmode==3) envfreegroup->label("Frequency Envelope"); +if (env->Envmode==4) envfreegroup->label("Filter Envelope"); +if (env->Envmode==5) envfreegroup->label("Bandwidth Envelope"); + +freemodeeditwindow->label(this->label()); + + +freeeditsmall->setpair(freeedit); +freeedit->setpair(freeeditsmall); + + +refresh();} {} + } + Function {reinit()} {} { + code {if (env->Pfreemode!=0){ + int answer=fl_choice("Disable the free mode of the Envelope?","No","Yes",NULL); + if (env->Pfreemode!=0) freemodebutton->value(1); + else freemodebutton->value(0); + if (answer==0) return; +}; + +if (env->Pfreemode==0) env->Pfreemode=1; + else env->Pfreemode=0; + +hide(); +int winx=freemodeeditwindow->x(); +int winy=freemodeeditwindow->y(); + +freemodeeditwindow->hide(); + +envwindow->hide(); +Fl_Group *par=envwindow->parent(); +par->hide(); + + +refresh(); +envwindow->show(); +par->redraw(); + +par->show(); +show(); +freemodeeditwindow->position(winx,winy); +freemodeeditwindow->show(); + +if (env->Pfreemode!=0) { + freemodebutton->value(1); + addpoint->show(); + deletepoint->show(); + forcedreleasecheck->show(); +}else{ + freemodebutton->value(0); + addpoint->hide(); + deletepoint->hide(); + forcedreleasecheck->hide(); +};} {selected + } + } + Function {refresh()} {} { + code {freemodebutton->value(env->Pfreemode); + +sustaincounter->value(env->Penvsustain); +if (env->Pfreemode==0) sustaincounter->hide(); + else sustaincounter->show(); +sustaincounter->maximum(env->Penvpoints-2); + +envstretchdial->value(env->Penvstretch); +if (env->Pfreemode==0) envstretchdial->hide(); + else envstretchdial->show(); + +linearenvelopecheck->value(env->Plinearenvelope); +if ((env->Pfreemode==0)||(env->Envmode>2)) linearenvelopecheck->hide(); + else linearenvelopecheck->show(); + +forcedreleasecheck->value(env->Pforcedrelease); +if (env->Pfreemode==0) forcedreleasecheck->hide(); + +freeedit->redraw(); + + +if (env->Pfreemode==0){ + switch(env->Envmode){ + case(1): + case(2): + e1adt->value(env->PA_dt); + e1ddt->value(env->PD_dt); + e1sval->value(env->PS_val); + e1rdt->value(env->PR_dt); + e1envstretch->value(env->Penvstretch); + e1linearenvelope->value(env->Plinearenvelope); + e1forcedrelease->value(env->Pforcedrelease); + break; + case(3): + e2aval->value(env->PA_val); + e2adt->value(env->PA_dt); + e2rdt->value(env->PR_dt); + e2rval->value(env->PR_val); + e2envstretch->value(env->Penvstretch); + e2forcedrelease->value(env->Pforcedrelease); + break; + case(4): + e3aval->value(env->PA_val); + e3adt->value(env->PA_dt); + e3dval->value(env->PD_val); + e3ddt->value(env->PD_dt); + e3rdt->value(env->PR_dt); + e3rval->value(env->PR_val); + e3envstretch->value(env->Penvstretch); + e3forcedrelease->value(env->Pforcedrelease); + break; + case(5): + e4aval->value(env->PA_val); + e4adt->value(env->PA_dt); + e4rdt->value(env->PR_dt); + e4rval->value(env->PR_val); + e4envstretch->value(env->Penvstretch); + e4forcedrelease->value(env->Pforcedrelease); + break; + default: + break; + }; +}else{ + envfree->redraw(); +}; + + +envADSR->hide(); +envASR->hide(); +envADSRfilter->hide(); +envASRbw->hide(); +envfree->hide(); + +if (env->Pfreemode==0){ + switch(env->Envmode){ + case(1): + case(2): + envwindow=envADSR; + break; + case(3): + envwindow=envASR; + break; + case(4): + envwindow=envADSRfilter; + break; + case(5): + envwindow=envASRbw; + break; + default: + break; + }; +}else{ + envwindow=envfree; +}; + +envwindow->resize(this->x(),this->y(),this->w(),this->h()); + +envwindow->show();} {} + } + decl {EnvelopeParams *env;} {} + decl {Fl_Group *envwindow;} {} +} diff --git a/plugins/zynaddsubfx/src/UI/EnvelopeUI.h b/plugins/zynaddsubfx/src/UI/EnvelopeUI.h new file mode 100644 index 000000000..670696091 --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/EnvelopeUI.h @@ -0,0 +1,280 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0109 + +#ifndef EnvelopeUI_h +#define EnvelopeUI_h +#include +#include "WidgetPDial.h" +#include +#include +#include "../globals.h" +#include +#include "../Params/EnvelopeParams.h" +#include +#include +#include +#include "PresetsUI.h" + +class EnvelopeFreeEdit : public Fl_Box { +public: + EnvelopeFreeEdit(int x,int y, int w, int h, const char *label=0); + void init(EnvelopeParams *env_); + void setpair(Fl_Box *pair_); + int getpointx(int n); + int getpointy(int n); + int getnearest(int x,int y); +private: + void draw(); +public: + int handle(int event); +private: + Fl_Box *pair; + EnvelopeParams *env; + int oldx,oldy; + int currentpoint,cpx,cpdt; +public: + int lastpoint; +}; +#include +#include +#include +#include +#include +#include + +class EnvelopeUI : public Fl_Group,PresetsUI_ { +public: + EnvelopeUI(int x,int y, int w, int h, const char *label=0); + ~EnvelopeUI(); + Fl_Double_Window* make_freemode_edit_window(); + Fl_Double_Window *freemodeeditwindow; + EnvelopeFreeEdit *freeedit; + Fl_Button *addpoint; +private: + void cb_addpoint_i(Fl_Button*, void*); + static void cb_addpoint(Fl_Button*, void*); +public: + Fl_Button *deletepoint; +private: + void cb_deletepoint_i(Fl_Button*, void*); + static void cb_deletepoint(Fl_Button*, void*); +public: + Fl_Light_Button *freemodebutton; +private: + void cb_freemodebutton_i(Fl_Light_Button*, void*); + static void cb_freemodebutton(Fl_Light_Button*, void*); +public: + Fl_Check_Button *forcedreleasecheck; +private: + void cb_forcedreleasecheck_i(Fl_Check_Button*, void*); + static void cb_forcedreleasecheck(Fl_Check_Button*, void*); +public: + WidgetPDial *envstretchdial; +private: + void cb_envstretchdial_i(WidgetPDial*, void*); + static void cb_envstretchdial(WidgetPDial*, void*); + void cb_Close_i(Fl_Button*, void*); + static void cb_Close(Fl_Button*, void*); +public: + Fl_Check_Button *linearenvelopecheck; +private: + void cb_linearenvelopecheck_i(Fl_Check_Button*, void*); + static void cb_linearenvelopecheck(Fl_Check_Button*, void*); +public: + Fl_Counter *sustaincounter; +private: + void cb_sustaincounter_i(Fl_Counter*, void*); + static void cb_sustaincounter(Fl_Counter*, void*); + void cb_C_i(Fl_Button*, void*); + static void cb_C(Fl_Button*, void*); + void cb_P_i(Fl_Button*, void*); + static void cb_P(Fl_Button*, void*); +public: + Fl_Group* make_ADSR_window(); + Fl_Group *envADSR; + WidgetPDial *e1adt; +private: + void cb_e1adt_i(WidgetPDial*, void*); + static void cb_e1adt(WidgetPDial*, void*); +public: + WidgetPDial *e1ddt; +private: + void cb_e1ddt_i(WidgetPDial*, void*); + static void cb_e1ddt(WidgetPDial*, void*); +public: + WidgetPDial *e1rdt; +private: + void cb_e1rdt_i(WidgetPDial*, void*); + static void cb_e1rdt(WidgetPDial*, void*); +public: + WidgetPDial *e1sval; +private: + void cb_e1sval_i(WidgetPDial*, void*); + static void cb_e1sval(WidgetPDial*, void*); +public: + Fl_Check_Button *e1forcedrelease; +private: + void cb_e1forcedrelease_i(Fl_Check_Button*, void*); + static void cb_e1forcedrelease(Fl_Check_Button*, void*); +public: + WidgetPDial *e1envstretch; +private: + void cb_e1envstretch_i(WidgetPDial*, void*); + static void cb_e1envstretch(WidgetPDial*, void*); + void cb_E_i(Fl_Button*, void*); + static void cb_E(Fl_Button*, void*); +public: + Fl_Check_Button *e1linearenvelope; +private: + void cb_e1linearenvelope_i(Fl_Check_Button*, void*); + static void cb_e1linearenvelope(Fl_Check_Button*, void*); + void cb_C1_i(Fl_Button*, void*); + static void cb_C1(Fl_Button*, void*); + void cb_P1_i(Fl_Button*, void*); + static void cb_P1(Fl_Button*, void*); +public: + Fl_Group* make_ASR_window(); + Fl_Group *envASR; + WidgetPDial *e2aval; +private: + void cb_e2aval_i(WidgetPDial*, void*); + static void cb_e2aval(WidgetPDial*, void*); +public: + WidgetPDial *e2adt; +private: + void cb_e2adt_i(WidgetPDial*, void*); + static void cb_e2adt(WidgetPDial*, void*); +public: + WidgetPDial *e2rval; +private: + void cb_e2rval_i(WidgetPDial*, void*); + static void cb_e2rval(WidgetPDial*, void*); +public: + WidgetPDial *e2rdt; +private: + void cb_e2rdt_i(WidgetPDial*, void*); + static void cb_e2rdt(WidgetPDial*, void*); +public: + WidgetPDial *e2envstretch; +private: + void cb_e2envstretch_i(WidgetPDial*, void*); + static void cb_e2envstretch(WidgetPDial*, void*); +public: + Fl_Check_Button *e2forcedrelease; +private: + void cb_e2forcedrelease_i(Fl_Check_Button*, void*); + static void cb_e2forcedrelease(Fl_Check_Button*, void*); + void cb_C2_i(Fl_Button*, void*); + static void cb_C2(Fl_Button*, void*); + void cb_P2_i(Fl_Button*, void*); + static void cb_P2(Fl_Button*, void*); + void cb_E1_i(Fl_Button*, void*); + static void cb_E1(Fl_Button*, void*); +public: + Fl_Group* make_ADSRfilter_window(); + Fl_Group *envADSRfilter; + WidgetPDial *e3aval; +private: + void cb_e3aval_i(WidgetPDial*, void*); + static void cb_e3aval(WidgetPDial*, void*); +public: + WidgetPDial *e3adt; +private: + void cb_e3adt_i(WidgetPDial*, void*); + static void cb_e3adt(WidgetPDial*, void*); +public: + WidgetPDial *e3dval; +private: + void cb_e3dval_i(WidgetPDial*, void*); + static void cb_e3dval(WidgetPDial*, void*); +public: + WidgetPDial *e3ddt; +private: + void cb_e3ddt_i(WidgetPDial*, void*); + static void cb_e3ddt(WidgetPDial*, void*); +public: + WidgetPDial *e3rdt; +private: + void cb_e3rdt_i(WidgetPDial*, void*); + static void cb_e3rdt(WidgetPDial*, void*); +public: + WidgetPDial *e3rval; +private: + void cb_e3rval_i(WidgetPDial*, void*); + static void cb_e3rval(WidgetPDial*, void*); +public: + WidgetPDial *e3envstretch; +private: + void cb_e3envstretch_i(WidgetPDial*, void*); + static void cb_e3envstretch(WidgetPDial*, void*); +public: + Fl_Check_Button *e3forcedrelease; +private: + void cb_e3forcedrelease_i(Fl_Check_Button*, void*); + static void cb_e3forcedrelease(Fl_Check_Button*, void*); + void cb_E2_i(Fl_Button*, void*); + static void cb_E2(Fl_Button*, void*); + void cb_C3_i(Fl_Button*, void*); + static void cb_C3(Fl_Button*, void*); + void cb_P3_i(Fl_Button*, void*); + static void cb_P3(Fl_Button*, void*); +public: + Fl_Group* make_ASRbw_window(); + Fl_Group *envASRbw; + WidgetPDial *e4aval; +private: + void cb_e4aval_i(WidgetPDial*, void*); + static void cb_e4aval(WidgetPDial*, void*); +public: + WidgetPDial *e4adt; +private: + void cb_e4adt_i(WidgetPDial*, void*); + static void cb_e4adt(WidgetPDial*, void*); +public: + WidgetPDial *e4rval; +private: + void cb_e4rval_i(WidgetPDial*, void*); + static void cb_e4rval(WidgetPDial*, void*); +public: + WidgetPDial *e4rdt; +private: + void cb_e4rdt_i(WidgetPDial*, void*); + static void cb_e4rdt(WidgetPDial*, void*); +public: + WidgetPDial *e4envstretch; +private: + void cb_e4envstretch_i(WidgetPDial*, void*); + static void cb_e4envstretch(WidgetPDial*, void*); +public: + Fl_Check_Button *e4forcedrelease; +private: + void cb_e4forcedrelease_i(Fl_Check_Button*, void*); + static void cb_e4forcedrelease(Fl_Check_Button*, void*); + void cb_C4_i(Fl_Button*, void*); + static void cb_C4(Fl_Button*, void*); + void cb_P4_i(Fl_Button*, void*); + static void cb_P4(Fl_Button*, void*); + void cb_E3_i(Fl_Button*, void*); + static void cb_E3(Fl_Button*, void*); +public: + Fl_Group* make_free_window(); + Fl_Group *envfree; + Fl_Group *envfreegroup; + EnvelopeFreeEdit *freeeditsmall; +private: + void cb_freeeditsmall_i(EnvelopeFreeEdit*, void*); + static void cb_freeeditsmall(EnvelopeFreeEdit*, void*); + void cb_E4_i(Fl_Button*, void*); + static void cb_E4(Fl_Button*, void*); + void cb_C5_i(Fl_Button*, void*); + static void cb_C5(Fl_Button*, void*); + void cb_P5_i(Fl_Button*, void*); + static void cb_P5(Fl_Button*, void*); +public: + void init(EnvelopeParams *env_); + void reinit(); + void refresh(); +private: + EnvelopeParams *env; + Fl_Group *envwindow; +}; +#endif diff --git a/plugins/zynaddsubfx/src/UI/FilterUI.cc b/plugins/zynaddsubfx/src/UI/FilterUI.cc new file mode 100644 index 000000000..86c7ea57a --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/FilterUI.cc @@ -0,0 +1,987 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0109 + +#include "FilterUI.h" +//Copyright (c) 2002-2005 Nasca Octavian Paul +//License: GNU GPL version 2 or later + +FormantFilterGraph::FormantFilterGraph(int x,int y, int w, int h, const char *label):Fl_Box(x,y,w,h,label) { + pars=NULL; +nvowel=NULL; +nformant=NULL; +graphpoints=NULL; +} + +void FormantFilterGraph::init(FilterParams *pars_,int *nvowel_,int *nformant_) { + pars=pars_; +nvowel=nvowel_; +nformant=nformant_; +oldx=-1; +graphpoints=new REALTYPE [w()]; +} + +void FormantFilterGraph::draw_freq_line(REALTYPE freq,int type) { + REALTYPE freqx=pars->getfreqpos(freq); +switch(type){ + case 0:fl_line_style(FL_SOLID);break; + case 1:fl_line_style(FL_DOT);break; + case 2:fl_line_style(FL_DASH);break; +}; + + +if ((freqx>0.0)&&(freqx<1.0)) + fl_line(x()+(int) (freqx*w()),y(), + x()+(int) (freqx*w()),y()+h()); +} + +void FormantFilterGraph::draw() { + int maxdB=30; +int ox=x(),oy=y(),lx=w(),ly=h(),i,oiy; +REALTYPE freqx; + +fl_color(FL_BLACK); +fl_rectf(ox,oy,lx,ly); + + +//draw the lines +fl_color(FL_GRAY); + +fl_line_style(FL_SOLID); +//fl_line(ox+2,oy+ly/2,ox+lx-2,oy+ly/2); + +freqx=pars->getfreqpos(1000.0); +if ((freqx>0.0)&&(freqx<1.0)) + fl_line(ox+(int) (freqx*lx),oy, + ox+(int) (freqx*lx),oy+ly); + +for (i=1;i<10;i++){ + if(i==1){ + draw_freq_line(i*100.0,0); + draw_freq_line(i*1000.0,0); + }else + if (i==5){ + draw_freq_line(i*100.0,2); + draw_freq_line(i*1000.0,2); + }else{ + draw_freq_line(i*100.0,1); + draw_freq_line(i*1000.0,1); + }; +}; + +draw_freq_line(10000.0,0); +draw_freq_line(20000.0,1); + +fl_line_style(FL_DOT); +int GY=10;if (lyPnumformants){ + draw_freq_line(pars->getformantfreq(pars->Pvowels[*nvowel].formants[*nformant].freq),2); + +//show some information (like current formant frequency,amplitude) + char tmpstr[20]; + + snprintf(tmpstr,20,"%.2f kHz",pars->getformantfreq(pars->Pvowels[*nvowel].formants[*nformant].freq)*0.001); + fl_draw(tmpstr,ox+1,oy+1,40,12,FL_ALIGN_LEFT,NULL,0); + + snprintf(tmpstr,20,"%d dB",(int)( rap2dB(1e-9 + pars->getformantamp(pars->Pvowels[*nvowel].formants[*nformant].amp)) + pars->getgain() )); + fl_draw(tmpstr,ox+1,oy+15,40,12,FL_ALIGN_LEFT,NULL,0); + +}; + +//draw the data + +fl_color(FL_RED); +fl_line_style(FL_SOLID); + +pars->formantfilterH(*nvowel,lx,graphpoints); + +oiy=(int) ((graphpoints[0]/maxdB+1.0)*ly/2.0); +for (i=1;i=0)&&(oiy>=0)&&(iyPtype=(int)o->value(); +pars->changed=true; +} +void FilterUI::cb_analogfiltertypechoice(Fl_Choice* o, void* v) { + ((FilterUI*)(o->parent()->parent()->user_data()))->cb_analogfiltertypechoice_i(o,v); +} + +Fl_Menu_Item FilterUI::menu_analogfiltertypechoice[] = { + {"LPF1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"HPF1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"LPF2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"HPF2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"BPF2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"NF2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"PkF2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"LSh2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"HSh2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void FilterUI::cb_svfiltertypechoice_i(Fl_Choice* o, void*) { + pars->Ptype=(int)o->value(); +pars->changed=true; +} +void FilterUI::cb_svfiltertypechoice(Fl_Choice* o, void* v) { + ((FilterUI*)(o->parent()->parent()->user_data()))->cb_svfiltertypechoice_i(o,v); +} + +Fl_Menu_Item FilterUI::menu_svfiltertypechoice[] = { + {"1LPF", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"1HPF", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"1BPF", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"1NF", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void FilterUI::cb_filtertype_i(Fl_Choice* o, void*) { + switchcategory((int)o->value()); +pars->changed=true; +} +void FilterUI::cb_filtertype(Fl_Choice* o, void* v) { + ((FilterUI*)(o->parent()->parent()->user_data()))->cb_filtertype_i(o,v); +} + +Fl_Menu_Item FilterUI::menu_filtertype[] = { + {"Analog", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Formant", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"StVarF", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void FilterUI::cb_cfreqdial_i(WidgetPDial* o, void*) { + pars->Pfreq=(int)o->value(); +} +void FilterUI::cb_cfreqdial(WidgetPDial* o, void* v) { + ((FilterUI*)(o->parent()->parent()->user_data()))->cb_cfreqdial_i(o,v); +} + +void FilterUI::cb_qdial_i(WidgetPDial* o, void*) { + pars->Pq=(int)o->value(); +formantfiltergraph->redraw(); +} +void FilterUI::cb_qdial(WidgetPDial* o, void* v) { + ((FilterUI*)(o->parent()->parent()->user_data()))->cb_qdial_i(o,v); +} + +void FilterUI::cb_freqtrdial_i(WidgetPDial* o, void*) { + pars->Pfreqtrack=(int) o->value(); +} +void FilterUI::cb_freqtrdial(WidgetPDial* o, void* v) { + ((FilterUI*)(o->parent()->parent()->user_data()))->cb_freqtrdial_i(o,v); +} + +void FilterUI::cb_vsnsadial_i(WidgetPDial* o, void*) { + if (velsnsamp!=NULL) *velsnsamp=(int)o->value(); +} +void FilterUI::cb_vsnsadial(WidgetPDial* o, void* v) { + ((FilterUI*)(o->parent()->parent()->user_data()))->cb_vsnsadial_i(o,v); +} + +void FilterUI::cb_vsnsdial_i(WidgetPDial* o, void*) { + if (velsns!=NULL) *velsns=(int)o->value(); +} +void FilterUI::cb_vsnsdial(WidgetPDial* o, void* v) { + ((FilterUI*)(o->parent()->parent()->user_data()))->cb_vsnsdial_i(o,v); +} + +void FilterUI::cb_gaindial_i(WidgetPDial* o, void*) { + pars->Pgain=(int)o->value(); +formantfiltergraph->redraw(); +pars->changed=true; +} +void FilterUI::cb_gaindial(WidgetPDial* o, void* v) { + ((FilterUI*)(o->parent()->parent()->user_data()))->cb_gaindial_i(o,v); +} + +void FilterUI::cb_stcounter_i(Fl_Choice* o, void*) { + pars->Pstages=(int)o->value(); +formantfiltergraph->redraw(); +pars->changed=true; +} +void FilterUI::cb_stcounter(Fl_Choice* o, void* v) { + ((FilterUI*)(o->parent()->parent()->user_data()))->cb_stcounter_i(o,v); +} + +void FilterUI::cb_editbutton_i(Fl_Button*, void*) { + formantparswindow->show(); +} +void FilterUI::cb_editbutton(Fl_Button* o, void* v) { + ((FilterUI*)(o->parent()->user_data()))->cb_editbutton_i(o,v); +} + +void FilterUI::cb_C_i(Fl_Button*, void*) { + presetsui->copy(pars); +} +void FilterUI::cb_C(Fl_Button* o, void* v) { + ((FilterUI*)(o->parent()->user_data()))->cb_C_i(o,v); +} + +void FilterUI::cb_P_i(Fl_Button*, void*) { + presetsui->paste(pars,this); +} +void FilterUI::cb_P(Fl_Button* o, void* v) { + ((FilterUI*)(o->parent()->user_data()))->cb_P_i(o,v); +} + +void FilterUI::cb_Formant_i(Fl_Counter* o, void*) { + nformant=(int) o->value(); +update_formant_window(); +formantfiltergraph->redraw(); +} +void FilterUI::cb_Formant(Fl_Counter* o, void* v) { + ((FilterUI*)(o->parent()->parent()->user_data()))->cb_Formant_i(o,v); +} + +void FilterUI::cb_Vowel_i(Fl_Counter* o, void*) { + nvowel=(int) o->value(); +update_formant_window(); +formantfiltergraph->redraw(); +} +void FilterUI::cb_Vowel(Fl_Counter* o, void* v) { + ((FilterUI*)(o->parent()->parent()->user_data()))->cb_Vowel_i(o,v); +} + +void FilterUI::cb_formant_freq_dial_i(WidgetPDial* o, void*) { + pars->Pvowels[nvowel].formants[nformant].freq=(int) o->value(); +formantfiltergraph->redraw(); +pars->changed=true; +} +void FilterUI::cb_formant_freq_dial(WidgetPDial* o, void* v) { + ((FilterUI*)(o->parent()->parent()->parent()->user_data()))->cb_formant_freq_dial_i(o,v); +} + +void FilterUI::cb_formant_q_dial_i(WidgetPDial* o, void*) { + pars->Pvowels[nvowel].formants[nformant].q=(int) o->value(); +formantfiltergraph->redraw(); +pars->changed=true; +} +void FilterUI::cb_formant_q_dial(WidgetPDial* o, void* v) { + ((FilterUI*)(o->parent()->parent()->parent()->user_data()))->cb_formant_q_dial_i(o,v); +} + +void FilterUI::cb_formant_amp_dial_i(WidgetPDial* o, void*) { + pars->Pvowels[nvowel].formants[nformant].amp=(int) o->value(); +formantfiltergraph->redraw(); +pars->changed=true; +} +void FilterUI::cb_formant_amp_dial(WidgetPDial* o, void* v) { + ((FilterUI*)(o->parent()->parent()->parent()->user_data()))->cb_formant_amp_dial_i(o,v); +} + +void FilterUI::cb_Seq_i(Fl_Counter* o, void*) { + pars->Psequencesize=(int) o->value(); +update_formant_window(); +pars->changed=true; +} +void FilterUI::cb_Seq(Fl_Counter* o, void* v) { + ((FilterUI*)(o->parent()->parent()->user_data()))->cb_Seq_i(o,v); +} + +void FilterUI::cb_S_i(Fl_Counter* o, void*) { + nseqpos=(int) o->value(); +update_formant_window(); +pars->changed=true; +} +void FilterUI::cb_S(Fl_Counter* o, void* v) { + ((FilterUI*)(o->parent()->parent()->user_data()))->cb_S_i(o,v); +} + +void FilterUI::cb_vowel_counter_i(Fl_Counter* o, void*) { + pars->Psequence[nseqpos].nvowel=(int) o->value(); +pars->changed=true; +} +void FilterUI::cb_vowel_counter(Fl_Counter* o, void* v) { + ((FilterUI*)(o->parent()->parent()->user_data()))->cb_vowel_counter_i(o,v); +} + +void FilterUI::cb_Neg_i(Fl_Check_Button* o, void*) { + pars->Psequencereversed=(int) o->value(); +pars->changed=true; +} +void FilterUI::cb_Neg(Fl_Check_Button* o, void* v) { + ((FilterUI*)(o->parent()->parent()->user_data()))->cb_Neg_i(o,v); +} + +void FilterUI::cb_strchdial_i(WidgetPDial* o, void*) { + pars->Psequencestretch=(int) o->value(); +pars->changed=true; +} +void FilterUI::cb_strchdial(WidgetPDial* o, void* v) { + ((FilterUI*)(o->parent()->parent()->user_data()))->cb_strchdial_i(o,v); +} + +void FilterUI::cb_Num_i(Fl_Counter* o, void*) { + pars->Pnumformants=(int) o->value(); +update_formant_window(); +pars->changed=true; +formantfiltergraph->redraw(); +} +void FilterUI::cb_Num(Fl_Counter* o, void* v) { + ((FilterUI*)(o->parent()->user_data()))->cb_Num_i(o,v); +} + +void FilterUI::cb_frsldial_i(WidgetPDial* o, void*) { + pars->Pformantslowness=(int) o->value(); +pars->changed=true; +} +void FilterUI::cb_frsldial(WidgetPDial* o, void* v) { + ((FilterUI*)(o->parent()->user_data()))->cb_frsldial_i(o,v); +} + +void FilterUI::cb_centerfreqvo_i(Fl_Value_Output* o, void*) { + o->value(pars->getcenterfreq()/1000.0); +} +void FilterUI::cb_centerfreqvo(Fl_Value_Output* o, void* v) { + ((FilterUI*)(o->parent()->user_data()))->cb_centerfreqvo_i(o,v); +} + +void FilterUI::cb_octavesfreqvo_i(Fl_Value_Output* o, void*) { + o->value(pars->getoctavesfreq()); +} +void FilterUI::cb_octavesfreqvo(Fl_Value_Output* o, void* v) { + ((FilterUI*)(o->parent()->user_data()))->cb_octavesfreqvo_i(o,v); +} + +void FilterUI::cb_cfknob_i(Fl_Slider* o, void*) { + pars->Pcenterfreq=(int)o->value(); +centerfreqvo->do_callback(); +formantfiltergraph->redraw(); +pars->changed=true; +} +void FilterUI::cb_cfknob(Fl_Slider* o, void* v) { + ((FilterUI*)(o->parent()->user_data()))->cb_cfknob_i(o,v); +} + +void FilterUI::cb_octknob_i(Fl_Slider* o, void*) { + pars->Poctavesfreq=(int)o->value(); +octavesfreqvo->do_callback(); +formantfiltergraph->redraw(); +} +void FilterUI::cb_octknob(Fl_Slider* o, void* v) { + ((FilterUI*)(o->parent()->user_data()))->cb_octknob_i(o,v); +} + +void FilterUI::cb_wvknob_i(WidgetPDial* o, void*) { + pars->Pvowelclearness=(int) o->value(); +pars->changed=true; +} +void FilterUI::cb_wvknob(WidgetPDial* o, void* v) { + ((FilterUI*)(o->parent()->user_data()))->cb_wvknob_i(o,v); +} + +void FilterUI::cb_Close_i(Fl_Button*, void*) { + formantparswindow->hide(); +} +void FilterUI::cb_Close(Fl_Button* o, void* v) { + ((FilterUI*)(o->parent()->user_data()))->cb_Close_i(o,v); +} + +void FilterUI::cb_C1_i(Fl_Button*, void*) { + presetsui->copy(pars,nvowel); +} +void FilterUI::cb_C1(Fl_Button* o, void* v) { + ((FilterUI*)(o->parent()->user_data()))->cb_C1_i(o,v); +} + +void FilterUI::cb_P1_i(Fl_Button*, void*) { + presetsui->paste(pars,this,nvowel); +} +void FilterUI::cb_P1(Fl_Button* o, void* v) { + ((FilterUI*)(o->parent()->user_data()))->cb_P1_i(o,v); +} + +FilterUI::FilterUI(int x,int y, int w, int h, const char *label):Fl_Group(x,y,w,h,label) { + pars=NULL; +velsnsamp=NULL; +velsns=NULL; +nvowel=0;nformant=0;nseqpos=0; +} + +FilterUI::~FilterUI() { + filterui->hide(); +formantparswindow->hide(); +hide(); +//delete (filterui); +delete (formantparswindow); +} + +Fl_Group* FilterUI::make_window() { + { filterui = new Fl_Group(0, 0, 275, 75); + filterui->box(FL_FLAT_BOX); + filterui->color(FL_LIGHT1); + filterui->selection_color(FL_BACKGROUND_COLOR); + filterui->labeltype(FL_NO_LABEL); + filterui->labelfont(1); + filterui->labelsize(14); + filterui->labelcolor(FL_FOREGROUND_COLOR); + filterui->user_data((void*)(this)); + filterui->align(FL_ALIGN_TOP); + filterui->when(FL_WHEN_RELEASE); + { filterparamswindow = new Fl_Group(0, 0, 275, 75, "Filter Parameters"); + filterparamswindow->box(FL_PLASTIC_UP_BOX); + filterparamswindow->color((Fl_Color)183); + filterparamswindow->labeltype(FL_ENGRAVED_LABEL); + filterparamswindow->labelsize(10); + filterparamswindow->align(FL_ALIGN_TOP|FL_ALIGN_INSIDE); + { Fl_Choice* o = analogfiltertypechoice = new Fl_Choice(10, 50, 50, 15, "FilterType"); + analogfiltertypechoice->tooltip("The Filter type"); + analogfiltertypechoice->down_box(FL_BORDER_BOX); + analogfiltertypechoice->labelsize(10); + analogfiltertypechoice->textsize(10); + analogfiltertypechoice->callback((Fl_Callback*)cb_analogfiltertypechoice); + analogfiltertypechoice->align(FL_ALIGN_TOP_LEFT); + analogfiltertypechoice->menu(menu_analogfiltertypechoice); + o->value(pars->Ptype); + } // Fl_Choice* analogfiltertypechoice + { Fl_Choice* o = svfiltertypechoice = new Fl_Choice(10, 50, 50, 15, "FilterType"); + svfiltertypechoice->tooltip("The Filter type"); + svfiltertypechoice->down_box(FL_BORDER_BOX); + svfiltertypechoice->labelsize(10); + svfiltertypechoice->textsize(10); + svfiltertypechoice->callback((Fl_Callback*)cb_svfiltertypechoice); + svfiltertypechoice->align(FL_ALIGN_TOP_LEFT); + svfiltertypechoice->menu(menu_svfiltertypechoice); + o->value(pars->Ptype); + } // Fl_Choice* svfiltertypechoice + { Fl_Choice* o = filtertype = new Fl_Choice(10, 20, 60, 15, "Category"); + filtertype->tooltip("The Category of the Filter (Analog/Formantic/etc.)"); + filtertype->down_box(FL_BORDER_BOX); + filtertype->labelsize(10); + filtertype->textsize(10); + filtertype->callback((Fl_Callback*)cb_filtertype); + filtertype->align(FL_ALIGN_TOP_LEFT); + filtertype->menu(menu_filtertype); + o->value(pars->Pcategory); + } // Fl_Choice* filtertype + { WidgetPDial* o = cfreqdial = new WidgetPDial(75, 25, 30, 30, "C.Freq"); + cfreqdial->tooltip("Center Frequency of the Filter or the base position in the vowel\'s sequence"); + cfreqdial->box(FL_ROUND_UP_BOX); + cfreqdial->color(FL_BACKGROUND_COLOR); + cfreqdial->selection_color(FL_INACTIVE_COLOR); + cfreqdial->labeltype(FL_NORMAL_LABEL); + cfreqdial->labelfont(0); + cfreqdial->labelsize(10); + cfreqdial->labelcolor(FL_FOREGROUND_COLOR); + cfreqdial->maximum(127); + cfreqdial->step(1); + cfreqdial->callback((Fl_Callback*)cb_cfreqdial); + cfreqdial->align(FL_ALIGN_BOTTOM); + cfreqdial->when(FL_WHEN_CHANGED); + o->value(pars->Pfreq); + } // WidgetPDial* cfreqdial + { WidgetPDial* o = qdial = new WidgetPDial(110, 25, 30, 30, "Q"); + qdial->tooltip("Filter resonance or bandwidth"); + qdial->box(FL_ROUND_UP_BOX); + qdial->color(FL_BACKGROUND_COLOR); + qdial->selection_color(FL_INACTIVE_COLOR); + qdial->labeltype(FL_NORMAL_LABEL); + qdial->labelfont(0); + qdial->labelsize(10); + qdial->labelcolor(FL_FOREGROUND_COLOR); + qdial->maximum(127); + qdial->step(1); + qdial->callback((Fl_Callback*)cb_qdial); + qdial->align(FL_ALIGN_BOTTOM); + qdial->when(FL_WHEN_CHANGED); + o->value(pars->Pq); + } // WidgetPDial* qdial + { WidgetPDial* o = freqtrdial = new WidgetPDial(215, 25, 30, 30, "freq.tr."); + freqtrdial->tooltip("Filter frequency tracking (left is negative, middle is 0, and right is positi\ +ve)"); + freqtrdial->box(FL_ROUND_UP_BOX); + freqtrdial->color(FL_BACKGROUND_COLOR); + freqtrdial->selection_color(FL_INACTIVE_COLOR); + freqtrdial->labeltype(FL_NORMAL_LABEL); + freqtrdial->labelfont(0); + freqtrdial->labelsize(10); + freqtrdial->labelcolor(FL_FOREGROUND_COLOR); + freqtrdial->maximum(127); + freqtrdial->step(1); + freqtrdial->callback((Fl_Callback*)cb_freqtrdial); + freqtrdial->align(FL_ALIGN_BOTTOM); + freqtrdial->when(FL_WHEN_CHANGED); + o->value(pars->Pfreqtrack); + } // WidgetPDial* freqtrdial + { vsnsadial = new WidgetPDial(145, 25, 30, 30, "V.SnsA."); + vsnsadial->tooltip("Velocity sensing amount of the Filter"); + vsnsadial->box(FL_ROUND_UP_BOX); + vsnsadial->color(FL_BACKGROUND_COLOR); + vsnsadial->selection_color(FL_INACTIVE_COLOR); + vsnsadial->labeltype(FL_NORMAL_LABEL); + vsnsadial->labelfont(0); + vsnsadial->labelsize(10); + vsnsadial->labelcolor(FL_FOREGROUND_COLOR); + vsnsadial->maximum(127); + vsnsadial->step(1); + vsnsadial->callback((Fl_Callback*)cb_vsnsadial); + vsnsadial->align(FL_ALIGN_BOTTOM); + vsnsadial->when(FL_WHEN_CHANGED); + } // WidgetPDial* vsnsadial + { vsnsdial = new WidgetPDial(180, 25, 30, 30, "V.Sns."); + vsnsdial->tooltip("Velocity Sensing Function of the Filter"); + vsnsdial->box(FL_ROUND_UP_BOX); + vsnsdial->color(FL_BACKGROUND_COLOR); + vsnsdial->selection_color(FL_INACTIVE_COLOR); + vsnsdial->labeltype(FL_NORMAL_LABEL); + vsnsdial->labelfont(0); + vsnsdial->labelsize(10); + vsnsdial->labelcolor(FL_FOREGROUND_COLOR); + vsnsdial->maximum(127); + vsnsdial->step(1); + vsnsdial->callback((Fl_Callback*)cb_vsnsdial); + vsnsdial->align(FL_ALIGN_BOTTOM); + vsnsdial->when(FL_WHEN_CHANGED); + } // WidgetPDial* vsnsdial + { WidgetPDial* o = gaindial = new WidgetPDial(250, 35, 20, 20, "gain"); + gaindial->tooltip("Filter output gain/damp"); + gaindial->box(FL_ROUND_UP_BOX); + gaindial->color(FL_BACKGROUND_COLOR); + gaindial->selection_color(FL_INACTIVE_COLOR); + gaindial->labeltype(FL_NORMAL_LABEL); + gaindial->labelfont(0); + gaindial->labelsize(10); + gaindial->labelcolor(FL_FOREGROUND_COLOR); + gaindial->maximum(127); + gaindial->step(1); + gaindial->callback((Fl_Callback*)cb_gaindial); + gaindial->align(FL_ALIGN_BOTTOM); + gaindial->when(FL_WHEN_CHANGED); + o->value(pars->Pgain); + } // WidgetPDial* gaindial + { Fl_Choice* o = stcounter = new Fl_Choice(235, 5, 35, 15, "St"); + stcounter->tooltip("Filter stages (in order to increase dB/oct. value and the order of the filter\ +)"); + stcounter->down_box(FL_BORDER_BOX); + stcounter->labelsize(10); + stcounter->textfont(1); + stcounter->textsize(10); + stcounter->callback((Fl_Callback*)cb_stcounter); + for (int i=0;iadd(tmp);}; + o->value(pars->Pstages); + } // Fl_Choice* stcounter + filterparamswindow->end(); + } // Fl_Group* filterparamswindow + { editbutton = new Fl_Button(15, 40, 50, 25, "Edit"); + editbutton->box(FL_PLASTIC_UP_BOX); + editbutton->labelfont(1); + editbutton->labelsize(11); + editbutton->callback((Fl_Callback*)cb_editbutton); + } // Fl_Button* editbutton + { Fl_Button* o = new Fl_Button(186, 5, 15, 15, "C"); + o->box(FL_THIN_UP_BOX); + o->color((Fl_Color)179); + o->labelfont(1); + o->labelsize(10); + o->labelcolor(FL_BACKGROUND2_COLOR); + o->callback((Fl_Callback*)cb_C); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(203, 5, 15, 15, "P"); + o->box(FL_THIN_UP_BOX); + o->color((Fl_Color)179); + o->labelfont(1); + o->labelsize(10); + o->labelcolor(FL_BACKGROUND2_COLOR); + o->callback((Fl_Callback*)cb_P); + } // Fl_Button* o + filterui->end(); + } // Fl_Group* filterui + return filterui; +} + +Fl_Double_Window* FilterUI::make_formant_window() { + { formantparswindow = new Fl_Double_Window(700, 205, "Formant Filter Parameters"); + formantparswindow->user_data((void*)(this)); + { Fl_Group* o = new Fl_Group(485, 47, 105, 113); + o->box(FL_THIN_UP_BOX); + { Fl_Counter* o = new Fl_Counter(545, 80, 40, 15, "Formant "); + o->type(1); + o->labelfont(1); + o->labelsize(10); + o->minimum(0); + o->maximum(127); + o->step(1); + o->textsize(10); + o->callback((Fl_Callback*)cb_Formant); + o->align(FL_ALIGN_LEFT); + o->bounds(0,FF_MAX_FORMANTS-1); + o->value(nformant); + } // Fl_Counter* o + { Fl_Counter* o = new Fl_Counter(545, 55, 40, 20, "Vowel no."); + o->type(1); + o->labelfont(1); + o->labelsize(10); + o->minimum(0); + o->maximum(127); + o->step(1); + o->textfont(1); + o->textsize(11); + o->callback((Fl_Callback*)cb_Vowel); + o->align(FL_ALIGN_LEFT); + o->bounds(0,FF_MAX_VOWELS-1); + o->value(nvowel); + } // Fl_Counter* o + { formantparsgroup = new Fl_Group(490, 105, 95, 50); + formantparsgroup->box(FL_ENGRAVED_FRAME); + { formant_freq_dial = new WidgetPDial(495, 115, 25, 25, "freq"); + formant_freq_dial->tooltip("Formant frequency"); + formant_freq_dial->box(FL_ROUND_UP_BOX); + formant_freq_dial->color(FL_BACKGROUND_COLOR); + formant_freq_dial->selection_color(FL_INACTIVE_COLOR); + formant_freq_dial->labeltype(FL_NORMAL_LABEL); + formant_freq_dial->labelfont(0); + formant_freq_dial->labelsize(10); + formant_freq_dial->labelcolor(FL_FOREGROUND_COLOR); + formant_freq_dial->maximum(127); + formant_freq_dial->step(1); + formant_freq_dial->callback((Fl_Callback*)cb_formant_freq_dial); + formant_freq_dial->align(FL_ALIGN_BOTTOM); + formant_freq_dial->when(FL_WHEN_CHANGED); + } // WidgetPDial* formant_freq_dial + { formant_q_dial = new WidgetPDial(525, 115, 24, 25, "Q"); + formant_q_dial->tooltip("Formant\'s Q"); + formant_q_dial->box(FL_ROUND_UP_BOX); + formant_q_dial->color(FL_BACKGROUND_COLOR); + formant_q_dial->selection_color(FL_INACTIVE_COLOR); + formant_q_dial->labeltype(FL_NORMAL_LABEL); + formant_q_dial->labelfont(0); + formant_q_dial->labelsize(10); + formant_q_dial->labelcolor(FL_FOREGROUND_COLOR); + formant_q_dial->maximum(127); + formant_q_dial->step(1); + formant_q_dial->callback((Fl_Callback*)cb_formant_q_dial); + formant_q_dial->align(FL_ALIGN_BOTTOM); + formant_q_dial->when(FL_WHEN_CHANGED); + } // WidgetPDial* formant_q_dial + { formant_amp_dial = new WidgetPDial(555, 115, 24, 25, "amp"); + formant_amp_dial->tooltip("Formant amplitude"); + formant_amp_dial->box(FL_ROUND_UP_BOX); + formant_amp_dial->color(FL_BACKGROUND_COLOR); + formant_amp_dial->selection_color(FL_INACTIVE_COLOR); + formant_amp_dial->labeltype(FL_NORMAL_LABEL); + formant_amp_dial->labelfont(0); + formant_amp_dial->labelsize(10); + formant_amp_dial->labelcolor(FL_FOREGROUND_COLOR); + formant_amp_dial->maximum(127); + formant_amp_dial->step(1); + formant_amp_dial->callback((Fl_Callback*)cb_formant_amp_dial); + formant_amp_dial->align(FL_ALIGN_BOTTOM); + formant_amp_dial->when(FL_WHEN_CHANGED); + } // WidgetPDial* formant_amp_dial + formantparsgroup->end(); + } // Fl_Group* formantparsgroup + o->end(); + } // Fl_Group* o + { Fl_Group* o = new Fl_Group(590, 47, 100, 113); + o->box(FL_THIN_UP_BOX); + { Fl_Counter* o = new Fl_Counter(595, 62, 55, 20, "Seq.Size"); + o->type(1); + o->labelfont(1); + o->labelsize(10); + o->minimum(0); + o->maximum(127); + o->step(1); + o->textfont(1); + o->textsize(11); + o->callback((Fl_Callback*)cb_Seq); + o->align(FL_ALIGN_TOP_LEFT); + o->bounds(1,FF_MAX_SEQUENCE-1); + o->value(pars->Psequencesize); + } // Fl_Counter* o + { Fl_Counter* o = new Fl_Counter(595, 97, 40, 15, "S.Pos."); + o->tooltip("Current position from the sequence"); + o->type(1); + o->labelfont(1); + o->labelsize(10); + o->minimum(0); + o->maximum(127); + o->step(1); + o->textsize(10); + o->callback((Fl_Callback*)cb_S); + o->align(FL_ALIGN_TOP_RIGHT); + o->bounds(0,FF_MAX_SEQUENCE-2); + o->value(nseqpos); + } // Fl_Counter* o + { Fl_Counter* o = vowel_counter = new Fl_Counter(640, 97, 40, 15, "Vowel"); + vowel_counter->type(1); + vowel_counter->labelsize(10); + vowel_counter->minimum(0); + vowel_counter->maximum(127); + vowel_counter->step(1); + vowel_counter->textsize(10); + vowel_counter->callback((Fl_Callback*)cb_vowel_counter); + vowel_counter->align(FL_ALIGN_TOP); + o->bounds(0,FF_MAX_VOWELS-1); + } // Fl_Counter* vowel_counter + { Fl_Check_Button* o = new Fl_Check_Button(625, 132, 60, 20, "Neg.Input"); + o->tooltip("Negate the input from LFO/envelopes/etc."); + o->down_box(FL_DOWN_BOX); + o->labelsize(10); + o->callback((Fl_Callback*)cb_Neg); + o->value(pars->Psequencereversed); + } // Fl_Check_Button* o + { WidgetPDial* o = strchdial = new WidgetPDial(595, 130, 25, 25, "Strch"); + strchdial->tooltip("Sequence Stretch"); + strchdial->box(FL_ROUND_UP_BOX); + strchdial->color(FL_BACKGROUND_COLOR); + strchdial->selection_color(FL_INACTIVE_COLOR); + strchdial->labeltype(FL_NORMAL_LABEL); + strchdial->labelfont(0); + strchdial->labelsize(10); + strchdial->labelcolor(FL_FOREGROUND_COLOR); + strchdial->maximum(127); + strchdial->step(1); + strchdial->callback((Fl_Callback*)cb_strchdial); + strchdial->align(FL_ALIGN_TOP); + strchdial->when(FL_WHEN_CHANGED); + o->value(pars->Psequencestretch); + } // WidgetPDial* strchdial + o->end(); + } // Fl_Group* o + { Fl_Counter* o = new Fl_Counter(485, 15, 65, 20, "Num.Formants"); + o->type(1); + o->labelfont(1); + o->labelsize(10); + o->minimum(0); + o->maximum(127); + o->step(1); + o->callback((Fl_Callback*)cb_Num); + o->align(FL_ALIGN_TOP_LEFT); + o->bounds(1,FF_MAX_FORMANTS); + o->value(pars->Pnumformants); + } // Fl_Counter* o + { WidgetPDial* o = frsldial = new WidgetPDial(565, 15, 25, 25, "Fr.Sl."); + frsldial->tooltip("Formant\'s Slowness (Morphing)"); + frsldial->box(FL_ROUND_UP_BOX); + frsldial->color(FL_BACKGROUND_COLOR); + frsldial->selection_color(FL_INACTIVE_COLOR); + frsldial->labeltype(FL_NORMAL_LABEL); + frsldial->labelfont(1); + frsldial->labelsize(10); + frsldial->labelcolor(FL_FOREGROUND_COLOR); + frsldial->maximum(127); + frsldial->step(1); + frsldial->callback((Fl_Callback*)cb_frsldial); + frsldial->align(FL_ALIGN_TOP); + frsldial->when(FL_WHEN_CHANGED); + o->value(pars->Pformantslowness); + } // WidgetPDial* frsldial + { Fl_Value_Output* o = centerfreqvo = new Fl_Value_Output(515, 164, 33, 18, "C.f."); + centerfreqvo->tooltip("Center Frequency (kHz)"); + centerfreqvo->minimum(1); + centerfreqvo->maximum(10); + centerfreqvo->step(0.01); + centerfreqvo->value(1); + centerfreqvo->textfont(1); + centerfreqvo->callback((Fl_Callback*)cb_centerfreqvo); + centerfreqvo->when(3); + o->value(pars->getcenterfreq()/1000.0); + } // Fl_Value_Output* centerfreqvo + { Fl_Value_Output* o = octavesfreqvo = new Fl_Value_Output(515, 182, 33, 18, "Oct."); + octavesfreqvo->tooltip("No. of octaves"); + octavesfreqvo->minimum(1); + octavesfreqvo->maximum(127); + octavesfreqvo->step(1); + octavesfreqvo->value(5); + octavesfreqvo->textfont(1); + octavesfreqvo->callback((Fl_Callback*)cb_octavesfreqvo); + octavesfreqvo->when(3); + o->value(pars->getoctavesfreq()); + } // Fl_Value_Output* octavesfreqvo + { Fl_Slider* o = cfknob = new Fl_Slider(551, 167, 84, 15); + cfknob->type(5); + cfknob->box(FL_FLAT_BOX); + cfknob->maximum(127); + cfknob->callback((Fl_Callback*)cb_cfknob); + o->value(pars->Pcenterfreq); + } // Fl_Slider* cfknob + { Fl_Slider* o = octknob = new Fl_Slider(551, 185, 84, 15); + octknob->type(5); + octknob->box(FL_FLAT_BOX); + octknob->maximum(127); + octknob->callback((Fl_Callback*)cb_octknob); + o->value(pars->Poctavesfreq); + } // Fl_Slider* octknob + { FormantFilterGraph* o = formantfiltergraph = new FormantFilterGraph(5, 5, 475, 195); + formantfiltergraph->box(FL_BORDER_BOX); + formantfiltergraph->color(FL_BACKGROUND_COLOR); + formantfiltergraph->selection_color(FL_BACKGROUND_COLOR); + formantfiltergraph->labeltype(FL_NORMAL_LABEL); + formantfiltergraph->labelfont(0); + formantfiltergraph->labelsize(14); + formantfiltergraph->labelcolor(FL_FOREGROUND_COLOR); + formantfiltergraph->align(FL_ALIGN_CENTER); + formantfiltergraph->when(FL_WHEN_RELEASE); + o->init(pars,&nvowel,&nformant); + } // FormantFilterGraph* formantfiltergraph + { WidgetPDial* o = wvknob = new WidgetPDial(600, 15, 25, 25, "Vw.Cl."); + wvknob->tooltip("Vowel \"clearness\" (how the mixed vowels are avoided)"); + wvknob->box(FL_ROUND_UP_BOX); + wvknob->color(FL_BACKGROUND_COLOR); + wvknob->selection_color(FL_INACTIVE_COLOR); + wvknob->labeltype(FL_NORMAL_LABEL); + wvknob->labelfont(1); + wvknob->labelsize(10); + wvknob->labelcolor(FL_FOREGROUND_COLOR); + wvknob->maximum(127); + wvknob->step(1); + wvknob->callback((Fl_Callback*)cb_wvknob); + wvknob->align(FL_ALIGN_TOP); + wvknob->when(FL_WHEN_CHANGED); + o->value(pars->Pvowelclearness); + } // WidgetPDial* wvknob + { Fl_Button* o = new Fl_Button(645, 180, 50, 25, "Close"); + o->box(FL_THIN_UP_BOX); + o->callback((Fl_Callback*)cb_Close); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(635, 25, 25, 15, "C"); + o->box(FL_THIN_UP_BOX); + o->color((Fl_Color)179); + o->labelfont(1); + o->labelsize(11); + o->labelcolor(FL_BACKGROUND2_COLOR); + o->callback((Fl_Callback*)cb_C1); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(665, 25, 25, 15, "P"); + o->box(FL_THIN_UP_BOX); + o->color((Fl_Color)179); + o->labelfont(1); + o->labelsize(11); + o->labelcolor(FL_BACKGROUND2_COLOR); + o->callback((Fl_Callback*)cb_P1); + } // Fl_Button* o + { new Fl_Box(635, 10, 55, 15, "Vowel"); + } // Fl_Box* o + formantparswindow->end(); + } // Fl_Double_Window* formantparswindow + return formantparswindow; +} + +void FilterUI::update_formant_window() { + formant_freq_dial->value(pars->Pvowels[nvowel].formants[nformant].freq); +formant_q_dial->value(pars->Pvowels[nvowel].formants[nformant].q); +formant_amp_dial->value(pars->Pvowels[nvowel].formants[nformant].amp); +if (nformantPnumformants) formantparsgroup->activate(); + else formantparsgroup->deactivate(); + +if (nseqposPsequencesize) vowel_counter->activate(); + else vowel_counter->deactivate(); + + +vowel_counter->value(pars->Psequence[nseqpos].nvowel); +} + +void FilterUI::refresh() { + update_formant_window(); +formantfiltergraph->redraw(); + +if (pars->Pcategory==0) svfiltertypechoice->value(pars->Ptype); +if (pars->Pcategory==2) analogfiltertypechoice->value(pars->Ptype); + +filtertype->value(pars->Pcategory); + +cfreqdial->value(pars->Pfreq); +qdial->value(pars->Pq); + +freqtrdial->value(pars->Pfreqtrack); +gaindial->value(pars->Pgain); + +stcounter->value(pars->Pstages); + +int categ=pars->Pcategory; +if ((categ==0)||(categ==2)) { + if (categ==0) { + analogfiltertypechoice->show(); + svfiltertypechoice->hide(); + } else { + svfiltertypechoice->show(); + analogfiltertypechoice->hide(); + }; + editbutton->hide(); + formantparswindow->hide(); + cfreqdial->label("C.freq"); +} else { + analogfiltertypechoice->hide(); + svfiltertypechoice->hide(); + editbutton->show(); + cfreqdial->label("BS.pos"); +}; + +filterparamswindow->redraw(); +} + +void FilterUI::init(FilterParams *filterpars_,unsigned char *velsnsamp_,unsigned char *velsns_) { + pars=filterpars_; +velsnsamp=velsnsamp_; +velsns=velsns_; + +make_window(); +end(); +make_formant_window(); + + +filterui->resize(this->x(),this->y(),this->w(),this->h()); + + +if (velsnsamp==NULL){ + vsnsadial->deactivate(); + vsnsadial->value(127); + } else vsnsadial->value(*velsnsamp); + +if (velsns==NULL){ + vsnsdial->deactivate(); + vsnsdial->value(127); + } else vsnsdial->value(*velsns); + +switchcategory(pars->Pcategory); + + +formantparswindow->label(this->label()); + +update_formant_window(); +} + +void FilterUI::switchcategory(int newcat) { + if (pars->Pcategory!=newcat){ + pars->Pgain=64; + gaindial->value(64); + analogfiltertypechoice->value(0); + analogfiltertypechoice->do_callback(); + svfiltertypechoice->value(0); + svfiltertypechoice->do_callback(); +}; +pars->Pcategory=newcat; + +refresh(); +} + +void FilterUI::use_for_dynamic_filter() { + freqtrdial->deactivate(); +gaindial->when(0); + +cfknob->when(FL_WHEN_RELEASE); +octknob->when(FL_WHEN_RELEASE); + +frsldial->when(0); +wvknob->when(0); +formant_freq_dial->when(0); +formant_q_dial->when(0); +formant_amp_dial->when(0); +strchdial->when(0); +} diff --git a/plugins/zynaddsubfx/src/UI/FilterUI.fl b/plugins/zynaddsubfx/src/UI/FilterUI.fl new file mode 100644 index 000000000..e2da82e12 --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/FilterUI.fl @@ -0,0 +1,624 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0106 +header_name {.h} +code_name {.cc} +decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} + +decl {//License: GNU GPL version 2 or later} {} + +decl {\#include "WidgetPDial.h"} {public +} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include "../globals.h"} {public +} + +decl {\#include } {public +} + +decl {\#include "../Params/FilterParams.h"} {public +} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include "PresetsUI.h"} {public +} + +class FormantFilterGraph {: {public Fl_Box} +} { + Function {FormantFilterGraph(int x,int y, int w, int h, const char *label=0):Fl_Box(x,y,w,h,label)} {} { + code {pars=NULL; +nvowel=NULL; +nformant=NULL; +graphpoints=NULL;} {} + } + Function {init(FilterParams *pars_,int *nvowel_,int *nformant_)} {} { + code {pars=pars_; +nvowel=nvowel_; +nformant=nformant_; +oldx=-1; +graphpoints=new REALTYPE [w()];} {} + } + Function {draw_freq_line(REALTYPE freq,int type)} {} { + code {REALTYPE freqx=pars->getfreqpos(freq); +switch(type){ + case 0:fl_line_style(FL_SOLID);break; + case 1:fl_line_style(FL_DOT);break; + case 2:fl_line_style(FL_DASH);break; +}; + + +if ((freqx>0.0)&&(freqx<1.0)) + fl_line(x()+(int) (freqx*w()),y(), + x()+(int) (freqx*w()),y()+h());} {} + } + Function {draw()} {open + } { + code {int maxdB=30; +int ox=x(),oy=y(),lx=w(),ly=h(),i,oiy; +REALTYPE freqx; + +fl_color(FL_BLACK); +fl_rectf(ox,oy,lx,ly); + + +//draw the lines +fl_color(FL_GRAY); + +fl_line_style(FL_SOLID); +//fl_line(ox+2,oy+ly/2,ox+lx-2,oy+ly/2); + +freqx=pars->getfreqpos(1000.0); +if ((freqx>0.0)&&(freqx<1.0)) + fl_line(ox+(int) (freqx*lx),oy, + ox+(int) (freqx*lx),oy+ly); + +for (i=1;i<10;i++){ + if(i==1){ + draw_freq_line(i*100.0,0); + draw_freq_line(i*1000.0,0); + }else + if (i==5){ + draw_freq_line(i*100.0,2); + draw_freq_line(i*1000.0,2); + }else{ + draw_freq_line(i*100.0,1); + draw_freq_line(i*1000.0,1); + }; +}; + +draw_freq_line(10000.0,0); +draw_freq_line(20000.0,1); + +fl_line_style(FL_DOT); +int GY=10;if (lyPnumformants){ + draw_freq_line(pars->getformantfreq(pars->Pvowels[*nvowel].formants[*nformant].freq),2); + +//show some information (like current formant frequency,amplitude) + char tmpstr[20]; + + snprintf(tmpstr,20,"%.2f kHz",pars->getformantfreq(pars->Pvowels[*nvowel].formants[*nformant].freq)*0.001); + fl_draw(tmpstr,ox+1,oy+1,40,12,FL_ALIGN_LEFT,NULL,0); + + snprintf(tmpstr,20,"%d dB",(int)( rap2dB(1e-9 + pars->getformantamp(pars->Pvowels[*nvowel].formants[*nformant].amp)) + pars->getgain() )); + fl_draw(tmpstr,ox+1,oy+15,40,12,FL_ALIGN_LEFT,NULL,0); + +}; + +//draw the data + +fl_color(FL_RED); +fl_line_style(FL_SOLID); + +pars->formantfilterH(*nvowel,lx,graphpoints); + +oiy=(int) ((graphpoints[0]/maxdB+1.0)*ly/2.0); +for (i=1;i=0)&&(oiy>=0)&&(iyhide(); +formantparswindow->hide(); +hide(); +//delete (filterui); +delete (formantparswindow);} {} + } + Function {make_window()} {} { + Fl_Window filterui { + xywh {211 312 275 75} type Double color 50 labelfont 1 hide + class Fl_Group + } { + Fl_Group filterparamswindow { + label {Filter Parameters} + xywh {0 0 275 75} box PLASTIC_UP_BOX color 183 labeltype ENGRAVED_LABEL labelsize 10 align 17 + } { + Fl_Choice analogfiltertypechoice { + label FilterType + callback {pars->Ptype=(int)o->value(); +pars->changed=true;} + tooltip {The Filter type} xywh {10 50 50 15} down_box BORDER_BOX labelsize 10 align 5 textsize 10 + code1 {o->value(pars->Ptype);} + } { + menuitem {} { + label LPF1 + xywh {40 40 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label HPF1 + xywh {50 50 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label LPF2 + xywh {60 60 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label HPF2 + xywh {70 70 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label BPF2 + xywh {82 82 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label NF2 + xywh {94 94 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label PkF2 + xywh {104 104 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label LSh2 + xywh {114 114 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label HSh2 + xywh {124 124 100 20} labelfont 1 labelsize 10 + } + } + Fl_Choice svfiltertypechoice { + label FilterType + callback {pars->Ptype=(int)o->value(); +pars->changed=true;} + tooltip {The Filter type} xywh {10 50 50 15} down_box BORDER_BOX labelsize 10 align 5 textsize 10 + code1 {o->value(pars->Ptype);} + } { + menuitem {} { + label 1LPF + xywh {134 134 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label 1HPF + xywh {144 144 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label 1BPF + xywh {154 154 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label 1NF + xywh {164 164 100 20} labelfont 1 labelsize 10 + } + } + Fl_Choice filtertype { + label Category + callback {switchcategory((int)o->value()); +pars->changed=true;} + tooltip {The Category of the Filter (Analog/Formantic/etc.)} xywh {10 20 60 15} down_box BORDER_BOX labelsize 10 align 5 textsize 10 + code0 {o->value(pars->Pcategory);} + } { + menuitem {} { + label Analog + xywh {50 50 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label Formant + xywh {60 60 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label StVarF + xywh {70 70 100 20} labelfont 1 labelsize 10 + } + } + Fl_Dial cfreqdial { + label {C.Freq} + callback {pars->Pfreq=(int)o->value();} + tooltip {Center Frequency of the Filter or the base position in the vowel's sequence} xywh {75 25 30 30} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + code0 {o->value(pars->Pfreq);} + class WidgetPDial + } + Fl_Dial qdial { + label Q + callback {pars->Pq=(int)o->value(); +formantfiltergraph->redraw();} + tooltip {Filter resonance or bandwidth} xywh {110 25 30 30} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + code0 {o->value(pars->Pq);} + class WidgetPDial + } + Fl_Dial freqtrdial { + label {freq.tr.} + callback {pars->Pfreqtrack=(int) o->value();} + tooltip {Filter frequency tracking (left is negative, middle is 0, and right is positive)} xywh {215 25 30 30} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + code0 {o->value(pars->Pfreqtrack);} + class WidgetPDial + } + Fl_Dial vsnsadial { + label {V.SnsA.} + callback {if (velsnsamp!=NULL) *velsnsamp=(int)o->value();} + tooltip {Velocity sensing amount of the Filter} xywh {145 25 30 30} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + class WidgetPDial + } + Fl_Dial vsnsdial { + label {V.Sns.} + callback {if (velsns!=NULL) *velsns=(int)o->value();} + tooltip {Velocity Sensing Function of the Filter} xywh {180 25 30 30} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + class WidgetPDial + } + Fl_Dial gaindial { + label gain + callback {pars->Pgain=(int)o->value(); +formantfiltergraph->redraw(); +pars->changed=true;} + tooltip {Filter output gain/damp} xywh {250 35 20 20} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + code0 {o->value(pars->Pgain);} + class WidgetPDial + } + Fl_Choice stcounter { + label St + callback {pars->Pstages=(int)o->value(); +formantfiltergraph->redraw(); +pars->changed=true;} open + tooltip {Filter stages (in order to increase dB/oct. value and the order of the filter)} xywh {235 5 35 15} down_box BORDER_BOX labelsize 10 textfont 1 textsize 10 + code1 {for (int i=0;iadd(tmp);};} + code2 {o->value(pars->Pstages);} + } {} + } + Fl_Button editbutton { + label Edit + callback {formantparswindow->show();} + xywh {15 40 50 25} box PLASTIC_UP_BOX labelfont 1 labelsize 11 + } + Fl_Button {} { + label C + callback {presetsui->copy(pars);} + xywh {186 5 15 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 10 labelcolor 7 + } + Fl_Button {} { + label P + callback {presetsui->paste(pars,this);} + xywh {203 5 15 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 10 labelcolor 7 + } + } + } + Function {make_formant_window()} {} { + Fl_Window formantparswindow { + label {Formant Filter Parameters} + xywh {47 301 700 205} type Double hide + } { + Fl_Group {} { + xywh {485 47 105 113} box THIN_UP_BOX + } { + Fl_Counter {} { + label {Formant } + callback {nformant=(int) o->value(); +update_formant_window(); +formantfiltergraph->redraw();} + xywh {545 80 40 15} type Simple labelfont 1 labelsize 10 align 4 minimum 0 maximum 127 step 1 textsize 10 + code0 {o->bounds(0,FF_MAX_FORMANTS-1);} + code1 {o->value(nformant);} + } + Fl_Counter {} { + label {Vowel no.} + callback {nvowel=(int) o->value(); +update_formant_window(); +formantfiltergraph->redraw();} + xywh {545 55 40 20} type Simple labelfont 1 labelsize 10 align 4 minimum 0 maximum 127 step 1 textfont 1 textsize 11 + code0 {o->bounds(0,FF_MAX_VOWELS-1);} + code1 {o->value(nvowel);} + } + Fl_Group formantparsgroup { + xywh {490 105 95 50} box ENGRAVED_FRAME + } { + Fl_Dial formant_freq_dial { + label freq + callback {pars->Pvowels[nvowel].formants[nformant].freq=(int) o->value(); +formantfiltergraph->redraw(); +pars->changed=true;} + tooltip {Formant frequency} xywh {495 115 25 25} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + class WidgetPDial + } + Fl_Dial formant_q_dial { + label Q + callback {pars->Pvowels[nvowel].formants[nformant].q=(int) o->value(); +formantfiltergraph->redraw(); +pars->changed=true;} + tooltip {Formant's Q} xywh {525 115 24 25} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + class WidgetPDial + } + Fl_Dial formant_amp_dial { + label amp + callback {pars->Pvowels[nvowel].formants[nformant].amp=(int) o->value(); +formantfiltergraph->redraw(); +pars->changed=true;} + tooltip {Formant amplitude} xywh {555 115 24 25} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + class WidgetPDial + } + } + } + Fl_Group {} { + xywh {590 47 100 113} box THIN_UP_BOX + } { + Fl_Counter {} { + label {Seq.Size} + callback {pars->Psequencesize=(int) o->value(); +update_formant_window(); +pars->changed=true;} + xywh {595 62 55 20} type Simple labelfont 1 labelsize 10 align 5 minimum 0 maximum 127 step 1 textfont 1 textsize 11 + code0 {o->bounds(1,FF_MAX_SEQUENCE-1);} + code1 {o->value(pars->Psequencesize);} + } + Fl_Counter {} { + label {S.Pos.} + callback {nseqpos=(int) o->value(); +update_formant_window(); +pars->changed=true;} + tooltip {Current position from the sequence} xywh {595 97 40 15} type Simple labelfont 1 labelsize 10 align 9 minimum 0 maximum 127 step 1 textsize 10 + code0 {o->bounds(0,FF_MAX_SEQUENCE-2);} + code1 {o->value(nseqpos);} + } + Fl_Counter vowel_counter { + label Vowel + callback {pars->Psequence[nseqpos].nvowel=(int) o->value(); +pars->changed=true;} + xywh {640 97 40 15} type Simple labelsize 10 align 1 minimum 0 maximum 127 step 1 textsize 10 + code0 {o->bounds(0,FF_MAX_VOWELS-1);} + } + Fl_Check_Button {} { + label {Neg.Input} + callback {pars->Psequencereversed=(int) o->value(); +pars->changed=true;} + tooltip {Negate the input from LFO/envelopes/etc.} xywh {625 132 60 20} down_box DOWN_BOX labelsize 10 + code0 {o->value(pars->Psequencereversed);} + } + Fl_Dial strchdial { + label Strch + callback {pars->Psequencestretch=(int) o->value(); +pars->changed=true;} + tooltip {Sequence Stretch} xywh {595 130 25 25} box ROUND_UP_BOX labelsize 10 align 1 maximum 127 step 1 + code0 {o->value(pars->Psequencestretch);} + class WidgetPDial + } + } + Fl_Counter {} { + label {Num.Formants} + callback {pars->Pnumformants=(int) o->value(); +update_formant_window(); +pars->changed=true; +formantfiltergraph->redraw();} + xywh {485 15 65 20} type Simple labelfont 1 labelsize 10 align 5 minimum 0 maximum 127 step 1 + code0 {o->bounds(1,FF_MAX_FORMANTS);} + code1 {o->value(pars->Pnumformants);} + } + Fl_Dial frsldial { + label {Fr.Sl.} + callback {pars->Pformantslowness=(int) o->value(); +pars->changed=true;} + tooltip {Formant's Slowness (Morphing)} xywh {565 15 25 25} box ROUND_UP_BOX labelfont 1 labelsize 10 align 1 maximum 127 step 1 + code0 {o->value(pars->Pformantslowness);} + class WidgetPDial + } + Fl_Value_Output centerfreqvo { + label {C.f.} + callback {o->value(pars->getcenterfreq()/1000.0);} + tooltip {Center Frequency (kHz)} xywh {515 164 33 18} when 3 minimum 1 maximum 10 step 0.01 value 1 textfont 1 + code0 {o->value(pars->getcenterfreq()/1000.0);} + } + Fl_Value_Output octavesfreqvo { + label {Oct.} + callback {o->value(pars->getoctavesfreq());} + tooltip {No. of octaves} xywh {515 182 33 18} when 3 minimum 1 maximum 127 step 1 value 5 textfont 1 + code0 {o->value(pars->getoctavesfreq());} + } + Fl_Slider cfknob { + callback {pars->Pcenterfreq=(int)o->value(); +centerfreqvo->do_callback(); +formantfiltergraph->redraw(); +pars->changed=true;} + xywh {551 167 84 15} type {Horz Knob} box FLAT_BOX maximum 127 + code0 {o->value(pars->Pcenterfreq);} + } + Fl_Slider octknob { + callback {pars->Poctavesfreq=(int)o->value(); +octavesfreqvo->do_callback(); +formantfiltergraph->redraw();} + xywh {551 185 84 15} type {Horz Knob} box FLAT_BOX maximum 127 + code0 {o->value(pars->Poctavesfreq);} + } + Fl_Box formantfiltergraph { + xywh {5 5 475 195} box BORDER_BOX + code0 {o->init(pars,&nvowel,&nformant);} + class FormantFilterGraph + } + Fl_Dial wvknob { + label {Vw.Cl.} + callback {pars->Pvowelclearness=(int) o->value(); +pars->changed=true;} + tooltip {Vowel "clearness" (how the mixed vowels are avoided)} xywh {600 15 25 25} box ROUND_UP_BOX labelfont 1 labelsize 10 align 1 maximum 127 step 1 + code0 {o->value(pars->Pvowelclearness);} + class WidgetPDial + } + Fl_Button {} { + label Close + callback {formantparswindow->hide();} + xywh {645 180 50 25} box THIN_UP_BOX + } + Fl_Button {} { + label C + callback {presetsui->copy(pars,nvowel);} + xywh {635 25 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 11 labelcolor 7 + } + Fl_Button {} { + label P + callback {presetsui->paste(pars,this,nvowel);} + xywh {665 25 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 11 labelcolor 7 + } + Fl_Box {} { + label Vowel + xywh {635 10 55 15} + } + } + } + Function {update_formant_window()} {} { + code {formant_freq_dial->value(pars->Pvowels[nvowel].formants[nformant].freq); +formant_q_dial->value(pars->Pvowels[nvowel].formants[nformant].q); +formant_amp_dial->value(pars->Pvowels[nvowel].formants[nformant].amp); +if (nformantPnumformants) formantparsgroup->activate(); + else formantparsgroup->deactivate(); + +if (nseqposPsequencesize) vowel_counter->activate(); + else vowel_counter->deactivate(); + + +vowel_counter->value(pars->Psequence[nseqpos].nvowel);} {} + } + Function {refresh()} {} { + code {update_formant_window(); +formantfiltergraph->redraw(); + +if (pars->Pcategory==0) svfiltertypechoice->value(pars->Ptype); +if (pars->Pcategory==2) analogfiltertypechoice->value(pars->Ptype); + +filtertype->value(pars->Pcategory); + +cfreqdial->value(pars->Pfreq); +qdial->value(pars->Pq); + +freqtrdial->value(pars->Pfreqtrack); +gaindial->value(pars->Pgain); + +stcounter->value(pars->Pstages); + +int categ=pars->Pcategory; +if ((categ==0)||(categ==2)) { + if (categ==0) { + analogfiltertypechoice->show(); + svfiltertypechoice->hide(); + } else { + svfiltertypechoice->show(); + analogfiltertypechoice->hide(); + }; + editbutton->hide(); + formantparswindow->hide(); + cfreqdial->label("C.freq"); +} else { + analogfiltertypechoice->hide(); + svfiltertypechoice->hide(); + editbutton->show(); + cfreqdial->label("BS.pos"); +}; + +filterparamswindow->redraw();} {selected + } + } + Function {init(FilterParams *filterpars_,unsigned char *velsnsamp_,unsigned char *velsns_)} {} { + code {pars=filterpars_; +velsnsamp=velsnsamp_; +velsns=velsns_; + +make_window(); +end(); +make_formant_window(); + + +filterui->resize(this->x(),this->y(),this->w(),this->h()); + + +if (velsnsamp==NULL){ + vsnsadial->deactivate(); + vsnsadial->value(127); + } else vsnsadial->value(*velsnsamp); + +if (velsns==NULL){ + vsnsdial->deactivate(); + vsnsdial->value(127); + } else vsnsdial->value(*velsns); + +switchcategory(pars->Pcategory); + + +formantparswindow->label(this->label()); + +update_formant_window();} {} + } + Function {switchcategory(int newcat)} {} { + code {if (pars->Pcategory!=newcat){ + pars->Pgain=64; + gaindial->value(64); + analogfiltertypechoice->value(0); + analogfiltertypechoice->do_callback(); + svfiltertypechoice->value(0); + svfiltertypechoice->do_callback(); +}; +pars->Pcategory=newcat; + +refresh();} {} + } + Function {use_for_dynamic_filter()} {} { + code {freqtrdial->deactivate(); +gaindial->when(0); + +cfknob->when(FL_WHEN_RELEASE); +octknob->when(FL_WHEN_RELEASE); + +frsldial->when(0); +wvknob->when(0); +formant_freq_dial->when(0); +formant_q_dial->when(0); +formant_amp_dial->when(0); +strchdial->when(0);} {} + } + decl {FilterParams *pars;} {} + decl {unsigned char *velsnsamp,*velsns;} {} + decl {int nvowel,nformant,nseqpos;} {} +} diff --git a/plugins/zynaddsubfx/src/UI/FilterUI.h b/plugins/zynaddsubfx/src/UI/FilterUI.h new file mode 100644 index 000000000..573eac7e6 --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/FilterUI.h @@ -0,0 +1,198 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0109 + +#ifndef FilterUI_h +#define FilterUI_h +#include +#include "WidgetPDial.h" +#include +#include +#include "../globals.h" +#include +#include "../Params/FilterParams.h" +#include +#include +#include +#include "PresetsUI.h" + +class FormantFilterGraph : public Fl_Box { +public: + FormantFilterGraph(int x,int y, int w, int h, const char *label=0); + void init(FilterParams *pars_,int *nvowel_,int *nformant_); + void draw_freq_line(REALTYPE freq,int type); + void draw(); + ~FormantFilterGraph(); +private: + FilterParams *pars; + int oldx,oldy; + int *nvowel,*nformant; + REALTYPE *graphpoints; +}; +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class FilterUI : public Fl_Group,PresetsUI_ { +public: + FilterUI(int x,int y, int w, int h, const char *label=0); + ~FilterUI(); + Fl_Group* make_window(); + Fl_Group *filterui; + Fl_Group *filterparamswindow; + Fl_Choice *analogfiltertypechoice; +private: + void cb_analogfiltertypechoice_i(Fl_Choice*, void*); + static void cb_analogfiltertypechoice(Fl_Choice*, void*); + static Fl_Menu_Item menu_analogfiltertypechoice[]; +public: + Fl_Choice *svfiltertypechoice; +private: + void cb_svfiltertypechoice_i(Fl_Choice*, void*); + static void cb_svfiltertypechoice(Fl_Choice*, void*); + static Fl_Menu_Item menu_svfiltertypechoice[]; +public: + Fl_Choice *filtertype; +private: + void cb_filtertype_i(Fl_Choice*, void*); + static void cb_filtertype(Fl_Choice*, void*); + static Fl_Menu_Item menu_filtertype[]; +public: + WidgetPDial *cfreqdial; +private: + void cb_cfreqdial_i(WidgetPDial*, void*); + static void cb_cfreqdial(WidgetPDial*, void*); +public: + WidgetPDial *qdial; +private: + void cb_qdial_i(WidgetPDial*, void*); + static void cb_qdial(WidgetPDial*, void*); +public: + WidgetPDial *freqtrdial; +private: + void cb_freqtrdial_i(WidgetPDial*, void*); + static void cb_freqtrdial(WidgetPDial*, void*); +public: + WidgetPDial *vsnsadial; +private: + void cb_vsnsadial_i(WidgetPDial*, void*); + static void cb_vsnsadial(WidgetPDial*, void*); +public: + WidgetPDial *vsnsdial; +private: + void cb_vsnsdial_i(WidgetPDial*, void*); + static void cb_vsnsdial(WidgetPDial*, void*); +public: + WidgetPDial *gaindial; +private: + void cb_gaindial_i(WidgetPDial*, void*); + static void cb_gaindial(WidgetPDial*, void*); +public: + Fl_Choice *stcounter; +private: + void cb_stcounter_i(Fl_Choice*, void*); + static void cb_stcounter(Fl_Choice*, void*); +public: + Fl_Button *editbutton; +private: + void cb_editbutton_i(Fl_Button*, void*); + static void cb_editbutton(Fl_Button*, void*); + void cb_C_i(Fl_Button*, void*); + static void cb_C(Fl_Button*, void*); + void cb_P_i(Fl_Button*, void*); + static void cb_P(Fl_Button*, void*); +public: + Fl_Double_Window* make_formant_window(); + Fl_Double_Window *formantparswindow; +private: + void cb_Formant_i(Fl_Counter*, void*); + static void cb_Formant(Fl_Counter*, void*); + void cb_Vowel_i(Fl_Counter*, void*); + static void cb_Vowel(Fl_Counter*, void*); +public: + Fl_Group *formantparsgroup; + WidgetPDial *formant_freq_dial; +private: + void cb_formant_freq_dial_i(WidgetPDial*, void*); + static void cb_formant_freq_dial(WidgetPDial*, void*); +public: + WidgetPDial *formant_q_dial; +private: + void cb_formant_q_dial_i(WidgetPDial*, void*); + static void cb_formant_q_dial(WidgetPDial*, void*); +public: + WidgetPDial *formant_amp_dial; +private: + void cb_formant_amp_dial_i(WidgetPDial*, void*); + static void cb_formant_amp_dial(WidgetPDial*, void*); + void cb_Seq_i(Fl_Counter*, void*); + static void cb_Seq(Fl_Counter*, void*); + void cb_S_i(Fl_Counter*, void*); + static void cb_S(Fl_Counter*, void*); +public: + Fl_Counter *vowel_counter; +private: + void cb_vowel_counter_i(Fl_Counter*, void*); + static void cb_vowel_counter(Fl_Counter*, void*); + void cb_Neg_i(Fl_Check_Button*, void*); + static void cb_Neg(Fl_Check_Button*, void*); +public: + WidgetPDial *strchdial; +private: + void cb_strchdial_i(WidgetPDial*, void*); + static void cb_strchdial(WidgetPDial*, void*); + void cb_Num_i(Fl_Counter*, void*); + static void cb_Num(Fl_Counter*, void*); +public: + WidgetPDial *frsldial; +private: + void cb_frsldial_i(WidgetPDial*, void*); + static void cb_frsldial(WidgetPDial*, void*); +public: + Fl_Value_Output *centerfreqvo; +private: + void cb_centerfreqvo_i(Fl_Value_Output*, void*); + static void cb_centerfreqvo(Fl_Value_Output*, void*); +public: + Fl_Value_Output *octavesfreqvo; +private: + void cb_octavesfreqvo_i(Fl_Value_Output*, void*); + static void cb_octavesfreqvo(Fl_Value_Output*, void*); +public: + Fl_Slider *cfknob; +private: + void cb_cfknob_i(Fl_Slider*, void*); + static void cb_cfknob(Fl_Slider*, void*); +public: + Fl_Slider *octknob; +private: + void cb_octknob_i(Fl_Slider*, void*); + static void cb_octknob(Fl_Slider*, void*); +public: + FormantFilterGraph *formantfiltergraph; + WidgetPDial *wvknob; +private: + void cb_wvknob_i(WidgetPDial*, void*); + static void cb_wvknob(WidgetPDial*, void*); + void cb_Close_i(Fl_Button*, void*); + static void cb_Close(Fl_Button*, void*); + void cb_C1_i(Fl_Button*, void*); + static void cb_C1(Fl_Button*, void*); + void cb_P1_i(Fl_Button*, void*); + static void cb_P1(Fl_Button*, void*); +public: + void update_formant_window(); + void refresh(); + void init(FilterParams *filterpars_,unsigned char *velsnsamp_,unsigned char *velsns_); + void switchcategory(int newcat); + void use_for_dynamic_filter(); +private: + FilterParams *pars; + unsigned char *velsnsamp,*velsns; + int nvowel,nformant,nseqpos; +}; +#endif diff --git a/plugins/zynaddsubfx/src/UI/LFOUI.cc b/plugins/zynaddsubfx/src/UI/LFOUI.cc new file mode 100644 index 000000000..216b52c39 --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/LFOUI.cc @@ -0,0 +1,289 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0109 + +#include "LFOUI.h" +//Copyright (c) 2002-2005 Nasca Octavian Paul +//License: GNU GPL version 2 or later + +void LFOUI::cb_freq_i(WidgetPDial* o, void*) { + pars->Pfreq=o->value(); +} +void LFOUI::cb_freq(WidgetPDial* o, void* v) { + ((LFOUI*)(o->parent()->parent()->user_data()))->cb_freq_i(o,v); +} + +void LFOUI::cb_intensity_i(WidgetPDial* o, void*) { + pars->Pintensity=(int)o->value(); +} +void LFOUI::cb_intensity(WidgetPDial* o, void* v) { + ((LFOUI*)(o->parent()->parent()->user_data()))->cb_intensity_i(o,v); +} + +void LFOUI::cb_delay_i(WidgetPDial* o, void*) { + pars->Pdelay=(int)o->value(); +} +void LFOUI::cb_delay(WidgetPDial* o, void* v) { + ((LFOUI*)(o->parent()->parent()->user_data()))->cb_delay_i(o,v); +} + +void LFOUI::cb_startphase_i(WidgetPDial* o, void*) { + pars->Pstartphase=(int)o->value(); +} +void LFOUI::cb_startphase(WidgetPDial* o, void* v) { + ((LFOUI*)(o->parent()->parent()->user_data()))->cb_startphase_i(o,v); +} + +void LFOUI::cb_randomness_i(WidgetPDial* o, void*) { + pars->Prandomness=(int)o->value(); +} +void LFOUI::cb_randomness(WidgetPDial* o, void* v) { + ((LFOUI*)(o->parent()->parent()->user_data()))->cb_randomness_i(o,v); +} + +void LFOUI::cb_LFOtype_i(Fl_Choice* o, void*) { + pars->PLFOtype=(int)o->value(); +} +void LFOUI::cb_LFOtype(Fl_Choice* o, void* v) { + ((LFOUI*)(o->parent()->parent()->user_data()))->cb_LFOtype_i(o,v); +} + +Fl_Menu_Item LFOUI::menu_LFOtype[] = { + {"SINE", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"TRI", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"SQR", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"R.up", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"R.dn", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"E1dn", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"E2dn", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void LFOUI::cb_continous_i(Fl_Check_Button* o, void*) { + pars->Pcontinous=(int)o->value(); +} +void LFOUI::cb_continous(Fl_Check_Button* o, void* v) { + ((LFOUI*)(o->parent()->parent()->user_data()))->cb_continous_i(o,v); +} + +void LFOUI::cb_freqrand_i(WidgetPDial* o, void*) { + pars->Pfreqrand=(int)o->value(); +} +void LFOUI::cb_freqrand(WidgetPDial* o, void* v) { + ((LFOUI*)(o->parent()->parent()->user_data()))->cb_freqrand_i(o,v); +} + +void LFOUI::cb_stretch_i(WidgetPDial* o, void*) { + pars->Pstretch=(int)o->value(); +} +void LFOUI::cb_stretch(WidgetPDial* o, void* v) { + ((LFOUI*)(o->parent()->parent()->user_data()))->cb_stretch_i(o,v); +} + +void LFOUI::cb_C_i(Fl_Button*, void*) { + presetsui->copy(pars); +} +void LFOUI::cb_C(Fl_Button* o, void* v) { + ((LFOUI*)(o->parent()->parent()->user_data()))->cb_C_i(o,v); +} + +void LFOUI::cb_P_i(Fl_Button*, void*) { + presetsui->paste(pars,this); +} +void LFOUI::cb_P(Fl_Button* o, void* v) { + ((LFOUI*)(o->parent()->parent()->user_data()))->cb_P_i(o,v); +} + +LFOUI::LFOUI(int x,int y, int w, int h, const char *label):Fl_Group(x,y,w,h,label) { + pars=NULL; +} + +LFOUI::~LFOUI() { + lfoui->hide(); +hide(); +//delete (lfoui); +} + +Fl_Group* LFOUI::make_window() { + { lfoui = new Fl_Group(0, 0, 230, 70); + lfoui->box(FL_FLAT_BOX); + lfoui->color(FL_LIGHT1); + lfoui->selection_color(FL_BACKGROUND_COLOR); + lfoui->labeltype(FL_NO_LABEL); + lfoui->labelfont(1); + lfoui->labelsize(14); + lfoui->labelcolor(FL_FOREGROUND_COLOR); + lfoui->user_data((void*)(this)); + lfoui->align(FL_ALIGN_TOP); + lfoui->when(FL_WHEN_RELEASE); + { lfoparamswindow = new Fl_Group(0, 0, 230, 70, "LFO"); + lfoparamswindow->box(FL_PLASTIC_UP_BOX); + lfoparamswindow->color(FL_CYAN); + lfoparamswindow->labeltype(FL_ENGRAVED_LABEL); + lfoparamswindow->labelsize(10); + lfoparamswindow->align(FL_ALIGN_TOP|FL_ALIGN_INSIDE); + { freq = new WidgetPDial(5, 20, 30, 30, "Freq."); + freq->tooltip("LFO Frequency"); + freq->box(FL_ROUND_UP_BOX); + freq->color(FL_BACKGROUND_COLOR); + freq->selection_color(FL_INACTIVE_COLOR); + freq->labeltype(FL_NORMAL_LABEL); + freq->labelfont(0); + freq->labelsize(10); + freq->labelcolor(FL_FOREGROUND_COLOR); + freq->step(1e-05); + freq->callback((Fl_Callback*)cb_freq); + freq->align(FL_ALIGN_BOTTOM); + freq->when(FL_WHEN_CHANGED); + } // WidgetPDial* freq + { intensity = new WidgetPDial(40, 20, 30, 30, "Depth"); + intensity->tooltip("LFO Amount"); + intensity->box(FL_ROUND_UP_BOX); + intensity->color(FL_BACKGROUND_COLOR); + intensity->selection_color(FL_INACTIVE_COLOR); + intensity->labeltype(FL_NORMAL_LABEL); + intensity->labelfont(0); + intensity->labelsize(10); + intensity->labelcolor(FL_FOREGROUND_COLOR); + intensity->maximum(127); + intensity->step(1); + intensity->callback((Fl_Callback*)cb_intensity); + intensity->align(FL_ALIGN_BOTTOM); + intensity->when(FL_WHEN_CHANGED); + } // WidgetPDial* intensity + { delay = new WidgetPDial(110, 20, 30, 30, "Delay"); + delay->tooltip("LFO delay"); + delay->box(FL_ROUND_UP_BOX); + delay->color(FL_BACKGROUND_COLOR); + delay->selection_color(FL_INACTIVE_COLOR); + delay->labeltype(FL_NORMAL_LABEL); + delay->labelfont(0); + delay->labelsize(10); + delay->labelcolor(FL_FOREGROUND_COLOR); + delay->maximum(127); + delay->step(1); + delay->callback((Fl_Callback*)cb_delay); + delay->align(FL_ALIGN_BOTTOM); + delay->when(FL_WHEN_CHANGED); + } // WidgetPDial* delay + { startphase = new WidgetPDial(75, 20, 30, 30, "Start"); + startphase->tooltip("LFO Startphase (leftmost is Random)"); + startphase->box(FL_ROUND_UP_BOX); + startphase->color(FL_BACKGROUND_COLOR); + startphase->selection_color(FL_INACTIVE_COLOR); + startphase->labeltype(FL_NORMAL_LABEL); + startphase->labelfont(0); + startphase->labelsize(10); + startphase->labelcolor(FL_FOREGROUND_COLOR); + startphase->maximum(127); + startphase->step(1); + startphase->callback((Fl_Callback*)cb_startphase); + startphase->align(FL_ALIGN_BOTTOM); + startphase->when(FL_WHEN_CHANGED); + } // WidgetPDial* startphase + { randomness = new WidgetPDial(180, 7, 20, 20, "A.R."); + randomness->tooltip("LFO Amplitude Randomness"); + randomness->box(FL_ROUND_UP_BOX); + randomness->color(FL_BACKGROUND_COLOR); + randomness->selection_color(FL_INACTIVE_COLOR); + randomness->labeltype(FL_NORMAL_LABEL); + randomness->labelfont(0); + randomness->labelsize(10); + randomness->labelcolor(FL_FOREGROUND_COLOR); + randomness->maximum(127); + randomness->step(1); + randomness->callback((Fl_Callback*)cb_randomness); + randomness->align(FL_ALIGN_BOTTOM); + randomness->when(FL_WHEN_CHANGED); + } // WidgetPDial* randomness + { LFOtype = new Fl_Choice(180, 40, 45, 15, "Type"); + LFOtype->tooltip("LFO function"); + LFOtype->down_box(FL_BORDER_BOX); + LFOtype->labelsize(10); + LFOtype->textsize(8); + LFOtype->callback((Fl_Callback*)cb_LFOtype); + LFOtype->align(FL_ALIGN_BOTTOM); + LFOtype->menu(menu_LFOtype); + } // Fl_Choice* LFOtype + { continous = new Fl_Check_Button(165, 35, 15, 15, "C."); + continous->tooltip("Continous LFO"); + continous->down_box(FL_DOWN_BOX); + continous->labelsize(10); + continous->callback((Fl_Callback*)cb_continous); + continous->align(FL_ALIGN_BOTTOM); + } // Fl_Check_Button* continous + { freqrand = new WidgetPDial(205, 7, 20, 20, "F.R."); + freqrand->tooltip("LFO Frequency Randomness"); + freqrand->box(FL_ROUND_UP_BOX); + freqrand->color(FL_BACKGROUND_COLOR); + freqrand->selection_color(FL_INACTIVE_COLOR); + freqrand->labeltype(FL_NORMAL_LABEL); + freqrand->labelfont(0); + freqrand->labelsize(10); + freqrand->labelcolor(FL_FOREGROUND_COLOR); + freqrand->maximum(127); + freqrand->step(1); + freqrand->callback((Fl_Callback*)cb_freqrand); + freqrand->align(FL_ALIGN_BOTTOM); + freqrand->when(FL_WHEN_CHANGED); + } // WidgetPDial* freqrand + { stretch = new WidgetPDial(144, 30, 20, 20, "Str."); + stretch->tooltip("LFO stretch"); + stretch->box(FL_ROUND_UP_BOX); + stretch->color(FL_BACKGROUND_COLOR); + stretch->selection_color(FL_INACTIVE_COLOR); + stretch->labeltype(FL_NORMAL_LABEL); + stretch->labelfont(0); + stretch->labelsize(10); + stretch->labelcolor(FL_FOREGROUND_COLOR); + stretch->maximum(127); + stretch->step(1); + stretch->callback((Fl_Callback*)cb_stretch); + stretch->align(FL_ALIGN_BOTTOM); + stretch->when(FL_WHEN_CHANGED); + } // WidgetPDial* stretch + { Fl_Button* o = new Fl_Button(145, 10, 15, 15, "C"); + o->box(FL_THIN_UP_BOX); + o->color((Fl_Color)179); + o->labelfont(1); + o->labelsize(10); + o->labelcolor(FL_BACKGROUND2_COLOR); + o->callback((Fl_Callback*)cb_C); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(162, 10, 15, 15, "P"); + o->box(FL_THIN_UP_BOX); + o->color((Fl_Color)179); + o->labelfont(1); + o->labelsize(10); + o->labelcolor(FL_BACKGROUND2_COLOR); + o->callback((Fl_Callback*)cb_P); + } // Fl_Button* o + lfoparamswindow->end(); + } // Fl_Group* lfoparamswindow + lfoui->end(); + } // Fl_Group* lfoui + return lfoui; +} + +void LFOUI::refresh() { + freq->value(pars->Pfreq); +intensity->value(pars->Pintensity); +startphase->value(pars->Pstartphase); +delay->value(pars->Pdelay); +continous->value(pars->Pcontinous); +stretch->value(pars->Pstretch); +randomness->value(pars->Prandomness); +freqrand->value(pars->Pfreqrand); +LFOtype->value(pars->PLFOtype); +} + +void LFOUI::init(LFOParams *lfopars_) { + pars=lfopars_; + +make_window(); +end(); + +refresh(); + +lfoui->resize(this->x(),this->y(),this->w(),this->h()); + +lfoparamswindow->label(this->label()); +} diff --git a/plugins/zynaddsubfx/src/UI/LFOUI.fl b/plugins/zynaddsubfx/src/UI/LFOUI.fl new file mode 100644 index 000000000..ca0433a2d --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/LFOUI.fl @@ -0,0 +1,176 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0105 +header_name {.h} +code_name {.cc} +decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} + +decl {//License: GNU GPL version 2 or later} {} + +decl {\#include "WidgetPDial.h"} {public +} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include "../globals.h"} {public +} + +decl {\#include } {public +} + +decl {\#include "../Params/LFOParams.h"} {public +} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include "PresetsUI.h"} {public +} + +class LFOUI {: {public Fl_Group, PresetsUI_} +} { + Function {LFOUI(int x,int y, int w, int h, const char *label=0):Fl_Group(x,y,w,h,label)} {} { + code {pars=NULL;} {} + } + Function {~LFOUI()} {} { + code {lfoui->hide(); +hide(); +//delete (lfoui);} {} + } + Function {make_window()} {} { + Fl_Window lfoui { + xywh {66 328 230 70} type Double color 50 labelfont 1 hide + class Fl_Group + } { + Fl_Group lfoparamswindow { + label LFO + xywh {0 0 230 70} box PLASTIC_UP_BOX color 223 labeltype ENGRAVED_LABEL labelsize 10 align 17 + } { + Fl_Dial freq { + label {Freq.} + callback {pars->Pfreq=o->value();} + tooltip {LFO Frequency} xywh {5 20 30 30} box ROUND_UP_BOX labelsize 10 step 1e-05 + class WidgetPDial + } + Fl_Dial intensity { + label Depth + callback {pars->Pintensity=(int)o->value();} + tooltip {LFO Amount} xywh {40 20 30 30} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + class WidgetPDial + } + Fl_Dial delay { + label Delay + callback {pars->Pdelay=(int)o->value();} + tooltip {LFO delay} xywh {110 20 30 30} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + class WidgetPDial + } + Fl_Dial startphase { + label Start + callback {pars->Pstartphase=(int)o->value();} + tooltip {LFO Startphase (leftmost is Random)} xywh {75 20 30 30} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + class WidgetPDial + } + Fl_Dial randomness { + label {A.R.} + callback {pars->Prandomness=(int)o->value();} + tooltip {LFO Amplitude Randomness} xywh {180 7 20 20} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + class WidgetPDial + } + Fl_Choice LFOtype { + label Type + callback {pars->PLFOtype=(int)o->value();} + tooltip {LFO function} xywh {180 40 45 15} down_box BORDER_BOX labelsize 10 align 2 textsize 8 + } { + menuitem {} { + label SINE + xywh {20 20 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label TRI + xywh {30 30 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label SQR + xywh {30 30 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label {R.up} + xywh {40 40 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label {R.dn} + xywh {50 50 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label E1dn + xywh {60 60 100 20} labelfont 1 labelsize 10 + } + menuitem {} { + label E2dn + xywh {70 70 100 20} labelfont 1 labelsize 10 + } + } + Fl_Check_Button continous { + label {C.} + callback {pars->Pcontinous=(int)o->value();} + tooltip {Continous LFO} xywh {165 35 15 15} down_box DOWN_BOX labelsize 10 align 2 + } + Fl_Dial freqrand { + label {F.R.} + callback {pars->Pfreqrand=(int)o->value();} + tooltip {LFO Frequency Randomness} xywh {205 7 20 20} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + class WidgetPDial + } + Fl_Dial stretch { + label {Str.} + callback {pars->Pstretch=(int)o->value();} + tooltip {LFO stretch} xywh {144 30 20 20} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + class WidgetPDial + } + Fl_Button {} { + label C + callback {presetsui->copy(pars);} selected + xywh {145 10 15 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 10 labelcolor 7 + } + Fl_Button {} { + label P + callback {presetsui->paste(pars,this);} selected + xywh {162 10 15 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 10 labelcolor 7 + } + } + } + } + Function {refresh()} {} { + code {freq->value(pars->Pfreq); +intensity->value(pars->Pintensity); +startphase->value(pars->Pstartphase); +delay->value(pars->Pdelay); +continous->value(pars->Pcontinous); +stretch->value(pars->Pstretch); +randomness->value(pars->Prandomness); +freqrand->value(pars->Pfreqrand); +LFOtype->value(pars->PLFOtype);} {} + } + Function {init(LFOParams *lfopars_)} {} { + code {pars=lfopars_; + +make_window(); +end(); + +refresh(); + +lfoui->resize(this->x(),this->y(),this->w(),this->h()); + +lfoparamswindow->label(this->label());} {} + } + decl {LFOParams *pars;} {} +} diff --git a/plugins/zynaddsubfx/src/UI/LFOUI.h b/plugins/zynaddsubfx/src/UI/LFOUI.h new file mode 100644 index 000000000..e5497ac1f --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/LFOUI.h @@ -0,0 +1,83 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0109 + +#ifndef LFOUI_h +#define LFOUI_h +#include +#include "WidgetPDial.h" +#include +#include +#include "../globals.h" +#include +#include "../Params/LFOParams.h" +#include +#include +#include +#include "PresetsUI.h" +#include +#include +#include +#include + +class LFOUI : public Fl_Group, PresetsUI_ { +public: + LFOUI(int x,int y, int w, int h, const char *label=0); + ~LFOUI(); + Fl_Group* make_window(); + Fl_Group *lfoui; + Fl_Group *lfoparamswindow; + WidgetPDial *freq; +private: + void cb_freq_i(WidgetPDial*, void*); + static void cb_freq(WidgetPDial*, void*); +public: + WidgetPDial *intensity; +private: + void cb_intensity_i(WidgetPDial*, void*); + static void cb_intensity(WidgetPDial*, void*); +public: + WidgetPDial *delay; +private: + void cb_delay_i(WidgetPDial*, void*); + static void cb_delay(WidgetPDial*, void*); +public: + WidgetPDial *startphase; +private: + void cb_startphase_i(WidgetPDial*, void*); + static void cb_startphase(WidgetPDial*, void*); +public: + WidgetPDial *randomness; +private: + void cb_randomness_i(WidgetPDial*, void*); + static void cb_randomness(WidgetPDial*, void*); +public: + Fl_Choice *LFOtype; +private: + void cb_LFOtype_i(Fl_Choice*, void*); + static void cb_LFOtype(Fl_Choice*, void*); + static Fl_Menu_Item menu_LFOtype[]; +public: + Fl_Check_Button *continous; +private: + void cb_continous_i(Fl_Check_Button*, void*); + static void cb_continous(Fl_Check_Button*, void*); +public: + WidgetPDial *freqrand; +private: + void cb_freqrand_i(WidgetPDial*, void*); + static void cb_freqrand(WidgetPDial*, void*); +public: + WidgetPDial *stretch; +private: + void cb_stretch_i(WidgetPDial*, void*); + static void cb_stretch(WidgetPDial*, void*); + void cb_C_i(Fl_Button*, void*); + static void cb_C(Fl_Button*, void*); + void cb_P_i(Fl_Button*, void*); + static void cb_P(Fl_Button*, void*); +public: + void refresh(); + void init(LFOParams *lfopars_); +private: + LFOParams *pars; +}; +#endif diff --git a/plugins/zynaddsubfx/src/UI/MasterUI.cc b/plugins/zynaddsubfx/src/UI/MasterUI.cc new file mode 100644 index 000000000..80adb2584 --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/MasterUI.cc @@ -0,0 +1,2494 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0109 + +#include "MasterUI.h" +//Copyright (c) 2002-2005 Nasca Octavian Paul +//License: GNU GPL version 2 or later + +VUMeter::VUMeter(int x,int y, int w, int h, const char *label):Fl_Box(x,y,w,h,label) { + master=NULL; +npart=-1; +} + +void VUMeter::init(Master *master_,int part_) { + //the "part_" parameters sets the part (if it is >=0), else it sets the master +master=master_; +label(NULL); +npart=part_; +olddbl=0.0; +olddbr=0.0; +oldrmsdbl=0.0; +oldrmsdbr=0.0; +} + +void VUMeter::draw_master() { + #define MIN_DB (-48) + +int ox=x(); int oy=y(); int lx=w(); int ly=h(); + +pthread_mutex_lock(&master->mutex); +REALTYPE dbl=rap2dB(master->vuoutpeakl); +REALTYPE dbr=rap2dB(master->vuoutpeakr); +REALTYPE rmsdbl=rap2dB(master->vurmspeakl); +REALTYPE rmsdbr=rap2dB(master->vurmspeakr); +REALTYPE maxdbl=rap2dB(master->vumaxoutpeakl); +REALTYPE maxdbr=rap2dB(master->vumaxoutpeakr); +int clipped=master->vuclipped; +pthread_mutex_unlock(&master->mutex); + +dbl=(MIN_DB-dbl)/MIN_DB; +if (dbl<0.0) dbl=0.0; + else if (dbl>1.0)dbl=1.0; + +dbr=(MIN_DB-dbr)/MIN_DB; +if (dbr<0.0) dbr=0.0; + else if (dbr>1.0) dbr=1.0; + +dbl=dbl*0.4+olddbl*0.6; +dbr=dbr*0.4+olddbr*0.6; + +olddbl=dbl; +olddbr=dbr; + +#define VULENX (lx-35) +#define VULENY (ly/2-3) + +dbl*=VULENX;dbr*=VULENX; + +int idbl=(int) dbl; +int idbr=(int) dbr; + +//compute RMS - start +rmsdbl=(MIN_DB-rmsdbl)/MIN_DB; +if (rmsdbl<0.0) rmsdbl=0.0; + else if (rmsdbl>1.0) rmsdbl=1.0; + +rmsdbr=(MIN_DB-rmsdbr)/MIN_DB; +if (rmsdbr<0.0) rmsdbr=0.0; + else if (rmsdbr>1.0) rmsdbr=1.0; + +rmsdbl=rmsdbl*0.4+oldrmsdbl*0.6; +rmsdbr=rmsdbr*0.4+oldrmsdbr*0.6; + +oldrmsdbl=rmsdbl; +oldrmsdbr=rmsdbr; + + +rmsdbl*=VULENX;rmsdbr*=VULENX; + +int irmsdbl=(int) rmsdbl; +int irmsdbr=(int) rmsdbr; +//compute RMS - end + + + +//draw the vu-meter lines +//db +fl_rectf(ox,oy,idbr,VULENY,0,200,255); +fl_rectf(ox,oy+ly/2,idbl,VULENY,0,200,255); +//black +fl_rectf(ox+idbr,oy,VULENX-idbr,VULENY,0,0,0); +fl_rectf(ox+idbl,oy+ly/2,VULENX-idbl,VULENY,0,0,0); + +//draw the scales +REALTYPE tmp=VULENX*1.0/MIN_DB; +for (int i=1;i<1-MIN_DB;i++){ + int tx=VULENX+(int) (tmp*i); + fl_rectf(ox+tx,oy,1,VULENY+ly/2,0,160,200); + if (i%5==0) fl_rectf(ox+tx,oy,1,VULENY+ly/2,0,230,240); + if (i%10==0) fl_rectf(ox+tx-1,oy,2,VULENY+ly/2,0,225,255); +}; + +//rms +if (irmsdbr>2) fl_rectf(ox+irmsdbr-1,oy,3,VULENY,255,255,0); +if (irmsdbl>2) fl_rectf(ox+irmsdbl-1,oy+ly/2,3,VULENY,255,255,0); + + +//draw the red box if clipping has occured +if (clipped==0) fl_rectf(ox+VULENX+2,oy+1,lx-VULENX-3,ly-4,0,0,10); + else fl_rectf(ox+VULENX+2,oy+1,lx-VULENX-3,ly-4,250,10,10); + +//draw the maxdB +fl_font(FL_HELVETICA|FL_BOLD,10); +fl_color(255,255,255); +char tmpstr[10]; +if ((maxdbl>MIN_DB-20)){ + snprintf((char *)&tmpstr,10,"%ddB",(int)maxdbr); + fl_draw(tmpstr,ox+VULENX+1,oy+1,lx-VULENX-1,VULENY,FL_ALIGN_RIGHT,NULL,0); +}; +if ((maxdbr>MIN_DB-20)){ + snprintf((char *)&tmpstr,10,"%ddB",(int)maxdbl); + fl_draw(tmpstr,ox+VULENX+1,oy+ly/2+1,lx-VULENX-1,VULENY,FL_ALIGN_RIGHT,NULL,0); +}; +} + +void VUMeter::draw_part() { + #define MIN_DB (-48) +int ox=x(); int oy=y(); int lx=w(); int ly=h(); + +if (!active_r()){ + pthread_mutex_lock(&master->mutex); + int fakedb=master->fakepeakpart[npart]; + pthread_mutex_unlock(&master->mutex); + fl_rectf(ox,oy,lx,ly,140,140,140); + if (fakedb>0){ + fakedb=(int)(fakedb/255.0*ly)+4; + fl_rectf(ox+2,oy+ly-fakedb,lx-4,fakedb,0,0,0); + }; + + return; +}; + +//draw the vu lines +pthread_mutex_lock(&master->mutex); + REALTYPE db=rap2dB(master->vuoutpeakpart[npart]); +pthread_mutex_unlock(&master->mutex); + +db=(MIN_DB-db)/MIN_DB; +if (db<0.0) db=0.0; + else if (db>1.0) db=1.0; + +db*=ly-2; + +int idb=(int) db; + +fl_rectf(ox,oy+ly-idb,lx,idb,0,200,255); +fl_rectf(ox,oy,lx,ly-idb,0,0,0); + + +//draw the scales +REALTYPE tmp=ly*1.0/MIN_DB; + for (int i=1;i<1-MIN_DB;i++){ + int ty=ly+(int) (tmp*i); + if (i%5==0) fl_rectf(ox,oy+ly-ty,lx,1,0,160,200); + if (i%10==0) fl_rectf(ox,oy+ly-ty,lx,1,0,230,240); +}; +} + +void VUMeter::draw() { + if (npart>=0) draw_part(); + else draw_master(); +} + +void VUMeter::tickdraw(VUMeter *o) { + o->redraw(); +} + +void VUMeter::tick(void *v) { + tickdraw((VUMeter *) v); +Fl::add_timeout(1.0/25.0,tick,v);//25 fps +} + +int VUMeter::handle(int event) { + switch(event){ + case FL_SHOW: + tick(this); + break; + case FL_HIDE: + Fl::remove_timeout(tick,this); + break; + case FL_PUSH: + if (npart>=0) break; + pthread_mutex_lock(&master->mutex); + master->vuresetpeaks(); + pthread_mutex_unlock(&master->mutex); + break; +}; +return(1); +} + +SysEffSend::SysEffSend(int x,int y, int w, int h, const char *label):WidgetPDial(x,y,w,h,label) { + master=NULL; +neff1=0; +neff2=0; +} + +void SysEffSend::init(Master *master_,int neff1_,int neff2_) { + neff1=neff1_; +neff2=neff2_; +master=master_; +minimum(0); +maximum(127); +step(1); +labelfont(1); +labelsize(10); +align(FL_ALIGN_TOP); + +value(master->Psysefxsend[neff1][neff2]); +char tmp[20];snprintf(tmp,20,"%d->%d",neff1+1,neff2+1);this->label(strdup(tmp)); +} + +SysEffSend::~SysEffSend() { + hide(); +} + +int SysEffSend::handle(int event) { + if ((event==FL_PUSH) || (event==FL_DRAG)){ + master->setPsysefxsend(neff1,neff2,(int) value()); +}; + +return(WidgetPDial::handle(event)); +} + +void Panellistitem::cb_partname_i(Fl_Button*, void*) { + if ((int)bankui->cbwig->value()!=(npart+1)){ + bankui->cbwig->value(npart+1); + bankui->cbwig->do_callback(); +}; +bankui->show(); +} +void Panellistitem::cb_partname(Fl_Button* o, void* v) { + ((Panellistitem*)(o->parent()->parent()->user_data()))->cb_partname_i(o,v); +} + +void Panellistitem::cb_partvolume_i(Fl_Slider* o, void*) { + master->part[npart]->setPvolume((int) o->value()); +} +void Panellistitem::cb_partvolume(Fl_Slider* o, void* v) { + ((Panellistitem*)(o->parent()->parent()->user_data()))->cb_partvolume_i(o,v); +} + +void Panellistitem::cb_partpanning_i(WidgetPDial* o, void*) { + master->part[npart]->setPpanning((int) o->value()); +} +void Panellistitem::cb_partpanning(WidgetPDial* o, void* v) { + ((Panellistitem*)(o->parent()->parent()->user_data()))->cb_partpanning_i(o,v); +} + +void Panellistitem::cb_edit_i(Fl_Button*, void*) { + if ((int)bankui->cbwig->value()!=(npart+1)){ + bankui->cbwig->value(npart+1); + bankui->cbwig->do_callback(); +}; +} +void Panellistitem::cb_edit(Fl_Button* o, void* v) { + ((Panellistitem*)(o->parent()->parent()->user_data()))->cb_edit_i(o,v); +} + +void Panellistitem::cb_partrcv_i(Fl_Choice* o, void*) { + master->part[npart]->Prcvchn=(int) o->value(); +} +void Panellistitem::cb_partrcv(Fl_Choice* o, void* v) { + ((Panellistitem*)(o->parent()->parent()->user_data()))->cb_partrcv_i(o,v); +} + +void Panellistitem::cb_partenabled_i(Fl_Check_Button* o, void*) { + pthread_mutex_lock(&master->mutex); + master->partonoff(npart,(int) o->value()); +pthread_mutex_unlock(&master->mutex); + +if ((int) o->value()==0) panellistitemgroup->deactivate(); + else { + panellistitemgroup->activate(); + if ((int)bankui->cbwig->value()!=(npart+1)){ + bankui->cbwig->value(npart+1); + bankui->cbwig->do_callback(); + }; +}; + +o->redraw(); +} +void Panellistitem::cb_partenabled(Fl_Check_Button* o, void* v) { + ((Panellistitem*)(o->parent()->user_data()))->cb_partenabled_i(o,v); +} + +Fl_Group* Panellistitem::make_window() { + { panellistitem = new Fl_Group(0, 0, 70, 260); + panellistitem->box(FL_FLAT_BOX); + panellistitem->color(FL_BACKGROUND_COLOR); + panellistitem->selection_color(FL_BACKGROUND_COLOR); + panellistitem->labeltype(FL_NO_LABEL); + panellistitem->labelfont(0); + panellistitem->labelsize(14); + panellistitem->labelcolor(FL_FOREGROUND_COLOR); + panellistitem->user_data((void*)(this)); + panellistitem->align(FL_ALIGN_TOP); + panellistitem->when(FL_WHEN_RELEASE); + { Fl_Group* o = panellistitemgroup = new Fl_Group(0, 20, 70, 240); + panellistitemgroup->box(FL_PLASTIC_THIN_UP_BOX); + { Fl_Group* o = new Fl_Group(45, 65, 15, 110); + o->box(FL_ENGRAVED_FRAME); + { VUMeter* o = new VUMeter(45, 65, 15, 110, "V U"); + o->box(FL_FLAT_BOX); + o->color(FL_FOREGROUND_COLOR); + o->selection_color((Fl_Color)75); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor((Fl_Color)55); + o->align(FL_ALIGN_WRAP); + o->when(FL_WHEN_RELEASE); + o->init(master,npart); + } // VUMeter* o + o->end(); + } // Fl_Group* o + { partname = new Fl_Button(5, 27, 60, 30, " "); + partname->box(FL_THIN_DOWN_BOX); + partname->down_box(FL_FLAT_BOX); + partname->labelfont(1); + partname->labelsize(10); + partname->callback((Fl_Callback*)cb_partname); + partname->align(192|FL_ALIGN_INSIDE); + } // Fl_Button* partname + { Fl_Slider* o = partvolume = new Fl_Slider(10, 65, 30, 110); + partvolume->type(4); + partvolume->box(FL_FLAT_BOX); + partvolume->minimum(127); + partvolume->maximum(0); + partvolume->step(1); + partvolume->value(127); + partvolume->callback((Fl_Callback*)cb_partvolume); + o->value(master->part[npart]->Pvolume); + } // Fl_Slider* partvolume + { WidgetPDial* o = partpanning = new WidgetPDial(20, 180, 30, 30); + partpanning->box(FL_OVAL_BOX); + partpanning->color(FL_BACKGROUND_COLOR); + partpanning->selection_color(FL_INACTIVE_COLOR); + partpanning->labeltype(FL_NORMAL_LABEL); + partpanning->labelfont(0); + partpanning->labelsize(14); + partpanning->labelcolor(FL_FOREGROUND_COLOR); + partpanning->maximum(127); + partpanning->step(1); + partpanning->callback((Fl_Callback*)cb_partpanning); + partpanning->align(FL_ALIGN_BOTTOM); + partpanning->when(FL_WHEN_CHANGED); + o->value(master->part[npart]->Ppanning); + } // WidgetPDial* partpanning + { Fl_Button* o = new Fl_Button(15, 235, 40, 20, "edit"); + o->box(FL_PLASTIC_UP_BOX); + o->labelsize(10); + o->callback((Fl_Callback*)cb_edit); + } // Fl_Button* o + { Fl_Choice* o = partrcv = new Fl_Choice(10, 213, 50, 15); + partrcv->tooltip("receive from Midi channel"); + partrcv->down_box(FL_BORDER_BOX); + partrcv->labelsize(10); + partrcv->textfont(1); + partrcv->textsize(10); + partrcv->callback((Fl_Callback*)cb_partrcv); + partrcv->align(FL_ALIGN_TOP_LEFT); + char nrstr[10]; for(int i=0;iadd(nrstr); else o->add("Dr10");}; + o->value(master->part[npart]->Prcvchn); + } // Fl_Choice* partrcv + if (master->part[npart]->Penabled==0) o->deactivate(); + panellistitemgroup->end(); + } // Fl_Group* panellistitemgroup + { Fl_Check_Button* o = partenabled = new Fl_Check_Button(5, 0, 45, 20, "01"); + partenabled->down_box(FL_DOWN_BOX); + partenabled->labeltype(FL_EMBOSSED_LABEL); + partenabled->labelfont(1); + partenabled->labelsize(13); + partenabled->callback((Fl_Callback*)cb_partenabled); + partenabled->align(FL_ALIGN_RIGHT|FL_ALIGN_INSIDE); + char tmp[10];snprintf(tmp,10,"%d",npart+1);o->label(strdup(tmp)); + o->value(master->part[npart]->Penabled); + } // Fl_Check_Button* partenabled + panellistitem->end(); + } // Fl_Group* panellistitem + return panellistitem; +} + +Panellistitem::Panellistitem(int x,int y, int w, int h, const char *label):Fl_Group(x,y,w,h,label) { + npart=0; +master=NULL; +bankui=NULL; +} + +void Panellistitem::init(Master *master_, int npart_,BankUI *bankui_) { + npart=npart_; +master=master_; +bankui=bankui_; + +make_window(); +panellistitem->show(); +end(); +} + +void Panellistitem::refresh() { + partenabled->value(master->part[npart]->Penabled); +if (master->part[npart]->Penabled!=0) panellistitemgroup->activate(); + else panellistitemgroup->deactivate(); + +partvolume->value(master->part[npart]->Pvolume); +partpanning->value(master->part[npart]->Ppanning); +partrcv->value(master->part[npart]->Prcvchn); + +partname->label((char *)master->part[npart]->Pname); + +if ((int)bankui->cbwig->value()!=(npart+1)) + panellistitemgroup->color(fl_rgb_color(160,160,160)); +else + panellistitemgroup->color(fl_rgb_color(50,190,240)); + +panellistitemgroup->redraw(); +} + +Panellistitem::~Panellistitem() { + panellistitem->hide(); +//delete(panellistitem); +} + +void MasterUI::cb_masterwindow_i(Fl_Double_Window*, void*) { + #ifdef VSTAUDIOOUT +fl_alert("ZynAddSubFX could not be closed this way, because it's a VST plugin. Please use the host aplication to close it."); +#else +if (fl_choice("Exit and leave the unsaved data?","No","Yes",NULL)) { + config.save(); + *exitprogram=1; +}; +#endif +} +void MasterUI::cb_masterwindow(Fl_Double_Window* o, void* v) { + ((MasterUI*)(o->user_data()))->cb_masterwindow_i(o,v); +} + +void MasterUI::cb_New_i(Fl_Menu_*, void*) { + do_new_master(); +} +void MasterUI::cb_New(Fl_Menu_* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_New_i(o,v); +} + +void MasterUI::cb_Open_i(Fl_Menu_*, void*) { + do_load_master(); +} +void MasterUI::cb_Open(Fl_Menu_* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_Open_i(o,v); +} + +void MasterUI::cb_Save_i(Fl_Menu_*, void*) { + do_save_master(); +} +void MasterUI::cb_Save(Fl_Menu_* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_Save_i(o,v); +} + +void MasterUI::cb_Load_i(Fl_Menu_*, void*) { + char *filename; +filename=fl_file_chooser("Open:","({*.xsz})",NULL,0); +if (filename==NULL) return; + +pthread_mutex_lock(&master->mutex); + //clear all parameters + master->microtonal.defaults(); + + //load the data + int result=master->microtonal.loadXML(filename); +pthread_mutex_unlock(&master->mutex); + + + delete microtonalui; + microtonalui=new MicrotonalUI(&master->microtonal); + +if (result==-10) fl_alert("Error: Could not load the file\nbecause it is not a scale file."); + else if (result<0) fl_alert("Error: Could not load the file."); +} +void MasterUI::cb_Load(Fl_Menu_* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_Load_i(o,v); +} + +void MasterUI::cb_Save1_i(Fl_Menu_*, void*) { + char *filename; +int result=0; + +filename=fl_file_chooser("Save:","({*.xsz})",NULL,0); +if (filename==NULL) return; +filename=fl_filename_setext(filename,".xsz"); + +result=fileexists(filename); +if (result) { + result=0; + if (!fl_choice("The file exists. \nOverwrite it?","No","Yes",NULL)) return; + +}; + + +pthread_mutex_lock(&master->mutex); +result=master->microtonal.saveXML(filename); +pthread_mutex_unlock(&master->mutex); + +if (result<0) fl_alert("Error: Could not save the file."); + + +updatepanel(); +} +void MasterUI::cb_Save1(Fl_Menu_* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_Save1_i(o,v); +} + +void MasterUI::cb_Show_i(Fl_Menu_*, void*) { + microtonalui->show(); +} +void MasterUI::cb_Show(Fl_Menu_* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_Show_i(o,v); +} + +void MasterUI::cb_Settings_i(Fl_Menu_*, void*) { + configui->show(); +} +void MasterUI::cb_Settings(Fl_Menu_* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_Settings_i(o,v); +} + +void MasterUI::cb_Copyright_i(Fl_Menu_*, void*) { + aboutwindow->show(); +} +void MasterUI::cb_Copyright(Fl_Menu_* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_Copyright_i(o,v); +} + +void MasterUI::cb_E_i(Fl_Menu_*, void*) { + masterwindow->do_callback(); +} +void MasterUI::cb_E(Fl_Menu_* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_E_i(o,v); +} + +void MasterUI::cb_Clear_i(Fl_Menu_*, void*) { + if (fl_choice("Clear instrument's parameters ?","No","Yes",NULL)){ +// int npart=(int)npartcounter->value()-1; + pthread_mutex_lock(&master->mutex); + master->part[npart]->defaultsinstrument(); + pthread_mutex_unlock(&master->mutex); + + npartcounter->do_callback(); +}; + +updatepanel(); +} +void MasterUI::cb_Clear(Fl_Menu_* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_Clear_i(o,v); +} + +void MasterUI::cb_Open1_i(Fl_Menu_*, void*) { + const char *filename; +filename=fl_file_chooser("Load:","({*.xiz})",NULL,0); +if (filename==NULL) return; + + +pthread_mutex_lock(&master->mutex); +// int npart=(int)npartcounter->value()-1; + + //clear all instrument parameters, first + master->part[npart]->defaultsinstrument(); + + //load the instr. parameters + int result=master->part[npart]->loadXMLinstrument(filename); + +pthread_mutex_unlock(&master->mutex); +master->part[npart]->applyparameters(); + +npartcounter->do_callback(); +updatepanel(); + +if (result==-10) fl_alert("Error: Could not load the file\nbecause it is not an instrument file."); + else if (result<0) fl_alert("Error: Could not load the file."); +} +void MasterUI::cb_Open1(Fl_Menu_* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_Open1_i(o,v); +} + +void MasterUI::cb_Save2_i(Fl_Menu_*, void*) { + char *filename; + +filename=fl_file_chooser("Save:","({*.xiz})",NULL,0); +if (filename==NULL) return; +filename=fl_filename_setext(filename,".xiz"); + +int result=fileexists(filename); +if (result) { + result=0; + if (!fl_choice("The file exists. \nOverwrite it?","No","Yes",NULL)) return; + +}; + + +pthread_mutex_lock(&master->mutex); +result=master->part[npart]->saveXML(filename); +pthread_mutex_unlock(&master->mutex); + +if (result<0) fl_alert("Error: Could not save the file."); + +updatepanel(); +} +void MasterUI::cb_Save2(Fl_Menu_* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_Save2_i(o,v); +} + +void MasterUI::cb_Show1_i(Fl_Menu_*, void*) { + bankui->show(); +} +void MasterUI::cb_Show1(Fl_Menu_* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_Show1_i(o,v); +} + +void MasterUI::cb_Virtual_i(Fl_Menu_*, void*) { + virkeyboard->show(); +} +void MasterUI::cb_Virtual(Fl_Menu_* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_Virtual_i(o,v); +} + +void MasterUI::cb_Choose_i(Fl_Menu_*, void*) { + char *filename; +recordbutton->deactivate(); +pausebutton->deactivate(); +pauselabel->deactivate(); +stopbutton->deactivate(); +filename=fl_file_chooser("Record to audio file:","(*.wav)",NULL,0); +if (filename==NULL) return; +fl_filename_setext(filename,".wav"); + +int result=master->HDDRecorder.preparefile(filename,0); +if (result==1) { + result=0; + if (fl_choice("The file exists. \nOverwrite it?","No","Yes",NULL)) + master->HDDRecorder.preparefile(filename,1); +}; +if (result==0) recordbutton->activate(); + +if (result!=0) fl_alert("Error: Could not save the file."); +} +void MasterUI::cb_Choose(Fl_Menu_* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_Choose_i(o,v); +} + +void MasterUI::cb_Show2_i(Fl_Menu_*, void*) { + sequi->show(); +} +void MasterUI::cb_Show2(Fl_Menu_* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_Show2_i(o,v); +} + +void MasterUI::cb_Switch_i(Fl_Menu_*, void*) { + if (fl_choice("Switch the User Interface to Beginner mode ?","No","Yes",NULL)){ + masterwindow->hide(); + refresh_master_ui(); + simplemasterwindow->show(); + config.cfg.UserInterfaceMode=2; +}; +} +void MasterUI::cb_Switch(Fl_Menu_* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_Switch_i(o,v); +} + +Fl_Menu_Item MasterUI::menu_mastermenu[] = { + {"&File", 0, 0, 0, 64, FL_NORMAL_LABEL, 0, 14, 0}, + {"&New (erase all)...", 0, (Fl_Callback*)MasterUI::cb_New, 0, 0, FL_NORMAL_LABEL, 0, 14, 0}, + {"&Open Parameters...", 0, (Fl_Callback*)MasterUI::cb_Open, 0, 0, FL_NORMAL_LABEL, 0, 14, 0}, + {"&Save All Parameters...", 0, (Fl_Callback*)MasterUI::cb_Save, 0, 128, FL_NORMAL_LABEL, 0, 14, 0}, + {"&Load Scale Settings...", 0, (Fl_Callback*)MasterUI::cb_Load, 0, 0, FL_NORMAL_LABEL, 0, 14, 0}, + {"Save Sc&ale Settings ..", 0, (Fl_Callback*)MasterUI::cb_Save1, 0, 0, FL_NORMAL_LABEL, 0, 14, 0}, + {"Show Scale Settings...", 0, (Fl_Callback*)MasterUI::cb_Show, 0, 128, FL_NORMAL_LABEL, 0, 14, 0}, + {"&Settings...", 0, (Fl_Callback*)MasterUI::cb_Settings, 0, 128, FL_NORMAL_LABEL, 0, 14, 0}, + {"&Copyright...", 0, (Fl_Callback*)MasterUI::cb_Copyright, 0, 128, FL_NORMAL_LABEL, 0, 14, 0}, + {"E&xit", 0, (Fl_Callback*)MasterUI::cb_E, 0, 0, FL_NORMAL_LABEL, 0, 14, 0}, + {0,0,0,0,0,0,0,0,0}, + {"&Instrument", 0, 0, 0, 64, FL_NORMAL_LABEL, 0, 14, 0}, + {"&Clear Instrument...", 0, (Fl_Callback*)MasterUI::cb_Clear, 0, 0, FL_NORMAL_LABEL, 0, 14, 0}, + {"&Open Instrument...", 0, (Fl_Callback*)MasterUI::cb_Open1, 0, 0, FL_NORMAL_LABEL, 0, 14, 0}, + {"&Save Instrument ...", 0, (Fl_Callback*)MasterUI::cb_Save2, 0, 128, FL_NORMAL_LABEL, 0, 14, 0}, + {"Show Instrument &Bank...", 0, (Fl_Callback*)MasterUI::cb_Show1, 0, 128, FL_NORMAL_LABEL, 0, 14, 0}, + {"&Virtual Keyboard...", 0, (Fl_Callback*)MasterUI::cb_Virtual, 0, 0, FL_NORMAL_LABEL, 0, 14, 0}, + {0,0,0,0,0,0,0,0,0}, + {"&Record", 0, 0, 0, 64, FL_NORMAL_LABEL, 0, 14, 0}, + {"&Choose WAV file...", 0, (Fl_Callback*)MasterUI::cb_Choose, 0, 0, FL_NORMAL_LABEL, 0, 14, 0}, + {0,0,0,0,0,0,0,0,0}, + {"&Sequencer", 0, 0, 0, 80, FL_NORMAL_LABEL, 0, 14, 0}, + {"Show &Sequencer...", 0, (Fl_Callback*)MasterUI::cb_Show2, 0, 0, FL_NORMAL_LABEL, 0, 14, 0}, + {0,0,0,0,0,0,0,0,0}, + {"Misc", 0, 0, 0, 64, FL_NORMAL_LABEL, 0, 14, 0}, + {"Switch User Interface Mode", 0, (Fl_Callback*)MasterUI::cb_Switch, 0, 0, FL_NORMAL_LABEL, 0, 14, 0}, + {0,0,0,0,0,0,0,0,0}, + {0,0,0,0,0,0,0,0,0} +}; +Fl_Menu_Item* MasterUI::recordmenu = MasterUI::menu_mastermenu + 18; + +void MasterUI::cb_mastervolumedial_i(WidgetPDial* o, void*) { + master->setPvolume((int) o->value()); +} +void MasterUI::cb_mastervolumedial(WidgetPDial* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_mastervolumedial_i(o,v); +} + +void MasterUI::cb_masterkeyshiftcounter_i(Fl_Counter* o, void*) { + master->setPkeyshift((int) o->value()+64); +} +void MasterUI::cb_masterkeyshiftcounter(Fl_Counter* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_masterkeyshiftcounter_i(o,v); +} + +void MasterUI::cb_Panic_i(Fl_Button*, void*) { + virkeyboard->relaseallkeys(); +pthread_mutex_lock(&master->mutex); +master->shutup=1; +pthread_mutex_unlock(&master->mutex); +} +void MasterUI::cb_Panic(Fl_Button* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_Panic_i(o,v); +} + +void MasterUI::cb_syseffnocounter_i(Fl_Counter* o, void*) { + nsyseff=(int) o->value()-1; +sysefftype->value(master->sysefx[nsyseff]->geteffect()); +syseffectui->refresh(master->sysefx[nsyseff]); +} +void MasterUI::cb_syseffnocounter(Fl_Counter* o, void* v) { + ((MasterUI*)(o->parent()->parent()->parent()->user_data()))->cb_syseffnocounter_i(o,v); +} + +void MasterUI::cb_sysefftype_i(Fl_Choice* o, void*) { + pthread_mutex_lock(&master->mutex); +master->sysefx[nsyseff]->changeeffect((int) o->value()); +pthread_mutex_unlock(&master->mutex); +syseffectui->refresh(master->sysefx[nsyseff]); +} +void MasterUI::cb_sysefftype(Fl_Choice* o, void* v) { + ((MasterUI*)(o->parent()->parent()->parent()->user_data()))->cb_sysefftype_i(o,v); +} + +Fl_Menu_Item MasterUI::menu_sysefftype[] = { + {"No Effect", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Reverb", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Echo", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Chorus", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Phaser", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"AlienWah", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Distortion", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"EQ", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"DynFilter", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void MasterUI::cb_Send_i(Fl_Button*, void*) { + syseffsendwindow->show(); +} +void MasterUI::cb_Send(Fl_Button* o, void* v) { + ((MasterUI*)(o->parent()->parent()->parent()->user_data()))->cb_Send_i(o,v); +} + +void MasterUI::cb_C_i(Fl_Button*, void*) { + presetsui->copy(master->sysefx[nsyseff]); +} +void MasterUI::cb_C(Fl_Button* o, void* v) { + ((MasterUI*)(o->parent()->parent()->parent()->user_data()))->cb_C_i(o,v); +} + +void MasterUI::cb_P_i(Fl_Button*, void*) { + pthread_mutex_lock(&master->mutex); +presetsui->paste(master->sysefx[nsyseff],syseffectui); +pthread_mutex_unlock(&master->mutex); +} +void MasterUI::cb_P(Fl_Button* o, void* v) { + ((MasterUI*)(o->parent()->parent()->parent()->user_data()))->cb_P_i(o,v); +} + +void MasterUI::cb_inseffnocounter_i(Fl_Counter* o, void*) { + ninseff=(int) o->value()-1; +insefftype->value(master->insefx[ninseff]->geteffect()); +inseffpart->value(master->Pinsparts[ninseff]+2); +inseffectui->refresh(master->insefx[ninseff]); + +if (master->Pinsparts[ninseff]!=-1) { + insefftype->activate(); + inseffectui->activate(); + inseffectuigroup->activate(); +} else { + insefftype->deactivate(); + inseffectui->deactivate(); + inseffectuigroup->deactivate(); +}; +} +void MasterUI::cb_inseffnocounter(Fl_Counter* o, void* v) { + ((MasterUI*)(o->parent()->parent()->parent()->user_data()))->cb_inseffnocounter_i(o,v); +} + +void MasterUI::cb_insefftype_i(Fl_Choice* o, void*) { + pthread_mutex_lock(&master->mutex); +master->insefx[ninseff]->changeeffect((int) o->value()); +pthread_mutex_unlock(&master->mutex); +inseffectui->refresh(master->insefx[ninseff]); +inseffectui->show(); +} +void MasterUI::cb_insefftype(Fl_Choice* o, void* v) { + ((MasterUI*)(o->parent()->parent()->parent()->user_data()))->cb_insefftype_i(o,v); +} + +Fl_Menu_Item MasterUI::menu_insefftype[] = { + {"No Effect", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Reverb", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Echo", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Chorus", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Phaser", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"AlienWah", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Distortion", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"EQ", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"DynFilter", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void MasterUI::cb_inseffpart_i(Fl_Choice* o, void*) { + master->Pinsparts[ninseff]=(int) o->value()-2; +if ((int) o->value()==1){ + inseffectuigroup->deactivate(); + insefftype->deactivate(); + inseffectui->deactivate(); +} else { + inseffectuigroup->activate(); + insefftype->activate(); + inseffectui->activate(); +}; +master->insefx[ninseff]->cleanup(); +} +void MasterUI::cb_inseffpart(Fl_Choice* o, void* v) { + ((MasterUI*)(o->parent()->parent()->parent()->user_data()))->cb_inseffpart_i(o,v); +} + +void MasterUI::cb_C1_i(Fl_Button*, void*) { + presetsui->copy(master->insefx[ninseff]); +} +void MasterUI::cb_C1(Fl_Button* o, void* v) { + ((MasterUI*)(o->parent()->parent()->parent()->user_data()))->cb_C1_i(o,v); +} + +void MasterUI::cb_P1_i(Fl_Button*, void*) { + pthread_mutex_lock(&master->mutex); +presetsui->paste(master->insefx[ninseff],inseffectui); +pthread_mutex_unlock(&master->mutex); +} +void MasterUI::cb_P1(Fl_Button* o, void* v) { + ((MasterUI*)(o->parent()->parent()->parent()->user_data()))->cb_P1_i(o,v); +} + +void MasterUI::cb_Scales_i(Fl_Button*, void*) { + microtonalui->show(); +} +void MasterUI::cb_Scales(Fl_Button* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_Scales_i(o,v); +} + +void MasterUI::cb_recordbutton_i(Fl_Button* o, void*) { + o->deactivate(); +recordmenu->deactivate(); +recordmenu->label("&Record(*)"); +stopbutton->activate(); +pausebutton->activate(); +pauselabel->activate(); +master->HDDRecorder.start(); +master->vuresetpeaks(); +mastermenu->redraw(); +} +void MasterUI::cb_recordbutton(Fl_Button* o, void* v) { + ((MasterUI*)(o->parent()->parent()->user_data()))->cb_recordbutton_i(o,v); +} + +void MasterUI::cb_stopbutton_i(Fl_Button* o, void*) { + o->deactivate(); +master->HDDRecorder.stop(); +recordbutton->deactivate(); +pausebutton->deactivate(); +pauselabel->deactivate(); +recordmenu->activate(); +recordmenu->label("&Record"); +mastermenu->redraw(); +} +void MasterUI::cb_stopbutton(Fl_Button* o, void* v) { + ((MasterUI*)(o->parent()->parent()->user_data()))->cb_stopbutton_i(o,v); +} + +void MasterUI::cb_pausebutton_i(Fl_Button* o, void*) { + o->deactivate(); +master->HDDRecorder.pause(); +recordbutton->activate(); +mastermenu->redraw(); +} +void MasterUI::cb_pausebutton(Fl_Button* o, void* v) { + ((MasterUI*)(o->parent()->parent()->user_data()))->cb_pausebutton_i(o,v); +} + +void MasterUI::cb_nrpnbutton_i(Fl_Check_Button* o, void*) { + master->ctl.NRPN.receive=(int) o->value(); +} +void MasterUI::cb_nrpnbutton(Fl_Check_Button* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_nrpnbutton_i(o,v); +} + +void MasterUI::cb_npartcounter_i(Fl_Counter* o, void*) { + int nval=(int) o->value()-1; +partuigroup->remove(partui); +delete partui; +partui=new PartUI(0,0,765,525); +partuigroup->add(partui); +partui->init(master->part[nval],master,nval,bankui); +partui->redraw(); +o->redraw(); +npart=nval; + +updatepanel(); +simplenpartcounter->value(nval+1); +simplenpartcounter->do_callback(); +} +void MasterUI::cb_npartcounter(Fl_Counter* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_npartcounter_i(o,v); +} + +void MasterUI::cb_vK_i(Fl_Button*, void*) { + virkeyboard->show(); +} +void MasterUI::cb_vK(Fl_Button* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_vK_i(o,v); +} + +void MasterUI::cb_R_i(Fl_Button*, void*) { + globalfinedetuneslider->value(64.0); +globalfinedetuneslider->do_callback(); +} +void MasterUI::cb_R(Fl_Button* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_R_i(o,v); +} + +void MasterUI::cb_globalfinedetuneslider_i(WidgetPDial* o, void*) { + master->microtonal.Pglobalfinedetune=(int) o->value(); +} +void MasterUI::cb_globalfinedetuneslider(WidgetPDial* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_globalfinedetuneslider_i(o,v); +} + +void MasterUI::cb_Panel_i(Fl_Button*, void*) { + updatepanel(); +panelwindow->show(); +} +void MasterUI::cb_Panel(Fl_Button* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_Panel_i(o,v); +} + +void MasterUI::cb_Close_i(Fl_Button*, void*) { + aboutwindow->hide(); +} +void MasterUI::cb_Close(Fl_Button* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_Close_i(o,v); +} + +void MasterUI::cb_Close1_i(Fl_Button*, void*) { + syseffsendwindow->hide(); +} +void MasterUI::cb_Close1(Fl_Button* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_Close1_i(o,v); +} + +void MasterUI::cb_Close2_i(Fl_Button*, void*) { + panelwindow->hide(); +updatepanel(); +} +void MasterUI::cb_Close2(Fl_Button* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_Close2_i(o,v); +} + +void MasterUI::cb_Refresh_i(Fl_Button*, void*) { + updatepanel(); +} +void MasterUI::cb_Refresh(Fl_Button* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_Refresh_i(o,v); +} + +void MasterUI::cb_simplemasterwindow_i(Fl_Double_Window*, void*) { + #ifdef VSTAUDIOOUT +fl_alert("ZynAddSubFX could not be closed this way, because it's a VST plugin. Please use the host aplication to close it."); +#else +if (fl_choice("Exit and leave the unsaved data?","No","Yes",NULL)) { + config.save(); + *exitprogram=1; +}; +#endif +} +void MasterUI::cb_simplemasterwindow(Fl_Double_Window* o, void* v) { + ((MasterUI*)(o->user_data()))->cb_simplemasterwindow_i(o,v); +} + +void MasterUI::cb_New1_i(Fl_Menu_*, void*) { + do_new_master(); +} +void MasterUI::cb_New1(Fl_Menu_* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_New1_i(o,v); +} + +void MasterUI::cb_Open2_i(Fl_Menu_*, void*) { + do_load_master(); +} +void MasterUI::cb_Open2(Fl_Menu_* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_Open2_i(o,v); +} + +void MasterUI::cb_Save3_i(Fl_Menu_*, void*) { + do_save_master(); +} +void MasterUI::cb_Save3(Fl_Menu_* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_Save3_i(o,v); +} + +void MasterUI::cb_Settings1_i(Fl_Menu_*, void*) { + configui->show(); +} +void MasterUI::cb_Settings1(Fl_Menu_* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_Settings1_i(o,v); +} + +void MasterUI::cb_Copyright1_i(Fl_Menu_*, void*) { + aboutwindow->show(); +} +void MasterUI::cb_Copyright1(Fl_Menu_* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_Copyright1_i(o,v); +} + +void MasterUI::cb_E1_i(Fl_Menu_*, void*) { + masterwindow->do_callback(); +} +void MasterUI::cb_E1(Fl_Menu_* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_E1_i(o,v); +} + +void MasterUI::cb_Open3_i(Fl_Menu_*, void*) { + const char *filename; +filename=fl_file_chooser("Load:","({*.xiz})",NULL,0); +if (filename==NULL) return; + + +pthread_mutex_lock(&master->mutex); +// int npart=(int)npartcounter->value()-1; + + //clear all instrument parameters, first + master->part[npart]->defaultsinstrument(); + + //load the instr. parameters + int result=master->part[npart]->loadXMLinstrument(filename); + +pthread_mutex_unlock(&master->mutex); +master->part[npart]->applyparameters(); + +simplenpartcounter->do_callback(); + +if (result==-10) fl_alert("Error: Could not load the file\nbecause it is not an instrument file."); + else if (result<0) fl_alert("Error: Could not load the file."); +} +void MasterUI::cb_Open3(Fl_Menu_* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_Open3_i(o,v); +} + +void MasterUI::cb_Show3_i(Fl_Menu_*, void*) { + bankui->show(); +} +void MasterUI::cb_Show3(Fl_Menu_* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_Show3_i(o,v); +} + +void MasterUI::cb_Switch1_i(Fl_Menu_*, void*) { + if (fl_choice("Switch the User Interface to Advanced mode ?","No","Yes",NULL)){ + simplemasterwindow->hide(); + refresh_master_ui(); + masterwindow->show(); + config.cfg.UserInterfaceMode=1; +}; +} +void MasterUI::cb_Switch1(Fl_Menu_* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_Switch1_i(o,v); +} + +Fl_Menu_Item MasterUI::menu_[] = { + {"&File", 0, 0, 0, 64, FL_NORMAL_LABEL, 0, 14, 0}, + {"&New (erase all)...", 0, (Fl_Callback*)MasterUI::cb_New1, 0, 0, FL_NORMAL_LABEL, 0, 14, 0}, + {"&Open Parameters...", 0, (Fl_Callback*)MasterUI::cb_Open2, 0, 0, FL_NORMAL_LABEL, 0, 14, 0}, + {"&Save All Parameters...", 0, (Fl_Callback*)MasterUI::cb_Save3, 0, 128, FL_NORMAL_LABEL, 0, 14, 0}, + {"&Settings...", 0, (Fl_Callback*)MasterUI::cb_Settings1, 0, 128, FL_NORMAL_LABEL, 0, 14, 0}, + {"&Copyright...", 0, (Fl_Callback*)MasterUI::cb_Copyright1, 0, 128, FL_NORMAL_LABEL, 0, 14, 0}, + {"E&xit", 0, (Fl_Callback*)MasterUI::cb_E1, 0, 0, FL_NORMAL_LABEL, 0, 14, 0}, + {0,0,0,0,0,0,0,0,0}, + {"&Instrument", 0, 0, 0, 64, FL_NORMAL_LABEL, 0, 14, 0}, + {"&Open Instrument...", 0, (Fl_Callback*)MasterUI::cb_Open3, 0, 0, FL_NORMAL_LABEL, 0, 14, 0}, + {"Show Instrument &Bank...", 0, (Fl_Callback*)MasterUI::cb_Show3, 0, 128, FL_NORMAL_LABEL, 0, 14, 0}, + {0,0,0,0,0,0,0,0,0}, + {"Misc", 0, 0, 0, 64, FL_NORMAL_LABEL, 0, 14, 0}, + {"Switch User Interface Mode", 0, (Fl_Callback*)MasterUI::cb_Switch1, 0, 0, FL_NORMAL_LABEL, 0, 14, 0}, + {0,0,0,0,0,0,0,0,0}, + {0,0,0,0,0,0,0,0,0} +}; + +void MasterUI::cb_partname1_i(Fl_Button*, void*) { + if ((int)bankui->cbwig->value()!=(npart+1)){ + bankui->cbwig->value(npart+1); + bankui->cbwig->do_callback(); +}; +bankui->show(); +} +void MasterUI::cb_partname1(Fl_Button* o, void* v) { + ((MasterUI*)(o->parent()->parent()->user_data()))->cb_partname1_i(o,v); +} + +void MasterUI::cb_partpanning1_i(Fl_Slider* o, void*) { + master->part[npart]->setPpanning((int) o->value()); +} +void MasterUI::cb_partpanning1(Fl_Slider* o, void* v) { + ((MasterUI*)(o->parent()->parent()->user_data()))->cb_partpanning1_i(o,v); +} + +void MasterUI::cb_partrcv1_i(Fl_Choice* o, void*) { + virkeys->relaseallkeys(0); +master->part[npart]->Prcvchn=(int) o->value(); +virkeys->midich=(int) o->value(); +} +void MasterUI::cb_partrcv1(Fl_Choice* o, void* v) { + ((MasterUI*)(o->parent()->parent()->user_data()))->cb_partrcv1_i(o,v); +} + +void MasterUI::cb_partvolume1_i(WidgetPDial* o, void*) { + master->part[npart]->setPvolume((int) o->value()); +} +void MasterUI::cb_partvolume1(WidgetPDial* o, void* v) { + ((MasterUI*)(o->parent()->parent()->user_data()))->cb_partvolume1_i(o,v); +} + +void MasterUI::cb_simplepartportamento_i(Fl_Check_Button* o, void*) { + master->part[npart]->ctl.portamento.portamento=(int) o->value(); +} +void MasterUI::cb_simplepartportamento(Fl_Check_Button* o, void* v) { + ((MasterUI*)(o->parent()->parent()->user_data()))->cb_simplepartportamento_i(o,v); +} + +void MasterUI::cb_simpleminkcounter_i(Fl_Counter* o, void*) { + master->part[npart]->Pminkey=(int) o->value(); +if (master->part[npart]->Pminkey>master->part[npart]->Pmaxkey) o->textcolor(FL_RED); + else o->textcolor(FL_BLACK); +} +void MasterUI::cb_simpleminkcounter(Fl_Counter* o, void* v) { + ((MasterUI*)(o->parent()->parent()->user_data()))->cb_simpleminkcounter_i(o,v); +} + +void MasterUI::cb_simplemaxkcounter_i(Fl_Counter* o, void*) { + master->part[npart]->Pmaxkey=(int) o->value(); + +if (master->part[npart]->Pminkey>master->part[npart]->Pmaxkey) o->textcolor(FL_RED); + else o->textcolor(FL_BLACK); +} +void MasterUI::cb_simplemaxkcounter(Fl_Counter* o, void* v) { + ((MasterUI*)(o->parent()->parent()->user_data()))->cb_simplemaxkcounter_i(o,v); +} + +void MasterUI::cb_m_i(Fl_Button*, void*) { + if (master->part[npart]->lastnote>=0) simpleminkcounter->value(master->part[npart]->lastnote); +simpleminkcounter->do_callback(); +simplemaxkcounter->do_callback(); +} +void MasterUI::cb_m(Fl_Button* o, void* v) { + ((MasterUI*)(o->parent()->parent()->user_data()))->cb_m_i(o,v); +} + +void MasterUI::cb_M_i(Fl_Button*, void*) { + if (master->part[npart]->lastnote>=0) simplemaxkcounter->value(master->part[npart]->lastnote); +simplemaxkcounter->do_callback(); +simpleminkcounter->do_callback(); +} +void MasterUI::cb_M(Fl_Button* o, void* v) { + ((MasterUI*)(o->parent()->parent()->user_data()))->cb_M_i(o,v); +} + +void MasterUI::cb_R1_i(Fl_Button*, void*) { + simpleminkcounter->value(0); +simpleminkcounter->do_callback(); +simplemaxkcounter->value(127); +simplemaxkcounter->do_callback(); +} +void MasterUI::cb_R1(Fl_Button* o, void* v) { + ((MasterUI*)(o->parent()->parent()->user_data()))->cb_R1_i(o,v); +} + +void MasterUI::cb_simplepartkeyshiftcounter_i(Fl_Counter* o, void*) { + master->part[npart]->Pkeyshift=(int) o->value()+64; +} +void MasterUI::cb_simplepartkeyshiftcounter(Fl_Counter* o, void* v) { + ((MasterUI*)(o->parent()->parent()->user_data()))->cb_simplepartkeyshiftcounter_i(o,v); +} + +void MasterUI::cb_simplesyseffsend_i(WidgetPDial* o, void*) { + master->setPsysefxvol(npart,nsyseff,(int) o->value()); +} +void MasterUI::cb_simplesyseffsend(WidgetPDial* o, void* v) { + ((MasterUI*)(o->parent()->parent()->user_data()))->cb_simplesyseffsend_i(o,v); +} + +void MasterUI::cb_partenabled1_i(Fl_Check_Button* o, void*) { + pthread_mutex_lock(&master->mutex); + master->partonoff(npart,(int) o->value()); +pthread_mutex_unlock(&master->mutex); + +if ((int) o->value()==0) simplelistitemgroup->deactivate(); + else { + simplelistitemgroup->activate(); + if ((int)bankui->cbwig->value()!=(npart+1)){ + bankui->cbwig->value(npart+1); + bankui->cbwig->do_callback(); + }; +}; + +o->redraw(); +} +void MasterUI::cb_partenabled1(Fl_Check_Button* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_partenabled1_i(o,v); +} + +void MasterUI::cb_simplesyseffnocounter_i(Fl_Counter* o, void*) { + nsyseff=(int) o->value()-1; +simplesysefftype->value(master->sysefx[nsyseff]->geteffect()); +simplesyseffectui->refresh(master->sysefx[nsyseff]); +simplerefresh(); +} +void MasterUI::cb_simplesyseffnocounter(Fl_Counter* o, void* v) { + ((MasterUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_simplesyseffnocounter_i(o,v); +} + +void MasterUI::cb_simplesysefftype_i(Fl_Choice* o, void*) { + pthread_mutex_lock(&master->mutex); +master->sysefx[nsyseff]->changeeffect((int) o->value()); +pthread_mutex_unlock(&master->mutex); +simplesyseffectui->refresh(master->sysefx[nsyseff]); +} +void MasterUI::cb_simplesysefftype(Fl_Choice* o, void* v) { + ((MasterUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_simplesysefftype_i(o,v); +} + +Fl_Menu_Item MasterUI::menu_simplesysefftype[] = { + {"No Effect", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Reverb", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Echo", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Chorus", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Phaser", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"AlienWah", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Distortion", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"EQ", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"DynFilter", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void MasterUI::cb_Send1_i(Fl_Button*, void*) { + syseffsendwindow->show(); +} +void MasterUI::cb_Send1(Fl_Button* o, void* v) { + ((MasterUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_Send1_i(o,v); +} + +void MasterUI::cb_P2_i(Fl_Button*, void*) { + pthread_mutex_lock(&master->mutex); +presetsui->paste(master->sysefx[nsyseff],simplesyseffectui); +pthread_mutex_unlock(&master->mutex); +} +void MasterUI::cb_P2(Fl_Button* o, void* v) { + ((MasterUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_P2_i(o,v); +} + +void MasterUI::cb_simpleinseffnocounter_i(Fl_Counter* o, void*) { + ninseff=(int) o->value()-1; +simpleinsefftype->value(master->insefx[ninseff]->geteffect()); +simpleinseffpart->value(master->Pinsparts[ninseff]+2); +simpleinseffectui->refresh(master->insefx[ninseff]); + +if (master->Pinsparts[ninseff]!=-1) { + simpleinsefftype->activate(); + simpleinseffectui->activate(); + simpleinseffectuigroup->activate(); +} else { + simpleinsefftype->deactivate(); + simpleinseffectui->deactivate(); + simpleinseffectuigroup->deactivate(); +}; +} +void MasterUI::cb_simpleinseffnocounter(Fl_Counter* o, void* v) { + ((MasterUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_simpleinseffnocounter_i(o,v); +} + +void MasterUI::cb_simpleinsefftype_i(Fl_Choice* o, void*) { + pthread_mutex_lock(&master->mutex); +master->insefx[ninseff]->changeeffect((int) o->value()); +pthread_mutex_unlock(&master->mutex); +simpleinseffectui->refresh(master->insefx[ninseff]); +simpleinseffectui->show(); +} +void MasterUI::cb_simpleinsefftype(Fl_Choice* o, void* v) { + ((MasterUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_simpleinsefftype_i(o,v); +} + +Fl_Menu_Item MasterUI::menu_simpleinsefftype[] = { + {"No Effect", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Reverb", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Echo", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Chorus", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Phaser", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"AlienWah", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Distortion", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"EQ", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"DynFilter", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void MasterUI::cb_simpleinseffpart_i(Fl_Choice* o, void*) { + master->Pinsparts[ninseff]=(int) o->value()-2; +if ((int) o->value()==1){ + simpleinseffectuigroup->deactivate(); + simpleinsefftype->deactivate(); + simpleinseffectui->deactivate(); +} else { + simpleinseffectuigroup->activate(); + simpleinsefftype->activate(); + simpleinseffectui->activate(); +}; +master->insefx[ninseff]->cleanup(); +} +void MasterUI::cb_simpleinseffpart(Fl_Choice* o, void* v) { + ((MasterUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_simpleinseffpart_i(o,v); +} + +void MasterUI::cb_P3_i(Fl_Button*, void*) { + pthread_mutex_lock(&master->mutex); +presetsui->paste(master->insefx[ninseff],simpleinseffectui); +pthread_mutex_unlock(&master->mutex); +} +void MasterUI::cb_P3(Fl_Button* o, void* v) { + ((MasterUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_P3_i(o,v); +} + +void MasterUI::cb_simplemastervolumedial_i(WidgetPDial* o, void*) { + master->setPvolume((int) o->value()); +} +void MasterUI::cb_simplemastervolumedial(WidgetPDial* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_simplemastervolumedial_i(o,v); +} + +void MasterUI::cb_simplemasterkeyshiftcounter_i(Fl_Counter* o, void*) { + master->setPkeyshift((int) o->value()+64); +} +void MasterUI::cb_simplemasterkeyshiftcounter(Fl_Counter* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_simplemasterkeyshiftcounter_i(o,v); +} + +void MasterUI::cb_Stop_i(Fl_Button*, void*) { + virkeyboard->relaseallkeys(); +pthread_mutex_lock(&master->mutex); +master->shutup=1; +pthread_mutex_unlock(&master->mutex); +} +void MasterUI::cb_Stop(Fl_Button* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_Stop_i(o,v); +} + +void MasterUI::cb_Reset_i(Fl_Button*, void*) { + simpleglobalfinedetuneslider->value(64.0); +simpleglobalfinedetuneslider->do_callback(); +} +void MasterUI::cb_Reset(Fl_Button* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_Reset_i(o,v); +} + +void MasterUI::cb_simpleglobalfinedetuneslider_i(WidgetPDial* o, void*) { + master->microtonal.Pglobalfinedetune=(int) o->value(); +} +void MasterUI::cb_simpleglobalfinedetuneslider(WidgetPDial* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_simpleglobalfinedetuneslider_i(o,v); +} + +void MasterUI::cb_simplenpartcounter_i(Fl_Counter* o, void*) { + virkeys->relaseallkeys(0); +npartcounter->value(o->value()); +npart=(int) o->value()-1; + +simplerefresh(); +virkeys->midich=master->part[npart]->Prcvchn; +} +void MasterUI::cb_simplenpartcounter(Fl_Counter* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_simplenpartcounter_i(o,v); +} + +void MasterUI::cb_Keyb_i(Fl_Counter* o, void*) { + virkeys->relaseallkeys(0); +virkeys->midioct=(int) o->value(); +virkeys->take_focus(); +} +void MasterUI::cb_Keyb(Fl_Counter* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_Keyb_i(o,v); +} + +void MasterUI::cb_selectuiwindow_i(Fl_Double_Window*, void*) { + *exitprogram=1; +} +void MasterUI::cb_selectuiwindow(Fl_Double_Window* o, void* v) { + ((MasterUI*)(o->user_data()))->cb_selectuiwindow_i(o,v); +} + +void MasterUI::cb_Advanced_i(Fl_Button*, void*) { + config.cfg.UserInterfaceMode=1; +masterwindow->show(); +selectuiwindow->hide(); +} +void MasterUI::cb_Advanced(Fl_Button* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_Advanced_i(o,v); +} + +void MasterUI::cb_Beginner_i(Fl_Button*, void*) { + simplemasterwindow->show(); +selectuiwindow->hide(); +config.cfg.UserInterfaceMode=2; +} +void MasterUI::cb_Beginner(Fl_Button* o, void* v) { + ((MasterUI*)(o->parent()->user_data()))->cb_Beginner_i(o,v); +} + +Fl_Double_Window* MasterUI::make_window() { + { masterwindow = new Fl_Double_Window(390, 465, "zynaddsubfx"); + masterwindow->callback((Fl_Callback*)cb_masterwindow, (void*)(this)); + { mastermenu = new Fl_Menu_Bar(-5, 0, 690, 25); + mastermenu->menu(menu_mastermenu); + } // Fl_Menu_Bar* mastermenu + { WidgetPDial* o = mastervolumedial = new WidgetPDial(5, 30, 30, 30, "M.Vol"); + mastervolumedial->tooltip("Master Volume"); + mastervolumedial->box(FL_ROUND_UP_BOX); + mastervolumedial->color(FL_BACKGROUND_COLOR); + mastervolumedial->selection_color(FL_INACTIVE_COLOR); + mastervolumedial->labeltype(FL_NORMAL_LABEL); + mastervolumedial->labelfont(1); + mastervolumedial->labelsize(11); + mastervolumedial->labelcolor(FL_FOREGROUND_COLOR); + mastervolumedial->maximum(127); + mastervolumedial->step(1); + mastervolumedial->callback((Fl_Callback*)cb_mastervolumedial); + mastervolumedial->align(130); + mastervolumedial->when(FL_WHEN_CHANGED); + o->value(master->Pvolume); + } // WidgetPDial* mastervolumedial + { Fl_Counter* o = masterkeyshiftcounter = new Fl_Counter(45, 31, 90, 20, "Master KeyShift"); + masterkeyshiftcounter->labelsize(11); + masterkeyshiftcounter->minimum(-64); + masterkeyshiftcounter->maximum(64); + masterkeyshiftcounter->step(1); + masterkeyshiftcounter->callback((Fl_Callback*)cb_masterkeyshiftcounter); + o->lstep(12); + o->value(master->Pkeyshift-64); + } // Fl_Counter* masterkeyshiftcounter + { Fl_Button* o = new Fl_Button(293, 29, 92, 31, "Panic!"); + o->box(FL_PLASTIC_UP_BOX); + o->color((Fl_Color)231); + o->labelfont(1); + o->callback((Fl_Callback*)cb_Panic); + } // Fl_Button* o + { partuigroup = new Fl_Group(0, 242, 390, 183); + partuigroup->box(FL_ENGRAVED_FRAME); + { PartUI* o = partui = new PartUI(4, 245, 383, 175); + partui->box(FL_FLAT_BOX); + partui->color(FL_BACKGROUND_COLOR); + partui->selection_color(FL_BACKGROUND_COLOR); + partui->labeltype(FL_NORMAL_LABEL); + partui->labelfont(0); + partui->labelsize(14); + partui->labelcolor(FL_FOREGROUND_COLOR); + partui->align(FL_ALIGN_TOP); + partui->when(FL_WHEN_RELEASE); + o->init(master->part[0],master,0,bankui); + o->show(); + partui->end(); + } // PartUI* partui + partuigroup->end(); + } // Fl_Group* partuigroup + { Fl_Tabs* o = new Fl_Tabs(0, 80, 390, 160); + { Fl_Group* o = new Fl_Group(0, 100, 390, 140, "System Effects"); + o->box(FL_ENGRAVED_FRAME); + o->labeltype(FL_EMBOSSED_LABEL); + o->labelsize(15); + o->align(FL_ALIGN_TOP_RIGHT|FL_ALIGN_INSIDE); + { Fl_Counter* o = syseffnocounter = new Fl_Counter(5, 120, 80, 20, "Sys.Effect No."); + syseffnocounter->type(1); + syseffnocounter->labelfont(1); + syseffnocounter->labelsize(10); + syseffnocounter->minimum(0); + syseffnocounter->maximum(127); + syseffnocounter->step(1); + syseffnocounter->value(1); + syseffnocounter->textfont(1); + syseffnocounter->callback((Fl_Callback*)cb_syseffnocounter); + syseffnocounter->align(FL_ALIGN_TOP); + o->bounds(1,NUM_SYS_EFX); + o->value(nsyseff+1); + } // Fl_Counter* syseffnocounter + { Fl_Choice* o = sysefftype = new Fl_Choice(315, 125, 70, 15, "EffType"); + sysefftype->down_box(FL_BORDER_BOX); + sysefftype->labelsize(10); + sysefftype->callback((Fl_Callback*)cb_sysefftype); + sysefftype->menu(menu_sysefftype); + o->value(master->sysefx[nsyseff]->geteffect()); + } // Fl_Choice* sysefftype + { syseffectuigroup = new Fl_Group(5, 140, 380, 95); + syseffectuigroup->box(FL_FLAT_BOX); + syseffectuigroup->color((Fl_Color)48); + { EffUI* o = syseffectui = new EffUI(5, 140, 380, 95); + syseffectui->box(FL_NO_BOX); + syseffectui->color(FL_BACKGROUND_COLOR); + syseffectui->selection_color(FL_BACKGROUND_COLOR); + syseffectui->labeltype(FL_NORMAL_LABEL); + syseffectui->labelfont(0); + syseffectui->labelsize(14); + syseffectui->labelcolor(FL_FOREGROUND_COLOR); + syseffectui->align(FL_ALIGN_TOP); + syseffectui->when(FL_WHEN_RELEASE); + o->init(master->sysefx[nsyseff]); + syseffectui->end(); + } // EffUI* syseffectui + syseffectuigroup->end(); + } // Fl_Group* syseffectuigroup + { Fl_Button* o = new Fl_Button(95, 120, 75, 20, "Send to..."); + o->box(FL_THIN_UP_BOX); + o->labelfont(1); + o->labelsize(11); + o->callback((Fl_Callback*)cb_Send); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(215, 124, 25, 15, "C"); + o->box(FL_THIN_UP_BOX); + o->color((Fl_Color)179); + o->labelfont(1); + o->labelsize(11); + o->labelcolor(FL_BACKGROUND2_COLOR); + o->callback((Fl_Callback*)cb_C); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(245, 124, 25, 15, "P"); + o->box(FL_THIN_UP_BOX); + o->color((Fl_Color)179); + o->labelfont(1); + o->labelsize(11); + o->labelcolor(FL_BACKGROUND2_COLOR); + o->callback((Fl_Callback*)cb_P); + } // Fl_Button* o + o->end(); + } // Fl_Group* o + { Fl_Group* o = new Fl_Group(0, 100, 390, 140, "Insertion Effects"); + o->box(FL_ENGRAVED_FRAME); + o->labeltype(FL_EMBOSSED_LABEL); + o->labelsize(15); + o->align(FL_ALIGN_TOP_RIGHT|FL_ALIGN_INSIDE); + o->hide(); + { Fl_Counter* o = inseffnocounter = new Fl_Counter(5, 120, 80, 20, "Ins.Effect No."); + inseffnocounter->type(1); + inseffnocounter->labelfont(1); + inseffnocounter->labelsize(10); + inseffnocounter->minimum(0); + inseffnocounter->maximum(127); + inseffnocounter->step(1); + inseffnocounter->value(1); + inseffnocounter->textfont(1); + inseffnocounter->callback((Fl_Callback*)cb_inseffnocounter); + inseffnocounter->align(FL_ALIGN_TOP); + o->bounds(1,NUM_INS_EFX); + o->value(ninseff+1); + } // Fl_Counter* inseffnocounter + { Fl_Choice* o = insefftype = new Fl_Choice(315, 125, 70, 15, "EffType"); + insefftype->down_box(FL_BORDER_BOX); + insefftype->labelsize(10); + insefftype->callback((Fl_Callback*)cb_insefftype); + insefftype->menu(menu_insefftype); + o->value(master->insefx[ninseff]->geteffect()); + if (master->Pinsparts[ninseff]== -1) o->deactivate(); + } // Fl_Choice* insefftype + { inseffectuigroup = new Fl_Group(5, 140, 380, 95); + inseffectuigroup->box(FL_FLAT_BOX); + inseffectuigroup->color((Fl_Color)48); + { EffUI* o = inseffectui = new EffUI(5, 140, 380, 95); + inseffectui->box(FL_NO_BOX); + inseffectui->color(FL_BACKGROUND_COLOR); + inseffectui->selection_color(FL_BACKGROUND_COLOR); + inseffectui->labeltype(FL_NORMAL_LABEL); + inseffectui->labelfont(0); + inseffectui->labelsize(14); + inseffectui->labelcolor(FL_FOREGROUND_COLOR); + inseffectui->align(FL_ALIGN_TOP); + inseffectui->when(FL_WHEN_RELEASE); + o->init(master->insefx[ninseff]); + if (master->Pinsparts[ninseff]== -1) o->deactivate(); + inseffectui->end(); + } // EffUI* inseffectui + inseffectuigroup->end(); + } // Fl_Group* inseffectuigroup + { Fl_Choice* o = inseffpart = new Fl_Choice(95, 120, 80, 20, "Insert To."); + inseffpart->down_box(FL_BORDER_BOX); + inseffpart->labelfont(1); + inseffpart->labelsize(10); + inseffpart->textsize(10); + inseffpart->callback((Fl_Callback*)cb_inseffpart); + inseffpart->align(FL_ALIGN_TOP_LEFT); + o->add("Master Out");o->add("Off"); + char tmp[50]; for (int i=0;iadd(tmp);}; + o->value(master->Pinsparts[ninseff]+2); + } // Fl_Choice* inseffpart + { Fl_Button* o = new Fl_Button(215, 124, 25, 15, "C"); + o->box(FL_THIN_UP_BOX); + o->color((Fl_Color)179); + o->labelfont(1); + o->labelsize(11); + o->labelcolor(FL_BACKGROUND2_COLOR); + o->callback((Fl_Callback*)cb_C1); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(245, 124, 25, 15, "P"); + o->box(FL_THIN_UP_BOX); + o->color((Fl_Color)179); + o->labelfont(1); + o->labelsize(11); + o->labelcolor(FL_BACKGROUND2_COLOR); + o->callback((Fl_Callback*)cb_P1); + } // Fl_Button* o + o->end(); + } // Fl_Group* o + o->end(); + } // Fl_Tabs* o + { Fl_Button* o = new Fl_Button(330, 80, 56, 19, "Scales"); + o->box(FL_PLASTIC_UP_BOX); + o->color((Fl_Color)231); + o->labeltype(FL_ENGRAVED_LABEL); + o->labelfont(1); + o->callback((Fl_Callback*)cb_Scales); + } // Fl_Button* o + { Fl_Group* o = new Fl_Group(172, 30, 117, 45); + o->box(FL_ENGRAVED_BOX); + { recordbutton = new Fl_Button(181, 36, 21, 21, "Rec."); + recordbutton->tooltip("Start Recording"); + recordbutton->box(FL_ROUND_UP_BOX); + recordbutton->color(FL_RED); + recordbutton->labelfont(1); + recordbutton->labelsize(10); + recordbutton->callback((Fl_Callback*)cb_recordbutton); + recordbutton->align(FL_ALIGN_BOTTOM); + recordbutton->deactivate(); + } // Fl_Button* recordbutton + { stopbutton = new Fl_Button(259, 36, 21, 21, "Stop"); + stopbutton->tooltip("Stop Recording and close the audio file"); + stopbutton->box(FL_THIN_UP_BOX); + stopbutton->color((Fl_Color)4); + stopbutton->labelfont(1); + stopbutton->labelsize(10); + stopbutton->callback((Fl_Callback*)cb_stopbutton); + stopbutton->align(FL_ALIGN_BOTTOM); + stopbutton->deactivate(); + } // Fl_Button* stopbutton + { pausebutton = new Fl_Button(220, 36, 21, 21, "@||"); + pausebutton->tooltip("Pause Recording"); + pausebutton->box(FL_THIN_UP_BOX); + pausebutton->color((Fl_Color)4); + pausebutton->selection_color((Fl_Color)4); + pausebutton->labelfont(1); + pausebutton->labelcolor((Fl_Color)3); + pausebutton->callback((Fl_Callback*)cb_pausebutton); + pausebutton->align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE); + pausebutton->deactivate(); + } // Fl_Button* pausebutton + { pauselabel = new Fl_Box(214, 56, 30, 15, "Pause"); + pauselabel->labelfont(1); + pauselabel->labelsize(10); + pauselabel->deactivate(); + } // Fl_Box* pauselabel + o->end(); + } // Fl_Group* o + { Fl_Group* o = new Fl_Group(1, 427, 389, 33); + o->box(FL_ENGRAVED_FRAME); + { VUMeter* o = new VUMeter(4, 430, 384, 30, "VU-Meter"); + o->box(FL_FLAT_BOX); + o->color((Fl_Color)48); + o->selection_color((Fl_Color)75); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); + o->align(FL_ALIGN_CENTER); + o->when(FL_WHEN_RELEASE); + o->init(master,-1); + } // VUMeter* o + o->end(); + } // Fl_Group* o + { Fl_Check_Button* o = nrpnbutton = new Fl_Check_Button(45, 65, 47, 10, "NRPN"); + nrpnbutton->tooltip("Receive NRPNs"); + nrpnbutton->down_box(FL_DOWN_BOX); + nrpnbutton->labelsize(10); + nrpnbutton->callback((Fl_Callback*)cb_nrpnbutton); + o->value(master->ctl.NRPN.receive); + } // Fl_Check_Button* nrpnbutton + { Fl_Counter* o = npartcounter = new Fl_Counter(5, 247, 70, 23); + npartcounter->tooltip("The part number"); + npartcounter->type(1); + npartcounter->labelfont(1); + npartcounter->minimum(0); + npartcounter->maximum(127); + npartcounter->step(1); + npartcounter->value(1); + npartcounter->textfont(1); + npartcounter->callback((Fl_Callback*)cb_npartcounter); + o->bounds(1,NUM_MIDI_PARTS); + bankui->init(o); + } // Fl_Counter* npartcounter + { Fl_Button* o = new Fl_Button(292, 80, 35, 19, "vK"); + o->tooltip("Virtual Keyboard"); + o->box(FL_PLASTIC_UP_BOX); + o->color((Fl_Color)231); + o->labeltype(FL_ENGRAVED_LABEL); + o->labelfont(1); + o->callback((Fl_Callback*)cb_vK); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(140, 65, 30, 10, "R.D."); + o->tooltip("Master fine detune reset"); + o->box(FL_THIN_UP_BOX); + o->labelfont(1); + o->labelsize(10); + o->callback((Fl_Callback*)cb_R); + } // Fl_Button* o + { WidgetPDial* o = globalfinedetuneslider = new WidgetPDial(143, 30, 20, 20, "F.Det."); + globalfinedetuneslider->tooltip("global fine detune"); + globalfinedetuneslider->box(FL_ROUND_UP_BOX); + globalfinedetuneslider->color(FL_BACKGROUND_COLOR); + globalfinedetuneslider->selection_color(FL_INACTIVE_COLOR); + globalfinedetuneslider->labeltype(FL_NORMAL_LABEL); + globalfinedetuneslider->labelfont(0); + globalfinedetuneslider->labelsize(10); + globalfinedetuneslider->labelcolor(FL_FOREGROUND_COLOR); + globalfinedetuneslider->maximum(127); + globalfinedetuneslider->step(1); + globalfinedetuneslider->value(64); + globalfinedetuneslider->callback((Fl_Callback*)cb_globalfinedetuneslider); + globalfinedetuneslider->align(130); + globalfinedetuneslider->when(FL_WHEN_CHANGED); + o->value(master->microtonal.Pglobalfinedetune); + } // WidgetPDial* globalfinedetuneslider + { Fl_Button* o = new Fl_Button(293, 62, 92, 16, "Panel Window"); + o->tooltip("Panel Window"); + o->box(FL_PLASTIC_UP_BOX); + o->color((Fl_Color)183); + o->labelfont(1); + o->labelsize(10); + o->callback((Fl_Callback*)cb_Panel); + } // Fl_Button* o + masterwindow->xclass("zynaddsubfx"); + masterwindow->end(); + } // Fl_Double_Window* masterwindow + { aboutwindow = new Fl_Double_Window(330, 210, "Copyright..."); + aboutwindow->user_data((void*)(this)); + { Fl_Box* o = new Fl_Box(0, 35, 330, 25, "Copyright (c) 2002-2005 Nasca O. Paul and others"); + o->labeltype(FL_EMBOSSED_LABEL); + o->labelsize(15); + o->align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(0, 60, 325, 115, "This is free software; you may redistribute it and/or modify it under the ter\ +ms of the \nversion 2 (or any later version) of the GNU General Public License\ + as published by the Free Software Fundation.\n This program comes with\n ABS\ +OLUTELY NO WARRANTY. \n See the version 2 (or any later version) of the \nGNU \ +General Public License for details."); + o->labelfont(1); + o->labelsize(11); + o->align(FL_ALIGN_WRAP|FL_ALIGN_INSIDE); + } // Fl_Box* o + { Fl_Button* o = new Fl_Button(80, 180, 180, 25, "Close this window"); + o->box(FL_THIN_UP_BOX); + o->labelsize(11); + o->callback((Fl_Callback*)cb_Close); + } // Fl_Button* o + { Fl_Box* o = new Fl_Box(5, 5, 325, 30, "ZynAddSubFX"); + o->labeltype(FL_EMBOSSED_LABEL); + o->labelfont(1); + o->labelsize(20); + o->align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE); + } // Fl_Box* o + aboutwindow->end(); + } // Fl_Double_Window* aboutwindow + { syseffsendwindow = new Fl_Double_Window(120, 250, "System Effects Send"); + syseffsendwindow->user_data((void*)(this)); + { Fl_Scroll* o = new Fl_Scroll(0, 45, 120, 170); + o->box(FL_FLAT_BOX); + for (int neff1=0;neff1x()+(neff2-1)*35,o->y()+15+neff1*50,30,30);syseffsend[neff1][neff2]->label("aaa");syseffsend[neff1][neff2]->init(master,neff1,neff2);}; + o->end(); + Fl_Group::current()->resizable(o); + } // Fl_Scroll* o + { Fl_Button* o = new Fl_Button(25, 220, 80, 25, "Close"); + o->box(FL_THIN_UP_BOX); + o->callback((Fl_Callback*)cb_Close1); + } // Fl_Button* o + { Fl_Box* o = new Fl_Box(5, 5, 110, 35, "Send system effect\'s output to other system effects"); + o->labelsize(10); + o->align(192); + } // Fl_Box* o + syseffsendwindow->end(); + } // Fl_Double_Window* syseffsendwindow + { panelwindow = new Fl_Double_Window(630, 635, "ZynAddSubFX Panel"); + panelwindow->user_data((void*)(this)); + { Fl_Scroll* o = new Fl_Scroll(0, 5, 570, 310); + o->type(1); + o->box(FL_THIN_UP_BOX); + { Fl_Pack* o = new Fl_Pack(5, 10, 560, 285); + o->type(1); + for (int i=0;iinit(master,i,bankui);} + o->end(); + } // Fl_Pack* o + o->end(); + } // Fl_Scroll* o + { Fl_Scroll* o = new Fl_Scroll(0, 320, 570, 310); + o->type(1); + o->box(FL_THIN_UP_BOX); + { Fl_Pack* o = new Fl_Pack(5, 325, 560, 285); + o->type(1); + for (int i=NUM_MIDI_PARTS/2;iinit(master,i,bankui);} + o->end(); + } // Fl_Pack* o + o->end(); + } // Fl_Scroll* o + { Fl_Button* o = new Fl_Button(575, 605, 50, 25, "Close"); + o->box(FL_THIN_UP_BOX); + o->labelsize(13); + o->callback((Fl_Callback*)cb_Close2); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(575, 570, 55, 25, "Refresh"); + o->box(FL_THIN_UP_BOX); + o->labelsize(13); + o->callback((Fl_Callback*)cb_Refresh); + } // Fl_Button* o + panelwindow->end(); + } // Fl_Double_Window* panelwindow + { simplemasterwindow = new Fl_Double_Window(600, 335, "ZynAddSubFX"); + simplemasterwindow->callback((Fl_Callback*)cb_simplemasterwindow, (void*)(this)); + { Fl_Menu_Bar* o = new Fl_Menu_Bar(0, 0, 690, 25); + o->menu(menu_); + } // Fl_Menu_Bar* o + { Fl_Group* o = simplelistitemgroup = new Fl_Group(125, 65, 215, 150); + simplelistitemgroup->box(FL_ENGRAVED_BOX); + { partname = new Fl_Button(130, 72, 205, 18); + partname->box(FL_PLASTIC_THIN_DOWN_BOX); + partname->down_box(FL_FLAT_BOX); + partname->color((Fl_Color)247); + partname->labelfont(1); + partname->labelsize(11); + partname->callback((Fl_Callback*)cb_partname1); + partname->align(192|FL_ALIGN_INSIDE); + } // Fl_Button* partname + { Fl_Slider* o = partpanning = new Fl_Slider(185, 95, 70, 15, "Pan"); + partpanning->type(5); + partpanning->box(FL_FLAT_BOX); + partpanning->maximum(127); + partpanning->step(1); + partpanning->value(64); + partpanning->callback((Fl_Callback*)cb_partpanning1); + o->value(master->part[npart]->Ppanning); + } // Fl_Slider* partpanning + { Fl_Choice* o = partrcv = new Fl_Choice(140, 157, 65, 18, "Midi Channel Receive"); + partrcv->tooltip("receive from Midi channel"); + partrcv->down_box(FL_BORDER_BOX); + partrcv->labelsize(10); + partrcv->textfont(1); + partrcv->callback((Fl_Callback*)cb_partrcv1); + partrcv->align(130); + char nrstr[10]; for(int i=0;iadd(nrstr); else o->add("Dr10");}; + o->value(master->part[npart]->Prcvchn); + } // Fl_Choice* partrcv + { WidgetPDial* o = partvolume = new WidgetPDial(145, 95, 30, 30); + partvolume->box(FL_OVAL_BOX); + partvolume->color(FL_BACKGROUND_COLOR); + partvolume->selection_color(FL_INACTIVE_COLOR); + partvolume->labeltype(FL_NORMAL_LABEL); + partvolume->labelfont(0); + partvolume->labelsize(14); + partvolume->labelcolor(FL_FOREGROUND_COLOR); + partvolume->maximum(127); + partvolume->step(1); + partvolume->callback((Fl_Callback*)cb_partvolume1); + partvolume->align(FL_ALIGN_BOTTOM); + partvolume->when(FL_WHEN_CHANGED); + o->value(master->part[npart]->Pvolume); + } // WidgetPDial* partvolume + { new Fl_Box(130, 125, 60, 15, "Volume"); + } // Fl_Box* o + { Fl_Check_Button* o = simplepartportamento = new Fl_Check_Button(260, 95, 75, 20, "Portamento"); + simplepartportamento->tooltip("Enable/Disable the portamento"); + simplepartportamento->down_box(FL_DOWN_BOX); + simplepartportamento->labelfont(1); + simplepartportamento->labelsize(10); + simplepartportamento->callback((Fl_Callback*)cb_simplepartportamento); + o->value(master->part[npart]->ctl.portamento.portamento); + } // Fl_Check_Button* simplepartportamento + { Fl_Counter* o = simpleminkcounter = new Fl_Counter(210, 158, 40, 15, "Min.key"); + simpleminkcounter->tooltip("Minimum key (that the part receives NoteOn messages)"); + simpleminkcounter->type(1); + simpleminkcounter->labelfont(1); + simpleminkcounter->labelsize(10); + simpleminkcounter->minimum(0); + simpleminkcounter->maximum(127); + simpleminkcounter->step(1); + simpleminkcounter->textsize(10); + simpleminkcounter->callback((Fl_Callback*)cb_simpleminkcounter); + o->value(master->part[npart]->Pminkey); + } // Fl_Counter* simpleminkcounter + { Fl_Counter* o = simplemaxkcounter = new Fl_Counter(255, 158, 40, 15, "Max.key"); + simplemaxkcounter->tooltip("Maximum key (that the part receives NoteOn messages)"); + simplemaxkcounter->type(1); + simplemaxkcounter->labelfont(1); + simplemaxkcounter->labelsize(10); + simplemaxkcounter->minimum(0); + simplemaxkcounter->maximum(127); + simplemaxkcounter->step(1); + simplemaxkcounter->textsize(10); + simplemaxkcounter->callback((Fl_Callback*)cb_simplemaxkcounter); + o->value(master->part[npart]->Pmaxkey); + } // Fl_Counter* simplemaxkcounter + { Fl_Button* o = new Fl_Button(230, 188, 15, 12, "m"); + o->tooltip("set the minimum key to the last pressed key"); + o->box(FL_THIN_UP_BOX); + o->labelsize(10); + o->callback((Fl_Callback*)cb_m); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(260, 188, 15, 12, "M"); + o->tooltip("set the maximum key to the last pressed key"); + o->box(FL_THIN_UP_BOX); + o->labelsize(10); + o->callback((Fl_Callback*)cb_M); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(245, 188, 15, 12, "R"); + o->tooltip("reset the minimum key to 0 and maximum key to 127"); + o->box(FL_THIN_UP_BOX); + o->labelfont(1); + o->labelsize(10); + o->callback((Fl_Callback*)cb_R1); + } // Fl_Button* o + { Fl_Counter* o = simplepartkeyshiftcounter = new Fl_Counter(240, 120, 90, 20, "KeyShift"); + simplepartkeyshiftcounter->labelsize(11); + simplepartkeyshiftcounter->minimum(-64); + simplepartkeyshiftcounter->maximum(64); + simplepartkeyshiftcounter->step(1); + simplepartkeyshiftcounter->callback((Fl_Callback*)cb_simplepartkeyshiftcounter); + o->lstep(12); + o->value(master->part[npart]->Pkeyshift-64); + } // Fl_Counter* simplepartkeyshiftcounter + { simplesyseffsend = new WidgetPDial(300, 160, 30, 30); + simplesyseffsend->box(FL_OVAL_BOX); + simplesyseffsend->color(FL_BACKGROUND_COLOR); + simplesyseffsend->selection_color(FL_INACTIVE_COLOR); + simplesyseffsend->labeltype(FL_NORMAL_LABEL); + simplesyseffsend->labelfont(0); + simplesyseffsend->labelsize(14); + simplesyseffsend->labelcolor(FL_FOREGROUND_COLOR); + simplesyseffsend->maximum(127); + simplesyseffsend->step(1); + simplesyseffsend->callback((Fl_Callback*)cb_simplesyseffsend); + simplesyseffsend->align(FL_ALIGN_BOTTOM); + simplesyseffsend->when(FL_WHEN_CHANGED); + } // WidgetPDial* simplesyseffsend + { new Fl_Box(295, 190, 40, 15, "Effect"); + } // Fl_Box* o + if (master->part[npart]->Penabled==0) o->deactivate(); + simplelistitemgroup->end(); + } // Fl_Group* simplelistitemgroup + { Fl_Check_Button* o = partenabled = new Fl_Check_Button(250, 40, 85, 20, "Enabled"); + partenabled->down_box(FL_DOWN_BOX); + partenabled->labeltype(FL_EMBOSSED_LABEL); + partenabled->labelfont(1); + partenabled->labelsize(13); + partenabled->callback((Fl_Callback*)cb_partenabled1); + partenabled->align(FL_ALIGN_RIGHT|FL_ALIGN_INSIDE); + //char tmp[10];snprintf(tmp,10,"%d",npart+1);o->label(strdup(tmp)); + o->value(master->part[npart]->Penabled); + } // Fl_Check_Button* partenabled + { VirKeys* o = virkeys = new VirKeys(5, 215, 590, 80, "Keyboard"); + virkeys->box(FL_BORDER_BOX); + virkeys->color((Fl_Color)17); + virkeys->selection_color(FL_BACKGROUND_COLOR); + virkeys->labeltype(FL_NORMAL_LABEL); + virkeys->labelfont(0); + virkeys->labelsize(14); + virkeys->labelcolor(FL_FOREGROUND_COLOR); + virkeys->align(FL_ALIGN_CENTER); + virkeys->when(FL_WHEN_RELEASE); + o->init(master); + } // VirKeys* virkeys + { Fl_Group* o = new Fl_Group(340, 30, 255, 185); + o->box(FL_ENGRAVED_BOX); + { Fl_Tabs* o = new Fl_Tabs(345, 35, 245, 175); + o->align(FL_ALIGN_BOTTOM|FL_ALIGN_INSIDE); + { Fl_Group* o = new Fl_Group(345, 55, 245, 155, "System Effects"); + o->box(FL_ENGRAVED_FRAME); + o->labelfont(1); + o->labelsize(12); + o->align(FL_ALIGN_BOTTOM|FL_ALIGN_INSIDE); + { Fl_Counter* o = simplesyseffnocounter = new Fl_Counter(350, 75, 80, 20, "Sys.Effect No."); + simplesyseffnocounter->type(1); + simplesyseffnocounter->labelfont(1); + simplesyseffnocounter->labelsize(10); + simplesyseffnocounter->minimum(0); + simplesyseffnocounter->maximum(127); + simplesyseffnocounter->step(1); + simplesyseffnocounter->value(1); + simplesyseffnocounter->textfont(1); + simplesyseffnocounter->callback((Fl_Callback*)cb_simplesyseffnocounter); + simplesyseffnocounter->align(FL_ALIGN_TOP); + o->bounds(1,NUM_SYS_EFX); + o->value(nsyseff+1); + } // Fl_Counter* simplesyseffnocounter + { Fl_Choice* o = simplesysefftype = new Fl_Choice(515, 80, 70, 15, "EffType"); + simplesysefftype->down_box(FL_BORDER_BOX); + simplesysefftype->labelsize(10); + simplesysefftype->callback((Fl_Callback*)cb_simplesysefftype); + simplesysefftype->align(FL_ALIGN_TOP_LEFT); + simplesysefftype->menu(menu_simplesysefftype); + o->value(master->sysefx[nsyseff]->geteffect()); + } // Fl_Choice* simplesysefftype + { simplesyseffectuigroup = new Fl_Group(350, 95, 235, 95); + simplesyseffectuigroup->box(FL_FLAT_BOX); + simplesyseffectuigroup->color((Fl_Color)48); + { SimpleEffUI* o = simplesyseffectui = new SimpleEffUI(350, 95, 234, 95); + simplesyseffectui->box(FL_NO_BOX); + simplesyseffectui->color(FL_BACKGROUND_COLOR); + simplesyseffectui->selection_color(FL_BACKGROUND_COLOR); + simplesyseffectui->labeltype(FL_NORMAL_LABEL); + simplesyseffectui->labelfont(0); + simplesyseffectui->labelsize(14); + simplesyseffectui->labelcolor(FL_FOREGROUND_COLOR); + simplesyseffectui->align(FL_ALIGN_TOP); + simplesyseffectui->when(FL_WHEN_RELEASE); + o->init(master->sysefx[nsyseff]); + simplesyseffectui->end(); + } // SimpleEffUI* simplesyseffectui + simplesyseffectuigroup->end(); + } // Fl_Group* simplesyseffectuigroup + { Fl_Button* o = new Fl_Button(435, 75, 75, 20, "Send to..."); + o->box(FL_THIN_UP_BOX); + o->labelfont(1); + o->labelsize(11); + o->callback((Fl_Callback*)cb_Send1); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(560, 65, 25, 15, "P"); + o->box(FL_THIN_UP_BOX); + o->color((Fl_Color)179); + o->labelfont(1); + o->labelsize(11); + o->labelcolor(FL_BACKGROUND2_COLOR); + o->callback((Fl_Callback*)cb_P2); + } // Fl_Button* o + o->end(); + } // Fl_Group* o + { Fl_Group* o = new Fl_Group(345, 55, 245, 155, "Insertion Effects"); + o->box(FL_ENGRAVED_FRAME); + o->labelfont(1); + o->labelsize(12); + o->align(FL_ALIGN_BOTTOM|FL_ALIGN_INSIDE); + o->hide(); + { Fl_Counter* o = simpleinseffnocounter = new Fl_Counter(350, 75, 80, 20, "Ins.Effect No."); + simpleinseffnocounter->type(1); + simpleinseffnocounter->labelfont(1); + simpleinseffnocounter->labelsize(10); + simpleinseffnocounter->minimum(0); + simpleinseffnocounter->maximum(127); + simpleinseffnocounter->step(1); + simpleinseffnocounter->value(1); + simpleinseffnocounter->textfont(1); + simpleinseffnocounter->callback((Fl_Callback*)cb_simpleinseffnocounter); + simpleinseffnocounter->align(FL_ALIGN_TOP); + o->bounds(1,NUM_INS_EFX); + o->value(ninseff+1); + } // Fl_Counter* simpleinseffnocounter + { Fl_Choice* o = simpleinsefftype = new Fl_Choice(515, 80, 70, 15, "EffType"); + simpleinsefftype->down_box(FL_BORDER_BOX); + simpleinsefftype->labelsize(10); + simpleinsefftype->callback((Fl_Callback*)cb_simpleinsefftype); + simpleinsefftype->align(FL_ALIGN_TOP_LEFT); + simpleinsefftype->menu(menu_simpleinsefftype); + o->value(master->insefx[ninseff]->geteffect()); + if (master->Pinsparts[ninseff]== -1) o->deactivate(); + } // Fl_Choice* simpleinsefftype + { simpleinseffectuigroup = new Fl_Group(350, 95, 234, 95); + simpleinseffectuigroup->box(FL_FLAT_BOX); + simpleinseffectuigroup->color((Fl_Color)48); + { SimpleEffUI* o = simpleinseffectui = new SimpleEffUI(350, 95, 234, 95); + simpleinseffectui->box(FL_NO_BOX); + simpleinseffectui->color(FL_BACKGROUND_COLOR); + simpleinseffectui->selection_color(FL_BACKGROUND_COLOR); + simpleinseffectui->labeltype(FL_NORMAL_LABEL); + simpleinseffectui->labelfont(0); + simpleinseffectui->labelsize(14); + simpleinseffectui->labelcolor(FL_FOREGROUND_COLOR); + simpleinseffectui->align(FL_ALIGN_TOP); + simpleinseffectui->when(FL_WHEN_RELEASE); + o->init(master->insefx[ninseff]); + if (master->Pinsparts[ninseff]== -1) o->deactivate(); + simpleinseffectui->end(); + } // SimpleEffUI* simpleinseffectui + simpleinseffectuigroup->end(); + } // Fl_Group* simpleinseffectuigroup + { Fl_Choice* o = simpleinseffpart = new Fl_Choice(435, 75, 80, 20, "Insert To."); + simpleinseffpart->down_box(FL_BORDER_BOX); + simpleinseffpart->labelfont(1); + simpleinseffpart->labelsize(10); + simpleinseffpart->textsize(10); + simpleinseffpart->callback((Fl_Callback*)cb_simpleinseffpart); + simpleinseffpart->align(FL_ALIGN_TOP_LEFT); + o->add("Master Out");o->add("Off"); + char tmp[50]; for (int i=0;iadd(tmp);}; + o->value(master->Pinsparts[ninseff]+2); + } // Fl_Choice* simpleinseffpart + { Fl_Button* o = new Fl_Button(560, 65, 25, 15, "P"); + o->box(FL_THIN_UP_BOX); + o->color((Fl_Color)179); + o->labelfont(1); + o->labelsize(11); + o->labelcolor(FL_BACKGROUND2_COLOR); + o->callback((Fl_Callback*)cb_P3); + } // Fl_Button* o + o->end(); + } // Fl_Group* o + o->end(); + } // Fl_Tabs* o + o->end(); + } // Fl_Group* o + { Fl_Group* o = new Fl_Group(5, 300, 590, 30); + o->box(FL_ENGRAVED_FRAME); + { VUMeter* o = new VUMeter(5, 300, 590, 30, "VU-Meter"); + o->box(FL_FLAT_BOX); + o->color((Fl_Color)41); + o->selection_color((Fl_Color)75); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(14); + o->labelcolor(FL_FOREGROUND_COLOR); + o->align(FL_ALIGN_CENTER); + o->when(FL_WHEN_RELEASE); + o->init(master,-1); + } // VUMeter* o + o->end(); + } // Fl_Group* o + { WidgetPDial* o = simplemastervolumedial = new WidgetPDial(10, 35, 40, 40, "Master Volume"); + simplemastervolumedial->tooltip("Master Volume"); + simplemastervolumedial->box(FL_ROUND_UP_BOX); + simplemastervolumedial->color(FL_BACKGROUND_COLOR); + simplemastervolumedial->selection_color(FL_INACTIVE_COLOR); + simplemastervolumedial->labeltype(FL_NORMAL_LABEL); + simplemastervolumedial->labelfont(1); + simplemastervolumedial->labelsize(11); + simplemastervolumedial->labelcolor(FL_FOREGROUND_COLOR); + simplemastervolumedial->maximum(127); + simplemastervolumedial->step(1); + simplemastervolumedial->callback((Fl_Callback*)cb_simplemastervolumedial); + simplemastervolumedial->align(130); + simplemastervolumedial->when(FL_WHEN_CHANGED); + o->value(master->Pvolume); + } // WidgetPDial* simplemastervolumedial + { Fl_Counter* o = simplemasterkeyshiftcounter = new Fl_Counter(25, 110, 90, 20, "Master KeyShift"); + simplemasterkeyshiftcounter->labelsize(11); + simplemasterkeyshiftcounter->minimum(-64); + simplemasterkeyshiftcounter->maximum(64); + simplemasterkeyshiftcounter->step(1); + simplemasterkeyshiftcounter->callback((Fl_Callback*)cb_simplemasterkeyshiftcounter); + o->lstep(12); + o->value(master->Pkeyshift-64); + } // Fl_Counter* simplemasterkeyshiftcounter + { Fl_Button* o = new Fl_Button(5, 149, 115, 31, "Stop ALL sounds!"); + o->box(FL_PLASTIC_UP_BOX); + o->color((Fl_Color)231); + o->labelfont(1); + o->labelsize(11); + o->callback((Fl_Callback*)cb_Stop); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(70, 32, 50, 10, "Reset"); + o->tooltip("Master fine detune reset"); + o->box(FL_THIN_UP_BOX); + o->labelfont(1); + o->labelsize(11); + o->callback((Fl_Callback*)cb_Reset); + o->align(FL_ALIGN_WRAP); + } // Fl_Button* o + { WidgetPDial* o = simpleglobalfinedetuneslider = new WidgetPDial(80, 45, 30, 30, "Fine Detune"); + simpleglobalfinedetuneslider->tooltip("global fine detune"); + simpleglobalfinedetuneslider->box(FL_ROUND_UP_BOX); + simpleglobalfinedetuneslider->color(FL_BACKGROUND_COLOR); + simpleglobalfinedetuneslider->selection_color(FL_INACTIVE_COLOR); + simpleglobalfinedetuneslider->labeltype(FL_NORMAL_LABEL); + simpleglobalfinedetuneslider->labelfont(0); + simpleglobalfinedetuneslider->labelsize(11); + simpleglobalfinedetuneslider->labelcolor(FL_FOREGROUND_COLOR); + simpleglobalfinedetuneslider->maximum(127); + simpleglobalfinedetuneslider->step(1); + simpleglobalfinedetuneslider->value(64); + simpleglobalfinedetuneslider->callback((Fl_Callback*)cb_simpleglobalfinedetuneslider); + simpleglobalfinedetuneslider->align(130); + simpleglobalfinedetuneslider->when(FL_WHEN_CHANGED); + o->value(master->microtonal.Pglobalfinedetune); + } // WidgetPDial* simpleglobalfinedetuneslider + { Fl_Counter* o = simplenpartcounter = new Fl_Counter(170, 40, 70, 20, "Part"); + simplenpartcounter->tooltip("The part number"); + simplenpartcounter->type(1); + simplenpartcounter->labelfont(1); + simplenpartcounter->minimum(0); + simplenpartcounter->maximum(127); + simplenpartcounter->step(1); + simplenpartcounter->value(1); + simplenpartcounter->textfont(1); + simplenpartcounter->callback((Fl_Callback*)cb_simplenpartcounter); + simplenpartcounter->align(FL_ALIGN_LEFT); + o->bounds(1,NUM_MIDI_PARTS); + } // Fl_Counter* simplenpartcounter + { Fl_Counter* o = new Fl_Counter(5, 195, 55, 20, "Keyb.Oct."); + o->tooltip("Midi Octave"); + o->type(1); + o->labelsize(11); + o->minimum(0); + o->maximum(5); + o->step(1); + o->textfont(1); + o->textsize(11); + o->callback((Fl_Callback*)cb_Keyb); + o->align(FL_ALIGN_RIGHT); + o->when(FL_WHEN_RELEASE_ALWAYS); + o->value(virkeys->midioct); + } // Fl_Counter* o + simplemasterwindow->end(); + } // Fl_Double_Window* simplemasterwindow + { selectuiwindow = new Fl_Double_Window(430, 250, "User Interface mode"); + selectuiwindow->callback((Fl_Callback*)cb_selectuiwindow, (void*)(this)); + { Fl_Box* o = new Fl_Box(5, 5, 425, 40, "Welcome to ZynAddSubFX"); + o->labeltype(FL_SHADOW_LABEL); + o->labelfont(1); + o->labelsize(26); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(10, 50, 265, 25, "Please choose the interface mode:"); + o->labelfont(1); + o->labelsize(13); + } // Fl_Box* o + { Fl_Button* o = new Fl_Button(10, 165, 100, 35, "Advanced"); + o->box(FL_PLASTIC_UP_BOX); + o->color((Fl_Color)229); + o->labelfont(1); + o->labelsize(16); + o->callback((Fl_Callback*)cb_Advanced); + } // Fl_Button* o + { Fl_Box* o = new Fl_Box(110, 165, 310, 35, ".. if you have used ZynAddSubFX before, or you like to have full controll to \ +all parameters."); + o->labelfont(1); + o->labelsize(11); + o->align(FL_ALIGN_WRAP|FL_ALIGN_INSIDE); + } // Fl_Box* o + { Fl_Button* o = new Fl_Button(10, 80, 100, 65, "Beginner"); + o->box(FL_PLASTIC_UP_BOX); + o->color((Fl_Color)238); + o->labelfont(1); + o->labelsize(16); + o->callback((Fl_Callback*)cb_Beginner); + } // Fl_Button* o + { Fl_Box* o = new Fl_Box(110, 75, 320, 75, "..if you are a beginner, you prefer using presets or you prefer to use simple\ +r user interfaces. Most functionality of ZynAddSubFX will be hidden in this mo\ +de to make simple the learning/using it."); + o->labelfont(1); + o->labelsize(11); + o->align(FL_ALIGN_WRAP|FL_ALIGN_INSIDE); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(30, 215, 360, 25, "You can switch the interface modes anytime you want."); + o->box(FL_BORDER_BOX); + o->color((Fl_Color)51); + o->labelfont(1); + o->labelsize(11); + o->align(FL_ALIGN_WRAP|FL_ALIGN_INSIDE); + } // Fl_Box* o + selectuiwindow->set_non_modal(); + selectuiwindow->end(); + } // Fl_Double_Window* selectuiwindow + return selectuiwindow; +} + +void MasterUI::updatesendwindow() { + for (int neff1=0;neff1value(master->Psysefxsend[neff1][neff2]); +} + +void MasterUI::updatepanel() { + for (int npart=0;npartrefresh(); +}; +} + +void MasterUI::setfilelabel(const char *filename) { + if (filename!=NULL) snprintf(&masterwindowlabel[0],100,"%s - ZynAddSubFX",fl_filename_name(filename)); + else snprintf(&masterwindowlabel[0],100,"%s","ZynAddSubFX (c)2002-2006 Nasca Paul and others"); +masterwindowlabel[99]='\0'; +masterwindow->label(&masterwindowlabel[0]); +simplemasterwindow->label(&masterwindowlabel[0]); +} + +MasterUI::MasterUI(Master *master_,int *exitprogram_) { + master=master_; +exitprogram=exitprogram_; +ninseff=0; +nsyseff=0; +npart=0; + +for (int i=0;imicrotonal); +virkeyboard=new VirKeyboard(master); +bankui=new BankUI(master,&npart); +configui=new ConfigUI(); +sequi=new SeqUI(master); + +make_window(); +presetsui=new PresetsUI(); +setfilelabel(NULL); +swapefftype=0; +simplerefresh(); +} + +MasterUI::~MasterUI() { + masterwindow->hide(); +delete (masterwindow); +aboutwindow->hide(); +delete (aboutwindow); +syseffsendwindow->hide(); +delete(syseffsendwindow); + +delete (virkeyboard); +delete (microtonalui); +delete (bankui); +delete (configui); +delete (sequi); + +delete(presetsui); +} + +void MasterUI::showUI() { + switch (config.cfg.UserInterfaceMode){ + case 0:selectuiwindow->show(); + break; + case 1:masterwindow->show(); + break; + case 2:simplemasterwindow->show(); + break; +}; +} + +void MasterUI::simplerefresh() { + partenabled->value(master->part[npart]->Penabled); +if (master->part[npart]->Penabled!=0) simplelistitemgroup->activate(); + else simplelistitemgroup->deactivate(); + +partvolume->value(master->part[npart]->Pvolume); +partpanning->value(master->part[npart]->Ppanning); +partrcv->value(master->part[npart]->Prcvchn); + +if (master->part[npart]->Pname[0]!=0) partname->label((char *)master->part[npart]->Pname); + else partname->label("Click here to load a instrument"); + +simplelistitemgroup->redraw(); +simplepartportamento->value(master->part[npart]->ctl.portamento.portamento); +simpleminkcounter->value(master->part[npart]->Pminkey); +simplemaxkcounter->value(master->part[npart]->Pmaxkey); + +simplepartkeyshiftcounter->value(master->part[npart]->Pkeyshift-64); +simplesyseffsend->value(master->Psysefxvol[nsyseff][npart]); +} + +void MasterUI::do_new_master() { + if (fl_choice("Clear *ALL* the parameters ?","No","Yes",NULL)){ + delete microtonalui; + + pthread_mutex_lock(&master->mutex); + master->defaults(); + pthread_mutex_unlock(&master->mutex); + + npartcounter->value(1); + refresh_master_ui(); + +}; + +updatepanel(); +} + +void MasterUI::do_load_master(char* file ) { + char *filename; + if (file == NULL) { + filename=fl_file_chooser("Open:","({*.xmz})",NULL,0); + if (filename==NULL) return; + } + else { + filename = file; + } + + +pthread_mutex_lock(&master->mutex); + //clear all parameters + master->defaults(); + + //load the data + int result=master->loadXML(filename); +pthread_mutex_unlock(&master->mutex); +master->applyparameters(); + +npartcounter->value(1); +refresh_master_ui(); +updatepanel(); +if (result>=0) setfilelabel(filename); + + +if (result==-10) fl_alert("Error: Could not load the file\nbecause it is not a zynaddsubfx parameters file."); + else if (result<0) fl_alert("Error: Could not load the file."); +} + +void MasterUI::do_save_master(char* file ) { + char *filename; + int result=0; + if (file == NULL) { + filename=fl_file_chooser("Save:","({*.xmz})",NULL,0); + if (filename==NULL) return; + filename=fl_filename_setext(filename,".xmz"); + result=fileexists(filename); + if (result) { + result=0; + if (!fl_choice("The file exists. Overwrite it?","No","Yes",NULL)) return; + + } + } + else { + filename = file; + } + + +pthread_mutex_lock(&master->mutex); +result=master->saveXML(filename); +pthread_mutex_unlock(&master->mutex); + +if (result<0) fl_alert("Error: Could not save the file."); + else setfilelabel(filename); + +updatepanel(); +} + +void MasterUI::refresh_master_ui() { + ninseff=0; +nsyseff=0; +npart=0; + +//the Master UI +npartcounter->do_callback(); +syseffnocounter->do_callback(); +inseffnocounter->do_callback(); +masterkeyshiftcounter->value(master->Pkeyshift-64); +mastervolumedial->value(master->Pvolume); +globalfinedetuneslider->value(master->microtonal.Pglobalfinedetune); +microtonalui=new MicrotonalUI(&master->microtonal); +nrpnbutton->value(master->ctl.NRPN.receive); +updatesendwindow(); +updatepanel(); + +//the simle MasterUI +simplenpartcounter->value(1); +simplesyseffnocounter->value(1); +simpleinseffnocounter->value(1); +simplenpartcounter->do_callback(); +simplesyseffnocounter->do_callback(); +simpleinseffnocounter->do_callback(); +simplemasterkeyshiftcounter->value(master->Pkeyshift-64); +simplemastervolumedial->value(master->Pvolume); +simpleglobalfinedetuneslider->value(master->microtonal.Pglobalfinedetune); +virkeys->midich=master->part[npart]->Prcvchn; + +simplerefresh(); +bankui->hide(); +} diff --git a/plugins/zynaddsubfx/src/UI/MasterUI.fl b/plugins/zynaddsubfx/src/UI/MasterUI.fl new file mode 100644 index 000000000..dbe81aa03 --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/MasterUI.fl @@ -0,0 +1,1811 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0107 +header_name {.h} +code_name {.cc} +decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} + +decl {//License: GNU GPL version 2 or later} {} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include "WidgetPDial.h"} {public +} + +decl {\#include "ADnoteUI.h"} {public +} + +decl {\#include "SUBnoteUI.h"} {public +} + +decl {\#include "EffUI.h"} {public +} + +decl {\#include "VirKeyboard.h"} {public +} + +decl {\#include "ConfigUI.h"} {public +} + +decl {\#include "BankUI.h"} {public +} + +decl {\#include "PartUI.h"} {public +} + +decl {\#include "MicrotonalUI.h"} {public +} + +decl {\#include "SeqUI.h"} {public +} + +decl {\#include "PresetsUI.h"} {public +} + +decl {\#include "../Misc/Master.h"} {public +} + +decl {\#include "../Misc/Part.h"} {public +} + +decl {\#include "../Misc/Util.h"} {public +} + +decl {\#include "../globals.h"} {public +} + +class VUMeter {: {public Fl_Box} +} { + Function {VUMeter(int x,int y, int w, int h, const char *label=0):Fl_Box(x,y,w,h,label)} {} { + code {master=NULL; +npart=-1;} {} + } + Function {init(Master *master_,int part_)} {} { + code {//the "part_" parameters sets the part (if it is >=0), else it sets the master +master=master_; +label(NULL); +npart=part_; +olddbl=0.0; +olddbr=0.0; +oldrmsdbl=0.0; +oldrmsdbr=0.0;} {} + } + Function {draw_master()} {} { + code {\#define MIN_DB (-48) + +int ox=x(); int oy=y(); int lx=w(); int ly=h(); + +pthread_mutex_lock(&master->mutex); +REALTYPE dbl=rap2dB(master->vuoutpeakl); +REALTYPE dbr=rap2dB(master->vuoutpeakr); +REALTYPE rmsdbl=rap2dB(master->vurmspeakl); +REALTYPE rmsdbr=rap2dB(master->vurmspeakr); +REALTYPE maxdbl=rap2dB(master->vumaxoutpeakl); +REALTYPE maxdbr=rap2dB(master->vumaxoutpeakr); +int clipped=master->vuclipped; +pthread_mutex_unlock(&master->mutex); + +dbl=(MIN_DB-dbl)/MIN_DB; +if (dbl<0.0) dbl=0.0; + else if (dbl>1.0)dbl=1.0; + +dbr=(MIN_DB-dbr)/MIN_DB; +if (dbr<0.0) dbr=0.0; + else if (dbr>1.0) dbr=1.0; + +dbl=dbl*0.4+olddbl*0.6; +dbr=dbr*0.4+olddbr*0.6; + +olddbl=dbl; +olddbr=dbr; + +\#define VULENX (lx-35) +\#define VULENY (ly/2-3) + +dbl*=VULENX;dbr*=VULENX; + +int idbl=(int) dbl; +int idbr=(int) dbr; + +//compute RMS - start +rmsdbl=(MIN_DB-rmsdbl)/MIN_DB; +if (rmsdbl<0.0) rmsdbl=0.0; + else if (rmsdbl>1.0) rmsdbl=1.0; + +rmsdbr=(MIN_DB-rmsdbr)/MIN_DB; +if (rmsdbr<0.0) rmsdbr=0.0; + else if (rmsdbr>1.0) rmsdbr=1.0; + +rmsdbl=rmsdbl*0.4+oldrmsdbl*0.6; +rmsdbr=rmsdbr*0.4+oldrmsdbr*0.6; + +oldrmsdbl=rmsdbl; +oldrmsdbr=rmsdbr; + + +rmsdbl*=VULENX;rmsdbr*=VULENX; + +int irmsdbl=(int) rmsdbl; +int irmsdbr=(int) rmsdbr; +//compute RMS - end + + + +//draw the vu-meter lines +//db +fl_rectf(ox,oy,idbr,VULENY,0,200,255); +fl_rectf(ox,oy+ly/2,idbl,VULENY,0,200,255); +//black +fl_rectf(ox+idbr,oy,VULENX-idbr,VULENY,0,0,0); +fl_rectf(ox+idbl,oy+ly/2,VULENX-idbl,VULENY,0,0,0); + +//draw the scales +REALTYPE tmp=VULENX*1.0/MIN_DB; +for (int i=1;i<1-MIN_DB;i++){ + int tx=VULENX+(int) (tmp*i); + fl_rectf(ox+tx,oy,1,VULENY+ly/2,0,160,200); + if (i%5==0) fl_rectf(ox+tx,oy,1,VULENY+ly/2,0,230,240); + if (i%10==0) fl_rectf(ox+tx-1,oy,2,VULENY+ly/2,0,225,255); +}; + +//rms +if (irmsdbr>2) fl_rectf(ox+irmsdbr-1,oy,3,VULENY,255,255,0); +if (irmsdbl>2) fl_rectf(ox+irmsdbl-1,oy+ly/2,3,VULENY,255,255,0); + + +//draw the red box if clipping has occured +if (clipped==0) fl_rectf(ox+VULENX+2,oy+1,lx-VULENX-3,ly-4,0,0,10); + else fl_rectf(ox+VULENX+2,oy+1,lx-VULENX-3,ly-4,250,10,10); + +//draw the maxdB +fl_font(FL_HELVETICA|FL_BOLD,10); +fl_color(255,255,255); +char tmpstr[10]; +if ((maxdbl>MIN_DB-20)){ + snprintf((char *)&tmpstr,10,"%ddB",(int)maxdbr); + fl_draw(tmpstr,ox+VULENX+1,oy+1,lx-VULENX-1,VULENY,FL_ALIGN_RIGHT,NULL,0); +}; +if ((maxdbr>MIN_DB-20)){ + snprintf((char *)&tmpstr,10,"%ddB",(int)maxdbl); + fl_draw(tmpstr,ox+VULENX+1,oy+ly/2+1,lx-VULENX-1,VULENY,FL_ALIGN_RIGHT,NULL,0); +};} {} + } + Function {draw_part()} {} { + code {\#define MIN_DB (-48) +int ox=x(); int oy=y(); int lx=w(); int ly=h(); + +if (!active_r()){ + pthread_mutex_lock(&master->mutex); + int fakedb=master->fakepeakpart[npart]; + pthread_mutex_unlock(&master->mutex); + fl_rectf(ox,oy,lx,ly,140,140,140); + if (fakedb>0){ + fakedb=(int)(fakedb/255.0*ly)+4; + fl_rectf(ox+2,oy+ly-fakedb,lx-4,fakedb,0,0,0); + }; + + return; +}; + +//draw the vu lines +pthread_mutex_lock(&master->mutex); + REALTYPE db=rap2dB(master->vuoutpeakpart[npart]); +pthread_mutex_unlock(&master->mutex); + +db=(MIN_DB-db)/MIN_DB; +if (db<0.0) db=0.0; + else if (db>1.0) db=1.0; + +db*=ly-2; + +int idb=(int) db; + +fl_rectf(ox,oy+ly-idb,lx,idb,0,200,255); +fl_rectf(ox,oy,lx,ly-idb,0,0,0); + + +//draw the scales +REALTYPE tmp=ly*1.0/MIN_DB; + for (int i=1;i<1-MIN_DB;i++){ + int ty=ly+(int) (tmp*i); + if (i%5==0) fl_rectf(ox,oy+ly-ty,lx,1,0,160,200); + if (i%10==0) fl_rectf(ox,oy+ly-ty,lx,1,0,230,240); +};} {} + } + Function {draw()} {} { + code {if (npart>=0) draw_part(); + else draw_master();} {} + } + Function {tickdraw(VUMeter *o)} {return_type {static void} + } { + code {o->redraw();} {} + } + Function {tick(void *v)} {return_type {static void} + } { + code {tickdraw((VUMeter *) v); +Fl::add_timeout(1.0/25.0,tick,v);//25 fps} {} + } + Function {handle(int event)} {return_type int + } { + code {switch(event){ + case FL_SHOW: + tick(this); + break; + case FL_HIDE: + Fl::remove_timeout(tick,this); + break; + case FL_PUSH: + if (npart>=0) break; + pthread_mutex_lock(&master->mutex); + master->vuresetpeaks(); + pthread_mutex_unlock(&master->mutex); + break; +}; +return(1);} {} + } + decl {Master *master;} {} + decl {int npart;} {} + decl {float olddbl,olddbr;} {} + decl {float oldrmsdbl,oldrmsdbr;} {} +} + +class SysEffSend {: {public WidgetPDial} +} { + Function {SysEffSend(int x,int y, int w, int h, const char *label=0):WidgetPDial(x,y,w,h,label)} {} { + code {master=NULL; +neff1=0; +neff2=0;} {} + } + Function {init(Master *master_,int neff1_,int neff2_)} {} { + code {neff1=neff1_; +neff2=neff2_; +master=master_; +minimum(0); +maximum(127); +step(1); +labelfont(1); +labelsize(10); +align(FL_ALIGN_TOP); + +value(master->Psysefxsend[neff1][neff2]); +char tmp[20];snprintf(tmp,20,"%d->%d",neff1+1,neff2+1);this->label(strdup(tmp));} {} + } + Function {~SysEffSend()} {} { + code {hide();} {} + } + Function {handle(int event)} {return_type int + } { + code {if ((event==FL_PUSH) || (event==FL_DRAG)){ + master->setPsysefxsend(neff1,neff2,(int) value()); +}; + +return(WidgetPDial::handle(event));} {} + } + decl {Master *master;} {} + decl {int neff1;} {} + decl {int neff2;} {} +} + +class Panellistitem {: {public Fl_Group} +} { + Function {make_window()} {private + } { + Fl_Window panellistitem { + private xywh {315 213 70 260} type Double hide + class Fl_Group + } { + Fl_Group panellistitemgroup { + private xywh {0 20 70 240} box PLASTIC_THIN_UP_BOX + code0 {if (master->part[npart]->Penabled==0) o->deactivate();} + } { + Fl_Group {} { + xywh {45 65 15 110} box ENGRAVED_FRAME + } { + Fl_Box {} { + label {V U} + xywh {45 65 15 110} box FLAT_BOX color 0 selection_color 75 labelcolor 55 align 128 + code0 {o->init(master,npart);} + class VUMeter + } + } + Fl_Button partname { + label { } + callback {if ((int)bankui->cbwig->value()!=(npart+1)){ + bankui->cbwig->value(npart+1); + bankui->cbwig->do_callback(); +}; +bankui->show();} + xywh {5 27 60 30} box THIN_DOWN_BOX down_box FLAT_BOX labelfont 1 labelsize 10 align 208 + } + Fl_Slider partvolume { + callback {master->part[npart]->setPvolume((int) o->value());} + xywh {10 65 30 110} type {Vert Knob} box FLAT_BOX minimum 127 maximum 0 step 1 value 127 + code0 {o->value(master->part[npart]->Pvolume);} + } + Fl_Dial partpanning { + callback {master->part[npart]->setPpanning((int) o->value());} + xywh {20 180 30 30} maximum 127 step 1 + code0 {o->value(master->part[npart]->Ppanning);} + class WidgetPDial + } + Fl_Button {} { + label edit + callback {if ((int)bankui->cbwig->value()!=(npart+1)){ + bankui->cbwig->value(npart+1); + bankui->cbwig->do_callback(); +};} + xywh {15 235 40 20} box PLASTIC_UP_BOX labelsize 10 + } + Fl_Choice partrcv { + callback {master->part[npart]->Prcvchn=(int) o->value();} open + tooltip {receive from Midi channel} xywh {10 213 50 15} down_box BORDER_BOX labelsize 10 align 5 textfont 1 textsize 10 + code0 {char nrstr[10]; for(int i=0;iadd(nrstr); else o->add("Dr10");};} + code1 {o->value(master->part[npart]->Prcvchn);} + } {} + } + Fl_Check_Button partenabled { + label 01 + callback {pthread_mutex_lock(&master->mutex); + master->partonoff(npart,(int) o->value()); +pthread_mutex_unlock(&master->mutex); + +if ((int) o->value()==0) panellistitemgroup->deactivate(); + else { + panellistitemgroup->activate(); + if ((int)bankui->cbwig->value()!=(npart+1)){ + bankui->cbwig->value(npart+1); + bankui->cbwig->do_callback(); + }; +}; + +o->redraw();} + private xywh {5 0 45 20} down_box DOWN_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 13 align 24 + code0 {char tmp[10];snprintf(tmp,10,"%d",npart+1);o->label(strdup(tmp));} + code1 {o->value(master->part[npart]->Penabled);} + } + } + } + Function {Panellistitem(int x,int y, int w, int h, const char *label=0):Fl_Group(x,y,w,h,label)} {} { + code {npart=0; +master=NULL; +bankui=NULL;} {} + } + Function {init(Master *master_, int npart_,BankUI *bankui_)} {} { + code {npart=npart_; +master=master_; +bankui=bankui_; + +make_window(); +panellistitem->show(); +end();} {} + } + Function {refresh()} {open + } { + code {partenabled->value(master->part[npart]->Penabled); +if (master->part[npart]->Penabled!=0) panellistitemgroup->activate(); + else panellistitemgroup->deactivate(); + +partvolume->value(master->part[npart]->Pvolume); +partpanning->value(master->part[npart]->Ppanning); +partrcv->value(master->part[npart]->Prcvchn); + +partname->label((char *)master->part[npart]->Pname); + +if ((int)bankui->cbwig->value()!=(npart+1)) + panellistitemgroup->color(fl_rgb_color(160,160,160)); +else + panellistitemgroup->color(fl_rgb_color(50,190,240)); + +panellistitemgroup->redraw();} {} + } + Function {~Panellistitem()} {} { + code {panellistitem->hide(); +//delete(panellistitem);} {} + } + decl {int npart;} {} + decl {Master *master;} {} + decl {BankUI *bankui;} {} +} + +class MasterUI {open +} { + Function {make_window()} {open + } { + Fl_Window masterwindow { + xclass zynaddsubfx + label zynaddsubfx + callback {\#ifdef VSTAUDIOOUT +fl_alert("ZynAddSubFX could not be closed this way, because it's a VST plugin. Please use the host aplication to close it."); +\#else +if (fl_choice("Exit and leave the unsaved data?","No","Yes",NULL)) { + config.save(); + *exitprogram=1; +}; +\#endif} + xywh {31 206 390 465} type Double visible + } { + Fl_Menu_Bar mastermenu { + xywh {-5 0 690 25} + } { + Submenu {} { + label {&File} + xywh {0 0 100 20} + } { + MenuItem {} { + label {&New (erase all)...} + callback {do_new_master();} + xywh {20 20 100 20} + } + MenuItem {} { + label {&Open Parameters...} + callback {do_load_master();} + xywh {20 20 100 20} + } + MenuItem {} { + label {&Save All Parameters...} + callback {do_save_master();} + xywh {10 10 100 20} divider + } + MenuItem {} { + label {&Load Scale Settings...} + callback {char *filename; +filename=fl_file_chooser("Open:","({*.xsz})",NULL,0); +if (filename==NULL) return; + +pthread_mutex_lock(&master->mutex); + //clear all parameters + master->microtonal.defaults(); + + //load the data + int result=master->microtonal.loadXML(filename); +pthread_mutex_unlock(&master->mutex); + + + delete microtonalui; + microtonalui=new MicrotonalUI(&master->microtonal); + +if (result==-10) fl_alert("Error: Could not load the file\\nbecause it is not a scale file."); + else if (result<0) fl_alert("Error: Could not load the file.");} + xywh {35 35 100 20} + } + MenuItem {} { + label {Save Sc&ale Settings ..} + callback {char *filename; +int result=0; + +filename=fl_file_chooser("Save:","({*.xsz})",NULL,0); +if (filename==NULL) return; +filename=fl_filename_setext(filename,".xsz"); + +result=fileexists(filename); +if (result) { + result=0; + if (!fl_choice("The file exists. \\nOverwrite it?","No","Yes",NULL)) return; + +}; + + +pthread_mutex_lock(&master->mutex); +result=master->microtonal.saveXML(filename); +pthread_mutex_unlock(&master->mutex); + +if (result<0) fl_alert("Error: Could not save the file."); + + +updatepanel();} + xywh {25 25 100 20} + } + MenuItem {} { + label {Show Scale Settings...} + callback {microtonalui->show();} + xywh {0 0 100 20} divider + } + MenuItem {} { + label {&Settings...} + callback {configui->show();} + xywh {25 25 100 20} divider + } + MenuItem {} { + label {&Copyright...} + callback {aboutwindow->show();} + xywh {15 15 100 20} divider + } + MenuItem {} { + label {E&xit} + callback {masterwindow->do_callback();} + xywh {10 10 100 20} + } + } + Submenu {} { + label {&Instrument} + xywh {10 10 100 20} + } { + MenuItem {} { + label {&Clear Instrument...} + callback {if (fl_choice("Clear instrument's parameters ?","No","Yes",NULL)){ +// int npart=(int)npartcounter->value()-1; + pthread_mutex_lock(&master->mutex); + master->part[npart]->defaultsinstrument(); + pthread_mutex_unlock(&master->mutex); + + npartcounter->do_callback(); +}; + +updatepanel();} + xywh {35 35 100 20} + } + MenuItem {} { + label {&Open Instrument...} + callback {const char *filename; +filename=fl_file_chooser("Load:","({*.xiz})",NULL,0); +if (filename==NULL) return; + + +pthread_mutex_lock(&master->mutex); +// int npart=(int)npartcounter->value()-1; + + //clear all instrument parameters, first + master->part[npart]->defaultsinstrument(); + + //load the instr. parameters + int result=master->part[npart]->loadXMLinstrument(filename); + +pthread_mutex_unlock(&master->mutex); +master->part[npart]->applyparameters(); + +npartcounter->do_callback(); +updatepanel(); + +if (result==-10) fl_alert("Error: Could not load the file\\nbecause it is not an instrument file."); + else if (result<0) fl_alert("Error: Could not load the file.");} + xywh {30 30 100 20} + } + MenuItem {} { + label {&Save Instrument ...} + callback {char *filename; + +filename=fl_file_chooser("Save:","({*.xiz})",NULL,0); +if (filename==NULL) return; +filename=fl_filename_setext(filename,".xiz"); + +int result=fileexists(filename); +if (result) { + result=0; + if (!fl_choice("The file exists. \\nOverwrite it?","No","Yes",NULL)) return; + +}; + + +pthread_mutex_lock(&master->mutex); +result=master->part[npart]->saveXML(filename); +pthread_mutex_unlock(&master->mutex); + +if (result<0) fl_alert("Error: Could not save the file."); + +updatepanel();} + xywh {20 20 100 20} divider + } + MenuItem {} { + label {Show Instrument &Bank...} + callback {bankui->show();} + xywh {0 0 100 20} divider + } + MenuItem {} { + label {&Virtual Keyboard...} + callback {virkeyboard->show();} + xywh {10 10 100 20} + } + } + Submenu recordmenu { + label {&Record} + xywh {0 0 100 20} + } { + MenuItem {} { + label {&Choose WAV file...} + callback {char *filename; +recordbutton->deactivate(); +pausebutton->deactivate(); +pauselabel->deactivate(); +stopbutton->deactivate(); +filename=fl_file_chooser("Record to audio file:","(*.wav)",NULL,0); +if (filename==NULL) return; +fl_filename_setext(filename,".wav"); + +int result=master->HDDRecorder.preparefile(filename,0); +if (result==1) { + result=0; + if (fl_choice("The file exists. \\nOverwrite it?","No","Yes",NULL)) + master->HDDRecorder.preparefile(filename,1); +}; +if (result==0) recordbutton->activate(); + +if (result!=0) fl_alert("Error: Could not save the file.");} + xywh {0 0 100 20} + } + } + Submenu {} { + label {&Sequencer} + xywh {0 0 100 20} hide + } { + MenuItem {} { + label {Show &Sequencer...} + callback {sequi->show();} + xywh {0 0 100 20} + } + } + Submenu {} { + label Misc + xywh {10 10 100 20} + } { + MenuItem {} { + label {Switch User Interface Mode} + callback {if (fl_choice("Switch the User Interface to Beginner mode ?","No","Yes",NULL)){ + masterwindow->hide(); + refresh_master_ui(); + simplemasterwindow->show(); + config.cfg.UserInterfaceMode=2; +};} + xywh {10 10 100 20} + } + } + } + Fl_Dial mastervolumedial { + label {M.Vol} + callback {master->setPvolume((int) o->value());} + tooltip {Master Volume} xywh {5 30 30 30} box ROUND_UP_BOX labelfont 1 labelsize 11 align 130 maximum 127 step 1 + code0 {o->value(master->Pvolume);} + class WidgetPDial + } + Fl_Counter masterkeyshiftcounter { + label {Master KeyShift} + callback {master->setPkeyshift((int) o->value()+64);} + xywh {45 31 90 20} labelsize 11 minimum -64 maximum 64 step 1 + code0 {o->lstep(12);} + code1 {o->value(master->Pkeyshift-64);} + } + Fl_Button {} { + label {Panic!} + callback {virkeyboard->relaseallkeys(); +pthread_mutex_lock(&master->mutex); +master->shutup=1; +pthread_mutex_unlock(&master->mutex);} + xywh {293 29 92 31} box PLASTIC_UP_BOX color 231 labelfont 1 + } + Fl_Group partuigroup { + xywh {0 242 390 183} box ENGRAVED_FRAME + } { + Fl_Group partui { + xywh {4 245 383 175} box FLAT_BOX + code0 {o->init(master->part[0],master,0,bankui);} + code1 {o->show();} + class PartUI + } {} + } + Fl_Tabs {} { + xywh {0 80 390 160} + } { + Fl_Group {} { + label {System Effects} open + xywh {0 100 390 140} box ENGRAVED_FRAME labeltype EMBOSSED_LABEL labelsize 15 align 25 + } { + Fl_Counter syseffnocounter { + label {Sys.Effect No.} + callback {nsyseff=(int) o->value()-1; +sysefftype->value(master->sysefx[nsyseff]->geteffect()); +syseffectui->refresh(master->sysefx[nsyseff]);} + xywh {5 120 80 20} type Simple labelfont 1 labelsize 10 align 1 minimum 0 maximum 127 step 1 value 1 textfont 1 + code0 {o->bounds(1,NUM_SYS_EFX);} + code1 {o->value(nsyseff+1);} + } + Fl_Choice sysefftype { + label EffType + callback {pthread_mutex_lock(&master->mutex); +master->sysefx[nsyseff]->changeeffect((int) o->value()); +pthread_mutex_unlock(&master->mutex); +syseffectui->refresh(master->sysefx[nsyseff]);} + xywh {315 125 70 15} down_box BORDER_BOX labelsize 10 + code0 {o->value(master->sysefx[nsyseff]->geteffect());} + } { + MenuItem {} { + label {No Effect} + xywh {10 10 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Reverb + xywh {20 20 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Echo + xywh {30 30 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Chorus + xywh {40 40 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Phaser + xywh {50 50 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label AlienWah + xywh {60 60 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Distortion + xywh {70 70 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label EQ + xywh {80 80 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label DynFilter + xywh {90 90 100 20} labelfont 1 labelsize 10 + } + } + Fl_Group syseffectuigroup { + xywh {5 140 380 95} box FLAT_BOX color 48 + } { + Fl_Group syseffectui { + xywh {5 140 380 95} + code0 {o->init(master->sysefx[nsyseff]);} + class EffUI + } {} + } + Fl_Button {} { + label {Send to...} + callback {syseffsendwindow->show();} + xywh {95 120 75 20} box THIN_UP_BOX labelfont 1 labelsize 11 + } + Fl_Button {} { + label C + callback {presetsui->copy(master->sysefx[nsyseff]);} + xywh {215 124 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 11 labelcolor 7 + } + Fl_Button {} { + label P + callback {pthread_mutex_lock(&master->mutex); +presetsui->paste(master->sysefx[nsyseff],syseffectui); +pthread_mutex_unlock(&master->mutex);} + xywh {245 124 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 11 labelcolor 7 + } + } + Fl_Group {} { + label {Insertion Effects} + xywh {0 100 390 140} box ENGRAVED_FRAME labeltype EMBOSSED_LABEL labelsize 15 align 25 hide + } { + Fl_Counter inseffnocounter { + label {Ins.Effect No.} + callback {ninseff=(int) o->value()-1; +insefftype->value(master->insefx[ninseff]->geteffect()); +inseffpart->value(master->Pinsparts[ninseff]+2); +inseffectui->refresh(master->insefx[ninseff]); + +if (master->Pinsparts[ninseff]!=-1) { + insefftype->activate(); + inseffectui->activate(); + inseffectuigroup->activate(); +} else { + insefftype->deactivate(); + inseffectui->deactivate(); + inseffectuigroup->deactivate(); +};} + xywh {5 120 80 20} type Simple labelfont 1 labelsize 10 align 1 minimum 0 maximum 127 step 1 value 1 textfont 1 + code0 {o->bounds(1,NUM_INS_EFX);} + code1 {o->value(ninseff+1);} + } + Fl_Choice insefftype { + label EffType + callback {pthread_mutex_lock(&master->mutex); +master->insefx[ninseff]->changeeffect((int) o->value()); +pthread_mutex_unlock(&master->mutex); +inseffectui->refresh(master->insefx[ninseff]); +inseffectui->show();} + xywh {315 125 70 15} down_box BORDER_BOX labelsize 10 + code0 {o->value(master->insefx[ninseff]->geteffect());} + code1 {if (master->Pinsparts[ninseff]== -1) o->deactivate();} + } { + MenuItem {} { + label {No Effect} + xywh {25 25 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Reverb + xywh {35 35 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Echo + xywh {45 45 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Chorus + xywh {55 55 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Phaser + xywh {60 60 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label AlienWah + xywh {70 70 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Distortion + xywh {80 80 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label EQ + xywh {90 90 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label DynFilter + xywh {100 100 100 20} labelfont 1 labelsize 10 + } + } + Fl_Group inseffectuigroup { + xywh {5 140 380 95} box FLAT_BOX color 48 + } { + Fl_Group inseffectui { + xywh {5 140 380 95} + code0 {o->init(master->insefx[ninseff]);} + code1 {if (master->Pinsparts[ninseff]== -1) o->deactivate();} + class EffUI + } {} + } + Fl_Choice inseffpart { + label {Insert To.} + callback {master->Pinsparts[ninseff]=(int) o->value()-2; +if ((int) o->value()==1){ + inseffectuigroup->deactivate(); + insefftype->deactivate(); + inseffectui->deactivate(); +} else { + inseffectuigroup->activate(); + insefftype->activate(); + inseffectui->activate(); +}; +master->insefx[ninseff]->cleanup();} open + xywh {95 120 80 20} down_box BORDER_BOX labelfont 1 labelsize 10 align 5 textsize 10 + code0 {o->add("Master Out");o->add("Off");} + code1 {char tmp[50]; for (int i=0;iadd(tmp);};} + code3 {o->value(master->Pinsparts[ninseff]+2);} + } {} + Fl_Button {} { + label C + callback {presetsui->copy(master->insefx[ninseff]);} + xywh {215 124 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 11 labelcolor 7 + } + Fl_Button {} { + label P + callback {pthread_mutex_lock(&master->mutex); +presetsui->paste(master->insefx[ninseff],inseffectui); +pthread_mutex_unlock(&master->mutex);} + xywh {245 124 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 11 labelcolor 7 + } + } + } + Fl_Button {} { + label Scales + callback {microtonalui->show();} + xywh {330 80 56 19} box PLASTIC_UP_BOX color 231 labeltype ENGRAVED_LABEL labelfont 1 + } + Fl_Group {} { + xywh {172 30 117 45} box ENGRAVED_BOX + } { + Fl_Button recordbutton { + label {Rec.} + callback {o->deactivate(); +recordmenu->deactivate(); +recordmenu->label("&Record(*)"); +stopbutton->activate(); +pausebutton->activate(); +pauselabel->activate(); +master->HDDRecorder.start(); +master->vuresetpeaks(); +mastermenu->redraw();} + tooltip {Start Recording} xywh {181 36 21 21} box ROUND_UP_BOX color 88 labelfont 1 labelsize 10 align 2 deactivate + } + Fl_Button stopbutton { + label Stop + callback {o->deactivate(); +master->HDDRecorder.stop(); +recordbutton->deactivate(); +pausebutton->deactivate(); +pauselabel->deactivate(); +recordmenu->activate(); +recordmenu->label("&Record"); +mastermenu->redraw();} + tooltip {Stop Recording and close the audio file} xywh {259 36 21 21} box THIN_UP_BOX color 4 labelfont 1 labelsize 10 align 2 deactivate + } + Fl_Button pausebutton { + label {@||} + callback {o->deactivate(); +master->HDDRecorder.pause(); +recordbutton->activate(); +mastermenu->redraw();} + tooltip {Pause Recording} xywh {220 36 21 21} box THIN_UP_BOX color 4 selection_color 4 labelfont 1 labelcolor 3 align 16 deactivate + } + Fl_Box pauselabel { + label Pause + xywh {214 56 30 15} labelfont 1 labelsize 10 deactivate + } + } + Fl_Group {} { + xywh {1 427 389 33} box ENGRAVED_FRAME + } { + Fl_Box {} { + label {VU-Meter} + xywh {4 430 384 30} box FLAT_BOX color 48 selection_color 75 + code0 {o->init(master,-1);} + class VUMeter + } + } + Fl_Check_Button nrpnbutton { + label NRPN + callback {master->ctl.NRPN.receive=(int) o->value();} + tooltip {Receive NRPNs} xywh {45 65 47 10} down_box DOWN_BOX labelsize 10 + code0 {o->value(master->ctl.NRPN.receive);} + } + Fl_Counter npartcounter { + callback {int nval=(int) o->value()-1; +partuigroup->remove(partui); +delete partui; +partui=new PartUI(0,0,765,525); +partuigroup->add(partui); +partui->init(master->part[nval],master,nval,bankui); +partui->redraw(); +o->redraw(); +npart=nval; + +updatepanel(); +simplenpartcounter->value(nval+1); +simplenpartcounter->do_callback();} + tooltip {The part number} xywh {5 247 70 23} type Simple labelfont 1 minimum 0 maximum 127 step 1 value 1 textfont 1 + code0 {o->bounds(1,NUM_MIDI_PARTS);} + code1 {bankui->init(o);} + } + Fl_Button {} { + label vK + callback {virkeyboard->show();} + tooltip {Virtual Keyboard} xywh {292 80 35 19} box PLASTIC_UP_BOX color 231 labeltype ENGRAVED_LABEL labelfont 1 + } + Fl_Button {} { + label {R.D.} + callback {globalfinedetuneslider->value(64.0); +globalfinedetuneslider->do_callback();} + tooltip {Master fine detune reset} xywh {140 65 30 10} box THIN_UP_BOX labelfont 1 labelsize 10 + } + Fl_Dial globalfinedetuneslider { + label {F.Det.} + callback {master->microtonal.Pglobalfinedetune=(int) o->value();} + tooltip {global fine detune} xywh {143 30 20 20} box ROUND_UP_BOX labelsize 10 align 130 maximum 127 step 1 value 64 + code0 {o->value(master->microtonal.Pglobalfinedetune);} + class WidgetPDial + } + Fl_Button {} { + label {Panel Window} + callback {updatepanel(); +panelwindow->show();} + tooltip {Panel Window} xywh {293 62 92 16} box PLASTIC_UP_BOX color 183 labelfont 1 labelsize 10 + } + } + Fl_Window aboutwindow { + label {Copyright...} + xywh {629 278 330 210} type Double hide + } { + Fl_Box {} { + label {Copyright (c) 2002-2005 Nasca O. Paul and others} + xywh {0 35 330 25} labeltype EMBOSSED_LABEL labelsize 15 align 16 + } + Fl_Box {} { + label {This is free software; you may redistribute it and/or modify it under the terms of the +version 2 (or any later version) of the GNU General Public License as published by the Free Software Fundation. + This program comes with + ABSOLUTELY NO WARRANTY. + See the version 2 (or any later version) of the +GNU General Public License for details.} + xywh {0 60 325 115} labelfont 1 labelsize 11 align 144 + } + Fl_Button {} { + label {Close this window} + callback {aboutwindow->hide();} + xywh {80 180 180 25} box THIN_UP_BOX labelsize 11 + } + Fl_Box {} { + label ZynAddSubFX + xywh {5 5 325 30} labeltype EMBOSSED_LABEL labelfont 1 labelsize 20 align 16 + } + } + Fl_Window syseffsendwindow { + label {System Effects Send} + xywh {171 234 120 250} type Double hide resizable + } { + Fl_Scroll {} {open + xywh {0 45 120 170} box FLAT_BOX resizable + code0 {for (int neff1=0;neff1x()+(neff2-1)*35,o->y()+15+neff1*50,30,30);syseffsend[neff1][neff2]->label("aaa");syseffsend[neff1][neff2]->init(master,neff1,neff2);};} + } {} + Fl_Button {} { + label Close + callback {syseffsendwindow->hide();} + xywh {25 220 80 25} box THIN_UP_BOX + } + Fl_Box {} { + label {Send system effect's output to other system effects} + xywh {5 5 110 35} labelsize 10 align 192 + } + } + Fl_Window panelwindow { + label {ZynAddSubFX Panel} + xywh {89 59 630 635} type Double hide + } { + Fl_Scroll {} {open + xywh {0 5 570 310} type HORIZONTAL box THIN_UP_BOX + } { + Fl_Pack {} {open + xywh {5 10 560 285} type HORIZONTAL + code0 {for (int i=0;iinit(master,i,bankui);}} + } {} + } + Fl_Scroll {} {open + xywh {0 320 570 310} type HORIZONTAL box THIN_UP_BOX + } { + Fl_Pack {} {open + xywh {5 325 560 285} type HORIZONTAL + code0 {for (int i=NUM_MIDI_PARTS/2;iinit(master,i,bankui);}} + } {} + } + Fl_Button {} { + label Close + callback {panelwindow->hide(); +updatepanel();} + xywh {575 605 50 25} box THIN_UP_BOX labelsize 13 + } + Fl_Button {} { + label Refresh + callback {updatepanel();} + xywh {575 570 55 25} box THIN_UP_BOX labelsize 13 + } + } + Fl_Window simplemasterwindow { + label ZynAddSubFX + callback {\#ifdef VSTAUDIOOUT +fl_alert("ZynAddSubFX could not be closed this way, because it's a VST plugin. Please use the host aplication to close it."); +\#else +if (fl_choice("Exit and leave the unsaved data?","No","Yes",NULL)) { + config.save(); + *exitprogram=1; +}; +\#endif} + xywh {400 405 600 335} type Double hide + } { + Fl_Menu_Bar {} { + xywh {0 0 690 25} + } { + Submenu {} { + label {&File} + xywh {10 10 100 20} + } { + MenuItem {} { + label {&New (erase all)...} + callback {do_new_master();} + xywh {30 30 100 20} + } + MenuItem {} { + label {&Open Parameters...} + callback {do_load_master();} + xywh {30 30 100 20} + } + MenuItem {} { + label {&Save All Parameters...} + callback {do_save_master();} + xywh {20 20 100 20} divider + } + MenuItem {} { + label {&Settings...} + callback {configui->show();} + xywh {35 35 100 20} divider + } + MenuItem {} { + label {&Copyright...} + callback {aboutwindow->show();} + xywh {25 25 100 20} divider + } + MenuItem {} { + label {E&xit} + callback {masterwindow->do_callback();} + xywh {20 20 100 20} + } + } + Submenu {} { + label {&Instrument} + xywh {20 20 100 20} + } { + MenuItem {} { + label {&Open Instrument...} + callback {const char *filename; +filename=fl_file_chooser("Load:","({*.xiz})",NULL,0); +if (filename==NULL) return; + + +pthread_mutex_lock(&master->mutex); +// int npart=(int)npartcounter->value()-1; + + //clear all instrument parameters, first + master->part[npart]->defaultsinstrument(); + + //load the instr. parameters + int result=master->part[npart]->loadXMLinstrument(filename); + +pthread_mutex_unlock(&master->mutex); +master->part[npart]->applyparameters(); + +simplenpartcounter->do_callback(); + +if (result==-10) fl_alert("Error: Could not load the file\\nbecause it is not an instrument file."); + else if (result<0) fl_alert("Error: Could not load the file.");} + xywh {40 40 100 20} + } + MenuItem {} { + label {Show Instrument &Bank...} + callback {bankui->show();} + xywh {10 10 100 20} divider + } + } + Submenu {} { + label Misc + xywh {0 0 100 20} + } { + MenuItem {} { + label {Switch User Interface Mode} + callback {if (fl_choice("Switch the User Interface to Advanced mode ?","No","Yes",NULL)){ + simplemasterwindow->hide(); + refresh_master_ui(); + masterwindow->show(); + config.cfg.UserInterfaceMode=1; +};} + xywh {0 0 100 20} + } + } + } + Fl_Group simplelistitemgroup { + private xywh {125 65 215 150} box ENGRAVED_BOX + code0 {if (master->part[npart]->Penabled==0) o->deactivate();} + } { + Fl_Button partname { + callback {if ((int)bankui->cbwig->value()!=(npart+1)){ + bankui->cbwig->value(npart+1); + bankui->cbwig->do_callback(); +}; +bankui->show();} + xywh {130 72 205 18} box PLASTIC_THIN_DOWN_BOX down_box FLAT_BOX color 247 labelfont 1 labelsize 11 align 208 + } + Fl_Slider partpanning { + label Pan + callback {master->part[npart]->setPpanning((int) o->value());} + xywh {185 95 70 15} type {Horz Knob} box FLAT_BOX maximum 127 step 1 value 64 + code0 {o->value(master->part[npart]->Ppanning);} + } + Fl_Choice partrcv { + label {Midi Channel Receive} + callback {virkeys->relaseallkeys(0); +master->part[npart]->Prcvchn=(int) o->value(); +virkeys->midich=(int) o->value();} open + tooltip {receive from Midi channel} xywh {140 157 65 18} down_box BORDER_BOX labelsize 10 align 130 textfont 1 + code0 {char nrstr[10]; for(int i=0;iadd(nrstr); else o->add("Dr10");};} + code1 {o->value(master->part[npart]->Prcvchn);} + } {} + Fl_Dial partvolume { + callback {master->part[npart]->setPvolume((int) o->value());} + xywh {145 95 30 30} maximum 127 step 1 + code0 {o->value(master->part[npart]->Pvolume);} + class WidgetPDial + } + Fl_Box {} { + label Volume + xywh {130 125 60 15} + } + Fl_Check_Button simplepartportamento { + label Portamento + callback {master->part[npart]->ctl.portamento.portamento=(int) o->value();} + tooltip {Enable/Disable the portamento} xywh {260 95 75 20} down_box DOWN_BOX labelfont 1 labelsize 10 + code0 {o->value(master->part[npart]->ctl.portamento.portamento);} + } + Fl_Counter simpleminkcounter { + label {Min.key} + callback {master->part[npart]->Pminkey=(int) o->value(); +if (master->part[npart]->Pminkey>master->part[npart]->Pmaxkey) o->textcolor(FL_RED); + else o->textcolor(FL_BLACK);} + tooltip {Minimum key (that the part receives NoteOn messages)} xywh {210 158 40 15} type Simple labelfont 1 labelsize 10 minimum 0 maximum 127 step 1 textsize 10 + code0 {o->value(master->part[npart]->Pminkey);} + } + Fl_Counter simplemaxkcounter { + label {Max.key} + callback {master->part[npart]->Pmaxkey=(int) o->value(); + +if (master->part[npart]->Pminkey>master->part[npart]->Pmaxkey) o->textcolor(FL_RED); + else o->textcolor(FL_BLACK);} + tooltip {Maximum key (that the part receives NoteOn messages)} xywh {255 158 40 15} type Simple labelfont 1 labelsize 10 minimum 0 maximum 127 step 1 textsize 10 + code0 {o->value(master->part[npart]->Pmaxkey);} + } + Fl_Button {} { + label m + callback {if (master->part[npart]->lastnote>=0) simpleminkcounter->value(master->part[npart]->lastnote); +simpleminkcounter->do_callback(); +simplemaxkcounter->do_callback();} + tooltip {set the minimum key to the last pressed key} xywh {230 188 15 12} box THIN_UP_BOX labelsize 10 + } + Fl_Button {} { + label M + callback {if (master->part[npart]->lastnote>=0) simplemaxkcounter->value(master->part[npart]->lastnote); +simplemaxkcounter->do_callback(); +simpleminkcounter->do_callback();} + tooltip {set the maximum key to the last pressed key} xywh {260 188 15 12} box THIN_UP_BOX labelsize 10 + } + Fl_Button {} { + label R + callback {simpleminkcounter->value(0); +simpleminkcounter->do_callback(); +simplemaxkcounter->value(127); +simplemaxkcounter->do_callback();} + tooltip {reset the minimum key to 0 and maximum key to 127} xywh {245 188 15 12} box THIN_UP_BOX labelfont 1 labelsize 10 + } + Fl_Counter simplepartkeyshiftcounter { + label KeyShift + callback {master->part[npart]->Pkeyshift=(int) o->value()+64;} + xywh {240 120 90 20} labelsize 11 minimum -64 maximum 64 step 1 + code0 {o->lstep(12);} + code1 {o->value(master->part[npart]->Pkeyshift-64);} + } + Fl_Dial simplesyseffsend { + callback {master->setPsysefxvol(npart,nsyseff,(int) o->value());} + xywh {300 160 30 30} maximum 127 step 1 + class WidgetPDial + } + Fl_Box {} { + label Effect + xywh {295 190 40 15} + } + } + Fl_Check_Button partenabled { + label Enabled + callback {pthread_mutex_lock(&master->mutex); + master->partonoff(npart,(int) o->value()); +pthread_mutex_unlock(&master->mutex); + +if ((int) o->value()==0) simplelistitemgroup->deactivate(); + else { + simplelistitemgroup->activate(); + if ((int)bankui->cbwig->value()!=(npart+1)){ + bankui->cbwig->value(npart+1); + bankui->cbwig->do_callback(); + }; +}; + +o->redraw();} + private xywh {250 40 85 20} down_box DOWN_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 13 align 24 + code0 {//char tmp[10];snprintf(tmp,10,"%d",npart+1);o->label(strdup(tmp));} + code1 {o->value(master->part[npart]->Penabled);} + } + Fl_Box virkeys { + label Keyboard + xywh {5 215 590 80} box BORDER_BOX color 17 + code0 {o->init(master);} + class VirKeys + } + Fl_Group {} { + xywh {340 30 255 185} box ENGRAVED_BOX + } { + Fl_Tabs {} { + xywh {345 35 245 175} align 18 + } { + Fl_Group {} { + label {System Effects} + xywh {345 55 245 155} box ENGRAVED_FRAME labelfont 1 labelsize 12 align 18 + } { + Fl_Counter simplesyseffnocounter { + label {Sys.Effect No.} + callback {nsyseff=(int) o->value()-1; +simplesysefftype->value(master->sysefx[nsyseff]->geteffect()); +simplesyseffectui->refresh(master->sysefx[nsyseff]); +simplerefresh();} + xywh {350 75 80 20} type Simple labelfont 1 labelsize 10 align 1 minimum 0 maximum 127 step 1 value 1 textfont 1 + code0 {o->bounds(1,NUM_SYS_EFX);} + code1 {o->value(nsyseff+1);} + } + Fl_Choice simplesysefftype { + label EffType + callback {pthread_mutex_lock(&master->mutex); +master->sysefx[nsyseff]->changeeffect((int) o->value()); +pthread_mutex_unlock(&master->mutex); +simplesyseffectui->refresh(master->sysefx[nsyseff]);} + xywh {515 80 70 15} down_box BORDER_BOX labelsize 10 align 5 + code0 {o->value(master->sysefx[nsyseff]->geteffect());} + } { + MenuItem {} { + label {No Effect} + xywh {20 20 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Reverb + xywh {30 30 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Echo + xywh {40 40 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Chorus + xywh {50 50 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Phaser + xywh {60 60 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label AlienWah + xywh {70 70 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Distortion + xywh {80 80 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label EQ + xywh {90 90 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label DynFilter + xywh {100 100 100 20} labelfont 1 labelsize 10 + } + } + Fl_Group simplesyseffectuigroup { + xywh {350 95 235 95} box FLAT_BOX color 48 + } { + Fl_Group simplesyseffectui { + xywh {350 95 234 95} + code0 {o->init(master->sysefx[nsyseff]);} + class SimpleEffUI + } {} + } + Fl_Button {} { + label {Send to...} + callback {syseffsendwindow->show();} + xywh {435 75 75 20} box THIN_UP_BOX labelfont 1 labelsize 11 + } + Fl_Button {} { + label P + callback {pthread_mutex_lock(&master->mutex); +presetsui->paste(master->sysefx[nsyseff],simplesyseffectui); +pthread_mutex_unlock(&master->mutex);} + xywh {560 65 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 11 labelcolor 7 + } + } + Fl_Group {} { + label {Insertion Effects} + xywh {345 55 245 155} box ENGRAVED_FRAME labelfont 1 labelsize 12 align 18 hide + } { + Fl_Counter simpleinseffnocounter { + label {Ins.Effect No.} + callback {ninseff=(int) o->value()-1; +simpleinsefftype->value(master->insefx[ninseff]->geteffect()); +simpleinseffpart->value(master->Pinsparts[ninseff]+2); +simpleinseffectui->refresh(master->insefx[ninseff]); + +if (master->Pinsparts[ninseff]!=-1) { + simpleinsefftype->activate(); + simpleinseffectui->activate(); + simpleinseffectuigroup->activate(); +} else { + simpleinsefftype->deactivate(); + simpleinseffectui->deactivate(); + simpleinseffectuigroup->deactivate(); +};} + xywh {350 75 80 20} type Simple labelfont 1 labelsize 10 align 1 minimum 0 maximum 127 step 1 value 1 textfont 1 + code0 {o->bounds(1,NUM_INS_EFX);} + code1 {o->value(ninseff+1);} + } + Fl_Choice simpleinsefftype { + label EffType + callback {pthread_mutex_lock(&master->mutex); +master->insefx[ninseff]->changeeffect((int) o->value()); +pthread_mutex_unlock(&master->mutex); +simpleinseffectui->refresh(master->insefx[ninseff]); +simpleinseffectui->show();} + xywh {515 80 70 15} down_box BORDER_BOX labelsize 10 align 5 + code0 {o->value(master->insefx[ninseff]->geteffect());} + code1 {if (master->Pinsparts[ninseff]== -1) o->deactivate();} + } { + MenuItem {} { + label {No Effect} + xywh {35 35 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Reverb + xywh {45 45 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Echo + xywh {55 55 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Chorus + xywh {65 65 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Phaser + xywh {70 70 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label AlienWah + xywh {80 80 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Distortion + xywh {90 90 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label EQ + xywh {100 100 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label DynFilter + xywh {110 110 100 20} labelfont 1 labelsize 10 + } + } + Fl_Group simpleinseffectuigroup { + xywh {350 95 234 95} box FLAT_BOX color 48 + } { + Fl_Group simpleinseffectui { + xywh {350 95 234 95} + code0 {o->init(master->insefx[ninseff]);} + code1 {if (master->Pinsparts[ninseff]== -1) o->deactivate();} + class SimpleEffUI + } {} + } + Fl_Choice simpleinseffpart { + label {Insert To.} + callback {master->Pinsparts[ninseff]=(int) o->value()-2; +if ((int) o->value()==1){ + simpleinseffectuigroup->deactivate(); + simpleinsefftype->deactivate(); + simpleinseffectui->deactivate(); +} else { + simpleinseffectuigroup->activate(); + simpleinsefftype->activate(); + simpleinseffectui->activate(); +}; +master->insefx[ninseff]->cleanup();} open + xywh {435 75 80 20} down_box BORDER_BOX labelfont 1 labelsize 10 align 5 textsize 10 + code0 {o->add("Master Out");o->add("Off");} + code1 {char tmp[50]; for (int i=0;iadd(tmp);};} + code3 {o->value(master->Pinsparts[ninseff]+2);} + } {} + Fl_Button {} { + label P + callback {pthread_mutex_lock(&master->mutex); +presetsui->paste(master->insefx[ninseff],simpleinseffectui); +pthread_mutex_unlock(&master->mutex);} + xywh {560 65 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 11 labelcolor 7 + } + } + } + } + Fl_Group {} { + xywh {5 300 590 30} box ENGRAVED_FRAME + } { + Fl_Box {} { + label {VU-Meter} + xywh {5 300 590 30} box FLAT_BOX color 41 selection_color 75 + code0 {o->init(master,-1);} + class VUMeter + } + } + Fl_Dial simplemastervolumedial { + label {Master Volume} + callback {master->setPvolume((int) o->value());} + tooltip {Master Volume} xywh {10 35 40 40} box ROUND_UP_BOX labelfont 1 labelsize 11 align 130 maximum 127 step 1 + code0 {o->value(master->Pvolume);} + class WidgetPDial + } + Fl_Counter simplemasterkeyshiftcounter { + label {Master KeyShift} + callback {master->setPkeyshift((int) o->value()+64);} + xywh {25 110 90 20} labelsize 11 minimum -64 maximum 64 step 1 + code0 {o->lstep(12);} + code1 {o->value(master->Pkeyshift-64);} + } + Fl_Button {} { + label {Stop ALL sounds!} + callback {virkeyboard->relaseallkeys(); +pthread_mutex_lock(&master->mutex); +master->shutup=1; +pthread_mutex_unlock(&master->mutex);} + xywh {5 149 115 31} box PLASTIC_UP_BOX color 231 labelfont 1 labelsize 11 + } + Fl_Button {} { + label Reset + callback {simpleglobalfinedetuneslider->value(64.0); +simpleglobalfinedetuneslider->do_callback();} + tooltip {Master fine detune reset} xywh {70 32 50 10} box THIN_UP_BOX labelfont 1 labelsize 11 align 128 + } + Fl_Dial simpleglobalfinedetuneslider { + label {Fine Detune} + callback {master->microtonal.Pglobalfinedetune=(int) o->value();} + tooltip {global fine detune} xywh {80 45 30 30} box ROUND_UP_BOX labelsize 11 align 130 maximum 127 step 1 value 64 + code0 {o->value(master->microtonal.Pglobalfinedetune);} + class WidgetPDial + } + Fl_Counter simplenpartcounter { + label Part + callback {virkeys->relaseallkeys(0); +npartcounter->value(o->value()); +npart=(int) o->value()-1; + +simplerefresh(); +virkeys->midich=master->part[npart]->Prcvchn;} + tooltip {The part number} xywh {170 40 70 20} type Simple labelfont 1 align 4 minimum 0 maximum 127 step 1 value 1 textfont 1 + code0 {o->bounds(1,NUM_MIDI_PARTS);} + } + Fl_Counter {} { + label {Keyb.Oct.} + callback {virkeys->relaseallkeys(0); +virkeys->midioct=(int) o->value(); +virkeys->take_focus();} + tooltip {Midi Octave} xywh {5 195 55 20} type Simple labelsize 11 align 8 when 6 minimum 0 maximum 5 step 1 textfont 1 textsize 11 + code0 {o->value(virkeys->midioct);} + } + } + Fl_Window selectuiwindow { + label {User Interface mode} + callback {*exitprogram=1;} + xywh {342 246 430 250} type Double hide non_modal + } { + Fl_Box {} { + label {Welcome to ZynAddSubFX} + xywh {5 5 425 40} labeltype SHADOW_LABEL labelfont 1 labelsize 26 + } + Fl_Box {} { + label {Please choose the interface mode:} + xywh {10 50 265 25} labelfont 1 labelsize 13 + } + Fl_Button {} { + label Advanced + callback {config.cfg.UserInterfaceMode=1; +masterwindow->show(); +selectuiwindow->hide();} + xywh {10 165 100 35} box PLASTIC_UP_BOX color 229 labelfont 1 labelsize 16 + } + Fl_Box {} { + label {.. if you have used ZynAddSubFX before, or you like to have full controll to all parameters.} + xywh {110 165 310 35} labelfont 1 labelsize 11 align 144 + } + Fl_Button {} { + label Beginner + callback {simplemasterwindow->show(); +selectuiwindow->hide(); +config.cfg.UserInterfaceMode=2;} + xywh {10 80 100 65} box PLASTIC_UP_BOX color 238 labelfont 1 labelsize 16 + } + Fl_Box {} { + label {..if you are a beginner, you prefer using presets or you prefer to use simpler user interfaces. Most functionality of ZynAddSubFX will be hidden in this mode to make simple the learning/using it.} + xywh {110 75 320 75} labelfont 1 labelsize 11 align 144 + } + Fl_Box {} { + label {You can switch the interface modes anytime you want.} + xywh {30 215 360 25} box BORDER_BOX color 51 labelfont 1 labelsize 11 align 144 + } + } + } + Function {updatesendwindow()} {} { + code {for (int neff1=0;neff1value(master->Psysefxsend[neff1][neff2]);} {} + } + Function {updatepanel()} {} { + code {for (int npart=0;npartrefresh(); +};} {} + } + Function {setfilelabel(const char *filename)} {open + } { + code {if (filename!=NULL) snprintf(&masterwindowlabel[0],100,"%s - ZynAddSubFX",fl_filename_name(filename)); + else snprintf(&masterwindowlabel[0],100,"%s","ZynAddSubFX (c)2002-2006 Nasca Paul and others"); +masterwindowlabel[99]='\\0'; +masterwindow->label(&masterwindowlabel[0]); +simplemasterwindow->label(&masterwindowlabel[0]);} {selected + } + } + Function {MasterUI(Master *master_,int *exitprogram_)} {} { + code {master=master_; +exitprogram=exitprogram_; +ninseff=0; +nsyseff=0; +npart=0; + +for (int i=0;imicrotonal); +virkeyboard=new VirKeyboard(master); +bankui=new BankUI(master,&npart); +configui=new ConfigUI(); +sequi=new SeqUI(master); + +make_window(); +presetsui=new PresetsUI(); +setfilelabel(NULL); +swapefftype=0; +simplerefresh();} {} + } + Function {~MasterUI()} {} { + code {masterwindow->hide(); +delete (masterwindow); +aboutwindow->hide(); +delete (aboutwindow); +syseffsendwindow->hide(); +delete(syseffsendwindow); + +delete (virkeyboard); +delete (microtonalui); +delete (bankui); +delete (configui); +delete (sequi); + +delete(presetsui);} {} + } + Function {showUI()} {} { + code {switch (config.cfg.UserInterfaceMode){ + case 0:selectuiwindow->show(); + break; + case 1:masterwindow->show(); + break; + case 2:simplemasterwindow->show(); + break; +};} {} + } + Function {simplerefresh()} {} { + code {partenabled->value(master->part[npart]->Penabled); +if (master->part[npart]->Penabled!=0) simplelistitemgroup->activate(); + else simplelistitemgroup->deactivate(); + +partvolume->value(master->part[npart]->Pvolume); +partpanning->value(master->part[npart]->Ppanning); +partrcv->value(master->part[npart]->Prcvchn); + +if (master->part[npart]->Pname[0]!=0) partname->label((char *)master->part[npart]->Pname); + else partname->label("Click here to load a instrument"); + +simplelistitemgroup->redraw(); +simplepartportamento->value(master->part[npart]->ctl.portamento.portamento); +simpleminkcounter->value(master->part[npart]->Pminkey); +simplemaxkcounter->value(master->part[npart]->Pmaxkey); + +simplepartkeyshiftcounter->value(master->part[npart]->Pkeyshift-64); +simplesyseffsend->value(master->Psysefxvol[nsyseff][npart]);} {} + } + Function {do_new_master()} {} { + code {if (fl_choice("Clear *ALL* the parameters ?","No","Yes",NULL)){ + delete microtonalui; + + pthread_mutex_lock(&master->mutex); + master->defaults(); + pthread_mutex_unlock(&master->mutex); + + npartcounter->value(1); + refresh_master_ui(); + +}; + +updatepanel();} {} + } + Function {do_load_master(char* file = NULL)} {} { + code {char *filename; + if (file == NULL) { + filename=fl_file_chooser("Open:","({*.xmz})",NULL,0); + if (filename==NULL) return; + } + else { + filename = file; + } + + +pthread_mutex_lock(&master->mutex); + //clear all parameters + master->defaults(); + + //load the data + int result=master->loadXML(filename); +pthread_mutex_unlock(&master->mutex); +master->applyparameters(); + +npartcounter->value(1); +refresh_master_ui(); +updatepanel(); +if (result>=0) setfilelabel(filename); + + +if (result==-10) fl_alert("Error: Could not load the file\\nbecause it is not a zynaddsubfx parameters file."); + else if (result<0) fl_alert("Error: Could not load the file.");} {} + } + Function {do_save_master(char* file = NULL)} {} { + code {char *filename; + int result=0; + if (file == NULL) { + filename=fl_file_chooser("Save:","({*.xmz})",NULL,0); + if (filename==NULL) return; + filename=fl_filename_setext(filename,".xmz"); + result=fileexists(filename); + if (result) { + result=0; + if (!fl_choice("The file exists. Overwrite it?","No","Yes",NULL)) return; + + } + } + else { + filename = file; + } + + +pthread_mutex_lock(&master->mutex); +result=master->saveXML(filename); +pthread_mutex_unlock(&master->mutex); + +if (result<0) fl_alert("Error: Could not save the file."); + else setfilelabel(filename); + +updatepanel();} {} + } + Function {refresh_master_ui()} {} { + code {ninseff=0; +nsyseff=0; +npart=0; + +//the Master UI +npartcounter->do_callback(); +syseffnocounter->do_callback(); +inseffnocounter->do_callback(); +masterkeyshiftcounter->value(master->Pkeyshift-64); +mastervolumedial->value(master->Pvolume); +globalfinedetuneslider->value(master->microtonal.Pglobalfinedetune); +microtonalui=new MicrotonalUI(&master->microtonal); +nrpnbutton->value(master->ctl.NRPN.receive); +updatesendwindow(); +updatepanel(); + +//the simle MasterUI +simplenpartcounter->value(1); +simplesyseffnocounter->value(1); +simpleinseffnocounter->value(1); +simplenpartcounter->do_callback(); +simplesyseffnocounter->do_callback(); +simpleinseffnocounter->do_callback(); +simplemasterkeyshiftcounter->value(master->Pkeyshift-64); +simplemastervolumedial->value(master->Pvolume); +simpleglobalfinedetuneslider->value(master->microtonal.Pglobalfinedetune); +virkeys->midich=master->part[npart]->Prcvchn; + +simplerefresh(); +bankui->hide();} {} + } + decl {Master *master;} {} + decl {MicrotonalUI *microtonalui;} {} + decl {SeqUI *sequi;} {} + decl {BankUI *bankui;} {} + decl {int ninseff,npart;} {} + decl {int nsyseff;} {} + decl {int *exitprogram;} {} + decl {SysEffSend *syseffsend[NUM_SYS_EFX][NUM_SYS_EFX];} {} + decl {VirKeyboard *virkeyboard;} {} + decl {ConfigUI *configui;} {} + decl {int swapefftype;} {} + decl {char masterwindowlabel[100];} {} + decl {Panellistitem *panellistitem[NUM_MIDI_PARTS];} {} +} diff --git a/plugins/zynaddsubfx/src/UI/MasterUI.h b/plugins/zynaddsubfx/src/UI/MasterUI.h new file mode 100644 index 000000000..2235123c5 --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/MasterUI.h @@ -0,0 +1,448 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0109 + +#ifndef MasterUI_h +#define MasterUI_h +#include +#include +#include +#include +#include "WidgetPDial.h" +#include "ADnoteUI.h" +#include "SUBnoteUI.h" +#include "EffUI.h" +#include "VirKeyboard.h" +#include "ConfigUI.h" +#include "BankUI.h" +#include "PartUI.h" +#include "MicrotonalUI.h" +#include "SeqUI.h" +#include "PresetsUI.h" +#include "../Misc/Master.h" +#include "../Misc/Part.h" +#include "../Misc/Util.h" +#include "../globals.h" + +class VUMeter : public Fl_Box { +public: + VUMeter(int x,int y, int w, int h, const char *label=0); + void init(Master *master_,int part_); + void draw_master(); + void draw_part(); + void draw(); + static void tickdraw(VUMeter *o); + static void tick(void *v); + int handle(int event); +private: + Master *master; + int npart; + float olddbl,olddbr; + float oldrmsdbl,oldrmsdbr; +}; + +class SysEffSend : public WidgetPDial { +public: + SysEffSend(int x,int y, int w, int h, const char *label=0); + void init(Master *master_,int neff1_,int neff2_); + ~SysEffSend(); + int handle(int event); +private: + Master *master; + int neff1; + int neff2; +}; +#include +#include +#include +#include +#include + +class Panellistitem : public Fl_Group { + Fl_Group* make_window(); + Fl_Group *panellistitem; + Fl_Group *panellistitemgroup; +public: + Fl_Button *partname; +private: + void cb_partname_i(Fl_Button*, void*); + static void cb_partname(Fl_Button*, void*); +public: + Fl_Slider *partvolume; +private: + void cb_partvolume_i(Fl_Slider*, void*); + static void cb_partvolume(Fl_Slider*, void*); +public: + WidgetPDial *partpanning; +private: + void cb_partpanning_i(WidgetPDial*, void*); + static void cb_partpanning(WidgetPDial*, void*); + void cb_edit_i(Fl_Button*, void*); + static void cb_edit(Fl_Button*, void*); +public: + Fl_Choice *partrcv; +private: + void cb_partrcv_i(Fl_Choice*, void*); + static void cb_partrcv(Fl_Choice*, void*); + Fl_Check_Button *partenabled; + void cb_partenabled_i(Fl_Check_Button*, void*); + static void cb_partenabled(Fl_Check_Button*, void*); +public: + Panellistitem(int x,int y, int w, int h, const char *label=0); + void init(Master *master_, int npart_,BankUI *bankui_); + void refresh(); + ~Panellistitem(); +private: + int npart; + Master *master; + BankUI *bankui; +}; +#include +#include +#include +#include +#include +#include +#include + +class MasterUI { +public: + Fl_Double_Window* make_window(); + Fl_Double_Window *masterwindow; +private: + void cb_masterwindow_i(Fl_Double_Window*, void*); + static void cb_masterwindow(Fl_Double_Window*, void*); +public: + Fl_Menu_Bar *mastermenu; + static Fl_Menu_Item menu_mastermenu[]; +private: + void cb_New_i(Fl_Menu_*, void*); + static void cb_New(Fl_Menu_*, void*); + void cb_Open_i(Fl_Menu_*, void*); + static void cb_Open(Fl_Menu_*, void*); + void cb_Save_i(Fl_Menu_*, void*); + static void cb_Save(Fl_Menu_*, void*); + void cb_Load_i(Fl_Menu_*, void*); + static void cb_Load(Fl_Menu_*, void*); + void cb_Save1_i(Fl_Menu_*, void*); + static void cb_Save1(Fl_Menu_*, void*); + void cb_Show_i(Fl_Menu_*, void*); + static void cb_Show(Fl_Menu_*, void*); + void cb_Settings_i(Fl_Menu_*, void*); + static void cb_Settings(Fl_Menu_*, void*); + void cb_Copyright_i(Fl_Menu_*, void*); + static void cb_Copyright(Fl_Menu_*, void*); + void cb_E_i(Fl_Menu_*, void*); + static void cb_E(Fl_Menu_*, void*); + void cb_Clear_i(Fl_Menu_*, void*); + static void cb_Clear(Fl_Menu_*, void*); + void cb_Open1_i(Fl_Menu_*, void*); + static void cb_Open1(Fl_Menu_*, void*); + void cb_Save2_i(Fl_Menu_*, void*); + static void cb_Save2(Fl_Menu_*, void*); + void cb_Show1_i(Fl_Menu_*, void*); + static void cb_Show1(Fl_Menu_*, void*); + void cb_Virtual_i(Fl_Menu_*, void*); + static void cb_Virtual(Fl_Menu_*, void*); +public: + static Fl_Menu_Item *recordmenu; +private: + void cb_Choose_i(Fl_Menu_*, void*); + static void cb_Choose(Fl_Menu_*, void*); + void cb_Show2_i(Fl_Menu_*, void*); + static void cb_Show2(Fl_Menu_*, void*); + void cb_Switch_i(Fl_Menu_*, void*); + static void cb_Switch(Fl_Menu_*, void*); +public: + WidgetPDial *mastervolumedial; +private: + void cb_mastervolumedial_i(WidgetPDial*, void*); + static void cb_mastervolumedial(WidgetPDial*, void*); +public: + Fl_Counter *masterkeyshiftcounter; +private: + void cb_masterkeyshiftcounter_i(Fl_Counter*, void*); + static void cb_masterkeyshiftcounter(Fl_Counter*, void*); + void cb_Panic_i(Fl_Button*, void*); + static void cb_Panic(Fl_Button*, void*); +public: + Fl_Group *partuigroup; + PartUI *partui; + Fl_Counter *syseffnocounter; +private: + void cb_syseffnocounter_i(Fl_Counter*, void*); + static void cb_syseffnocounter(Fl_Counter*, void*); +public: + Fl_Choice *sysefftype; +private: + void cb_sysefftype_i(Fl_Choice*, void*); + static void cb_sysefftype(Fl_Choice*, void*); + static Fl_Menu_Item menu_sysefftype[]; +public: + Fl_Group *syseffectuigroup; + EffUI *syseffectui; +private: + void cb_Send_i(Fl_Button*, void*); + static void cb_Send(Fl_Button*, void*); + void cb_C_i(Fl_Button*, void*); + static void cb_C(Fl_Button*, void*); + void cb_P_i(Fl_Button*, void*); + static void cb_P(Fl_Button*, void*); +public: + Fl_Counter *inseffnocounter; +private: + void cb_inseffnocounter_i(Fl_Counter*, void*); + static void cb_inseffnocounter(Fl_Counter*, void*); +public: + Fl_Choice *insefftype; +private: + void cb_insefftype_i(Fl_Choice*, void*); + static void cb_insefftype(Fl_Choice*, void*); + static Fl_Menu_Item menu_insefftype[]; +public: + Fl_Group *inseffectuigroup; + EffUI *inseffectui; + Fl_Choice *inseffpart; +private: + void cb_inseffpart_i(Fl_Choice*, void*); + static void cb_inseffpart(Fl_Choice*, void*); + void cb_C1_i(Fl_Button*, void*); + static void cb_C1(Fl_Button*, void*); + void cb_P1_i(Fl_Button*, void*); + static void cb_P1(Fl_Button*, void*); + void cb_Scales_i(Fl_Button*, void*); + static void cb_Scales(Fl_Button*, void*); +public: + Fl_Button *recordbutton; +private: + void cb_recordbutton_i(Fl_Button*, void*); + static void cb_recordbutton(Fl_Button*, void*); +public: + Fl_Button *stopbutton; +private: + void cb_stopbutton_i(Fl_Button*, void*); + static void cb_stopbutton(Fl_Button*, void*); +public: + Fl_Button *pausebutton; +private: + void cb_pausebutton_i(Fl_Button*, void*); + static void cb_pausebutton(Fl_Button*, void*); +public: + Fl_Box *pauselabel; + Fl_Check_Button *nrpnbutton; +private: + void cb_nrpnbutton_i(Fl_Check_Button*, void*); + static void cb_nrpnbutton(Fl_Check_Button*, void*); +public: + Fl_Counter *npartcounter; +private: + void cb_npartcounter_i(Fl_Counter*, void*); + static void cb_npartcounter(Fl_Counter*, void*); + void cb_vK_i(Fl_Button*, void*); + static void cb_vK(Fl_Button*, void*); + void cb_R_i(Fl_Button*, void*); + static void cb_R(Fl_Button*, void*); +public: + WidgetPDial *globalfinedetuneslider; +private: + void cb_globalfinedetuneslider_i(WidgetPDial*, void*); + static void cb_globalfinedetuneslider(WidgetPDial*, void*); + void cb_Panel_i(Fl_Button*, void*); + static void cb_Panel(Fl_Button*, void*); +public: + Fl_Double_Window *aboutwindow; +private: + void cb_Close_i(Fl_Button*, void*); + static void cb_Close(Fl_Button*, void*); +public: + Fl_Double_Window *syseffsendwindow; +private: + void cb_Close1_i(Fl_Button*, void*); + static void cb_Close1(Fl_Button*, void*); +public: + Fl_Double_Window *panelwindow; +private: + void cb_Close2_i(Fl_Button*, void*); + static void cb_Close2(Fl_Button*, void*); + void cb_Refresh_i(Fl_Button*, void*); + static void cb_Refresh(Fl_Button*, void*); +public: + Fl_Double_Window *simplemasterwindow; +private: + void cb_simplemasterwindow_i(Fl_Double_Window*, void*); + static void cb_simplemasterwindow(Fl_Double_Window*, void*); + static Fl_Menu_Item menu_[]; + void cb_New1_i(Fl_Menu_*, void*); + static void cb_New1(Fl_Menu_*, void*); + void cb_Open2_i(Fl_Menu_*, void*); + static void cb_Open2(Fl_Menu_*, void*); + void cb_Save3_i(Fl_Menu_*, void*); + static void cb_Save3(Fl_Menu_*, void*); + void cb_Settings1_i(Fl_Menu_*, void*); + static void cb_Settings1(Fl_Menu_*, void*); + void cb_Copyright1_i(Fl_Menu_*, void*); + static void cb_Copyright1(Fl_Menu_*, void*); + void cb_E1_i(Fl_Menu_*, void*); + static void cb_E1(Fl_Menu_*, void*); + void cb_Open3_i(Fl_Menu_*, void*); + static void cb_Open3(Fl_Menu_*, void*); + void cb_Show3_i(Fl_Menu_*, void*); + static void cb_Show3(Fl_Menu_*, void*); + void cb_Switch1_i(Fl_Menu_*, void*); + static void cb_Switch1(Fl_Menu_*, void*); + Fl_Group *simplelistitemgroup; +public: + Fl_Button *partname; +private: + void cb_partname1_i(Fl_Button*, void*); + static void cb_partname1(Fl_Button*, void*); +public: + Fl_Slider *partpanning; +private: + void cb_partpanning1_i(Fl_Slider*, void*); + static void cb_partpanning1(Fl_Slider*, void*); +public: + Fl_Choice *partrcv; +private: + void cb_partrcv1_i(Fl_Choice*, void*); + static void cb_partrcv1(Fl_Choice*, void*); +public: + WidgetPDial *partvolume; +private: + void cb_partvolume1_i(WidgetPDial*, void*); + static void cb_partvolume1(WidgetPDial*, void*); +public: + Fl_Check_Button *simplepartportamento; +private: + void cb_simplepartportamento_i(Fl_Check_Button*, void*); + static void cb_simplepartportamento(Fl_Check_Button*, void*); +public: + Fl_Counter *simpleminkcounter; +private: + void cb_simpleminkcounter_i(Fl_Counter*, void*); + static void cb_simpleminkcounter(Fl_Counter*, void*); +public: + Fl_Counter *simplemaxkcounter; +private: + void cb_simplemaxkcounter_i(Fl_Counter*, void*); + static void cb_simplemaxkcounter(Fl_Counter*, void*); + void cb_m_i(Fl_Button*, void*); + static void cb_m(Fl_Button*, void*); + void cb_M_i(Fl_Button*, void*); + static void cb_M(Fl_Button*, void*); + void cb_R1_i(Fl_Button*, void*); + static void cb_R1(Fl_Button*, void*); +public: + Fl_Counter *simplepartkeyshiftcounter; +private: + void cb_simplepartkeyshiftcounter_i(Fl_Counter*, void*); + static void cb_simplepartkeyshiftcounter(Fl_Counter*, void*); +public: + WidgetPDial *simplesyseffsend; +private: + void cb_simplesyseffsend_i(WidgetPDial*, void*); + static void cb_simplesyseffsend(WidgetPDial*, void*); + Fl_Check_Button *partenabled; + void cb_partenabled1_i(Fl_Check_Button*, void*); + static void cb_partenabled1(Fl_Check_Button*, void*); +public: + VirKeys *virkeys; + Fl_Counter *simplesyseffnocounter; +private: + void cb_simplesyseffnocounter_i(Fl_Counter*, void*); + static void cb_simplesyseffnocounter(Fl_Counter*, void*); +public: + Fl_Choice *simplesysefftype; +private: + void cb_simplesysefftype_i(Fl_Choice*, void*); + static void cb_simplesysefftype(Fl_Choice*, void*); + static Fl_Menu_Item menu_simplesysefftype[]; +public: + Fl_Group *simplesyseffectuigroup; + SimpleEffUI *simplesyseffectui; +private: + void cb_Send1_i(Fl_Button*, void*); + static void cb_Send1(Fl_Button*, void*); + void cb_P2_i(Fl_Button*, void*); + static void cb_P2(Fl_Button*, void*); +public: + Fl_Counter *simpleinseffnocounter; +private: + void cb_simpleinseffnocounter_i(Fl_Counter*, void*); + static void cb_simpleinseffnocounter(Fl_Counter*, void*); +public: + Fl_Choice *simpleinsefftype; +private: + void cb_simpleinsefftype_i(Fl_Choice*, void*); + static void cb_simpleinsefftype(Fl_Choice*, void*); + static Fl_Menu_Item menu_simpleinsefftype[]; +public: + Fl_Group *simpleinseffectuigroup; + SimpleEffUI *simpleinseffectui; + Fl_Choice *simpleinseffpart; +private: + void cb_simpleinseffpart_i(Fl_Choice*, void*); + static void cb_simpleinseffpart(Fl_Choice*, void*); + void cb_P3_i(Fl_Button*, void*); + static void cb_P3(Fl_Button*, void*); +public: + WidgetPDial *simplemastervolumedial; +private: + void cb_simplemastervolumedial_i(WidgetPDial*, void*); + static void cb_simplemastervolumedial(WidgetPDial*, void*); +public: + Fl_Counter *simplemasterkeyshiftcounter; +private: + void cb_simplemasterkeyshiftcounter_i(Fl_Counter*, void*); + static void cb_simplemasterkeyshiftcounter(Fl_Counter*, void*); + void cb_Stop_i(Fl_Button*, void*); + static void cb_Stop(Fl_Button*, void*); + void cb_Reset_i(Fl_Button*, void*); + static void cb_Reset(Fl_Button*, void*); +public: + WidgetPDial *simpleglobalfinedetuneslider; +private: + void cb_simpleglobalfinedetuneslider_i(WidgetPDial*, void*); + static void cb_simpleglobalfinedetuneslider(WidgetPDial*, void*); +public: + Fl_Counter *simplenpartcounter; +private: + void cb_simplenpartcounter_i(Fl_Counter*, void*); + static void cb_simplenpartcounter(Fl_Counter*, void*); + void cb_Keyb_i(Fl_Counter*, void*); + static void cb_Keyb(Fl_Counter*, void*); +public: + Fl_Double_Window *selectuiwindow; +private: + void cb_selectuiwindow_i(Fl_Double_Window*, void*); + static void cb_selectuiwindow(Fl_Double_Window*, void*); + void cb_Advanced_i(Fl_Button*, void*); + static void cb_Advanced(Fl_Button*, void*); + void cb_Beginner_i(Fl_Button*, void*); + static void cb_Beginner(Fl_Button*, void*); +public: + void updatesendwindow(); + void updatepanel(); + void setfilelabel(const char *filename); + MasterUI(Master *master_,int *exitprogram_); + ~MasterUI(); + void showUI(); + void simplerefresh(); + void do_new_master(); + void do_load_master(char* file = NULL); + void do_save_master(char* file = NULL); + void refresh_master_ui(); +private: + Master *master; + MicrotonalUI *microtonalui; + SeqUI *sequi; + BankUI *bankui; + int ninseff,npart; + int nsyseff; + int *exitprogram; + SysEffSend *syseffsend[NUM_SYS_EFX][NUM_SYS_EFX]; + VirKeyboard *virkeyboard; + ConfigUI *configui; + int swapefftype; + char masterwindowlabel[100]; + Panellistitem *panellistitem[NUM_MIDI_PARTS]; +}; +#endif diff --git a/plugins/zynaddsubfx/src/UI/MicrotonalUI.cc b/plugins/zynaddsubfx/src/UI/MicrotonalUI.cc new file mode 100644 index 000000000..aa233bced --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/MicrotonalUI.cc @@ -0,0 +1,463 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0109 + +#include "MicrotonalUI.h" +//Copyright (c) 2002-2005 Nasca Octavian Paul +//License: GNU GPL version 2 or later + +void MicrotonalUI::cb_Invert_i(Fl_Check_Button* o, void*) { + microtonal->Pinvertupdown=(int) o->value(); +if (microtonal->Pinvertupdown==0) centerinvertcounter->deactivate(); + else centerinvertcounter->activate(); +} +void MicrotonalUI::cb_Invert(Fl_Check_Button* o, void* v) { + ((MicrotonalUI*)(o->parent()->parent()->user_data()))->cb_Invert_i(o,v); +} + +void MicrotonalUI::cb_centerinvertcounter_i(Fl_Counter* o, void*) { + microtonal->Pinvertupdowncenter=(int) o->value(); +} +void MicrotonalUI::cb_centerinvertcounter(Fl_Counter* o, void* v) { + ((MicrotonalUI*)(o->parent()->parent()->user_data()))->cb_centerinvertcounter_i(o,v); +} + +void MicrotonalUI::cb_applybutton_i(Fl_Button*, void*) { + apply(); +} +void MicrotonalUI::cb_applybutton(Fl_Button* o, void* v) { + ((MicrotonalUI*)(o->parent()->parent()->user_data()))->cb_applybutton_i(o,v); +} + +void MicrotonalUI::cb_octavesizeoutput_i(Fl_Value_Output* o, void*) { + o->value(microtonal->getoctavesize()); +} +void MicrotonalUI::cb_octavesizeoutput(Fl_Value_Output* o, void* v) { + ((MicrotonalUI*)(o->parent()->parent()->user_data()))->cb_octavesizeoutput_i(o,v); +} + +void MicrotonalUI::cb_nameinput_i(Fl_Input* o, void*) { + snprintf((char *)microtonal->Pname,MICROTONAL_MAX_NAME_LEN,"%s",o->value()); +} +void MicrotonalUI::cb_nameinput(Fl_Input* o, void* v) { + ((MicrotonalUI*)(o->parent()->parent()->user_data()))->cb_nameinput_i(o,v); +} + +void MicrotonalUI::cb_commentinput_i(Fl_Input* o, void*) { + snprintf((char *)microtonal->Pcomment,MICROTONAL_MAX_NAME_LEN,"%s",o->value()); +} +void MicrotonalUI::cb_commentinput(Fl_Input* o, void* v) { + ((MicrotonalUI*)(o->parent()->parent()->user_data()))->cb_commentinput_i(o,v); +} + +void MicrotonalUI::cb_Shift_i(Fl_Counter* o, void*) { + microtonal->Pscaleshift=(int) o->value()+64; +} +void MicrotonalUI::cb_Shift(Fl_Counter* o, void* v) { + ((MicrotonalUI*)(o->parent()->parent()->user_data()))->cb_Shift_i(o,v); +} + +void MicrotonalUI::cb_Import_i(Fl_Button*, void*) { + const char *filename; +filename=fl_file_chooser("Open:","(*.scl)",NULL,0); +if (filename==NULL) return; +int result=microtonal->loadscl(filename); +if (result==0) { + updateTuningsInput(); + nameinput->cut(0,nameinput->maximum_size()); + nameinput->insert((char *)microtonal->Pname); + nameinput->position(0); + commentinput->cut(0,commentinput->maximum_size()); + commentinput->insert((char *)microtonal->Pname); + commentinput->position(0); + tuningsinput->position(0); + octavesizeoutput->do_callback(); + } else { + fl_alert("Error: Could not load the file."); + }; +} +void MicrotonalUI::cb_Import(Fl_Button* o, void* v) { + ((MicrotonalUI*)(o->parent()->parent()->user_data()))->cb_Import_i(o,v); +} + +void MicrotonalUI::cb_firstnotecounter_i(Fl_Counter* o, void*) { + microtonal->Pfirstkey=(int) o->value(); +} +void MicrotonalUI::cb_firstnotecounter(Fl_Counter* o, void* v) { + ((MicrotonalUI*)(o->parent()->parent()->parent()->user_data()))->cb_firstnotecounter_i(o,v); +} + +void MicrotonalUI::cb_lastnotecounter_i(Fl_Counter* o, void*) { + microtonal->Plastkey=(int) o->value(); +} +void MicrotonalUI::cb_lastnotecounter(Fl_Counter* o, void* v) { + ((MicrotonalUI*)(o->parent()->parent()->parent()->user_data()))->cb_lastnotecounter_i(o,v); +} + +void MicrotonalUI::cb_middlenotecounter_i(Fl_Counter* o, void*) { + microtonal->Pmiddlenote=(int) o->value(); +} +void MicrotonalUI::cb_middlenotecounter(Fl_Counter* o, void* v) { + ((MicrotonalUI*)(o->parent()->parent()->parent()->user_data()))->cb_middlenotecounter_i(o,v); +} + +void MicrotonalUI::cb_mapsizeoutput_i(Fl_Value_Output* o, void*) { + o->value(microtonal->Pmapsize); +} +void MicrotonalUI::cb_mapsizeoutput(Fl_Value_Output* o, void* v) { + ((MicrotonalUI*)(o->parent()->parent()->parent()->user_data()))->cb_mapsizeoutput_i(o,v); +} + +void MicrotonalUI::cb_mappingenabledbutton_i(Fl_Check_Button* o, void*) { + int x=(int) o->value(); +microtonal->Pmappingenabled=x; +if (x==0) keymappinggroup->deactivate(); + else keymappinggroup->activate(); +o->show(); +} +void MicrotonalUI::cb_mappingenabledbutton(Fl_Check_Button* o, void* v) { + ((MicrotonalUI*)(o->parent()->parent()->user_data()))->cb_mappingenabledbutton_i(o,v); +} + +void MicrotonalUI::cb_Import1_i(Fl_Button*, void*) { + const char *filename; +filename=fl_file_chooser("Open:","(*.kbm)",NULL,0); +if (filename==NULL) return; +int result=microtonal->loadkbm(filename); +if (result==0) { + updateMappingInput(); + mappinginput->position(0); + mapsizeoutput->do_callback(); + firstnotecounter->value(microtonal->Pfirstkey); + lastnotecounter->value(microtonal->Plastkey); + middlenotecounter->value(microtonal->Pmiddlenote); + mapsizeoutput->do_callback(); + mappingenabledbutton->value(microtonal->Pmappingenabled); + mappingenabledbutton->do_callback(); + afreqinput->value(microtonal->PAfreq); + anotecounter->value(microtonal->PAnote); + anotecounter->do_callback(); + } else { + fl_alert("Error: Could not load the file."); + }; +} +void MicrotonalUI::cb_Import1(Fl_Button* o, void* v) { + ((MicrotonalUI*)(o->parent()->parent()->user_data()))->cb_Import1_i(o,v); +} + +void MicrotonalUI::cb_anotecounter_i(Fl_Counter* o, void*) { + microtonal->PAnote=(int) o->value(); +if (microtonal->getnotefreq(microtonal->PAnote,0)<0.0) o->textcolor(FL_RED); + else o->textcolor(FL_BLACK); + +o->redraw(); +} +void MicrotonalUI::cb_anotecounter(Fl_Counter* o, void* v) { + ((MicrotonalUI*)(o->parent()->parent()->user_data()))->cb_anotecounter_i(o,v); +} + +void MicrotonalUI::cb_afreqinput_i(Fl_Value_Input* o, void*) { + microtonal->PAfreq=o->value(); +} +void MicrotonalUI::cb_afreqinput(Fl_Value_Input* o, void* v) { + ((MicrotonalUI*)(o->parent()->parent()->user_data()))->cb_afreqinput_i(o,v); +} + +void MicrotonalUI::cb_Close_i(Fl_Button*, void*) { + microtonaluiwindow->hide(); +} +void MicrotonalUI::cb_Close(Fl_Button* o, void* v) { + ((MicrotonalUI*)(o->parent()->user_data()))->cb_Close_i(o,v); +} + +void MicrotonalUI::cb_Enable_i(Fl_Check_Button* o, void*) { + microtonal->Penabled=(int) o->value(); +if (microtonal->Penabled==0) microtonalgroup->deactivate(); + else microtonalgroup->activate(); +} +void MicrotonalUI::cb_Enable(Fl_Check_Button* o, void* v) { + ((MicrotonalUI*)(o->parent()->user_data()))->cb_Enable_i(o,v); +} + +Fl_Double_Window* MicrotonalUI::make_window() { + { microtonaluiwindow = new Fl_Double_Window(405, 450, "Scales"); + microtonaluiwindow->user_data((void*)(this)); + { Fl_Group* o = new Fl_Group(249, 2, 155, 45); + o->tooltip("Center where the note\'s freqs. are turned upside-down"); + o->box(FL_ENGRAVED_FRAME); + { Fl_Check_Button* o = new Fl_Check_Button(254, 13, 55, 30, "Invert keys"); + o->tooltip("Turn upside-down the note frequencies"); + o->down_box(FL_DOWN_BOX); + o->labelfont(1); + o->labelsize(11); + o->callback((Fl_Callback*)cb_Invert); + o->align(132|FL_ALIGN_INSIDE); + o->value(microtonal->Pinvertupdown); + } // Fl_Check_Button* o + { Fl_Counter* o = centerinvertcounter = new Fl_Counter(319, 13, 80, 20, "Center"); + centerinvertcounter->labelfont(1); + centerinvertcounter->labelsize(11); + centerinvertcounter->minimum(0); + centerinvertcounter->maximum(127); + centerinvertcounter->step(1); + centerinvertcounter->textfont(1); + centerinvertcounter->callback((Fl_Callback*)cb_centerinvertcounter); + centerinvertcounter->align(130); + o->lstep(microtonal->getoctavesize()); + o->value(microtonal->Pinvertupdowncenter); + if (microtonal->Pinvertupdown==0) o->deactivate(); + } // Fl_Counter* centerinvertcounter + o->end(); + } // Fl_Group* o + { Fl_Group* o = microtonalgroup = new Fl_Group(3, 49, 402, 398); + microtonalgroup->box(FL_ENGRAVED_FRAME); + { applybutton = new Fl_Button(8, 413, 107, 28, "Retune"); + applybutton->tooltip("Retune the synth accorging to the inputs from \"Tunnings\" and \"Keyboard Map\ +pings\""); + applybutton->box(FL_THIN_UP_BOX); + applybutton->labeltype(FL_EMBOSSED_LABEL); + applybutton->labelfont(1); + applybutton->labelsize(13); + applybutton->callback((Fl_Callback*)cb_applybutton); + } // Fl_Button* applybutton + { Fl_Value_Output* o = octavesizeoutput = new Fl_Value_Output(150, 423, 35, 17, "nts./oct."); + octavesizeoutput->tooltip("Notes/Octave"); + octavesizeoutput->labelsize(10); + octavesizeoutput->maximum(500); + octavesizeoutput->step(1); + octavesizeoutput->value(12); + octavesizeoutput->textfont(1); + octavesizeoutput->callback((Fl_Callback*)cb_octavesizeoutput); + octavesizeoutput->align(FL_ALIGN_TOP_LEFT); + o->value(microtonal->getoctavesize()); + } // Fl_Value_Output* octavesizeoutput + { Fl_Input* o = nameinput = new Fl_Input(8, 64, 285, 25, "Name:"); + nameinput->labelfont(1); + nameinput->labelsize(11); + nameinput->callback((Fl_Callback*)cb_nameinput); + nameinput->align(FL_ALIGN_TOP_LEFT); + o->insert((char *)microtonal->Pname); + } // Fl_Input* nameinput + { tuningsinput = new Fl_Input(8, 144, 182, 264, "Tunings:"); + tuningsinput->type(4); + tuningsinput->labelfont(1); + tuningsinput->labelsize(11); + tuningsinput->align(FL_ALIGN_TOP_LEFT); + tuningsinput->when(FL_WHEN_NEVER); + updateTuningsInput(); + } // Fl_Input* tuningsinput + { Fl_Input* o = commentinput = new Fl_Input(8, 104, 391, 25, "Comment:"); + commentinput->labelfont(1); + commentinput->labelsize(11); + commentinput->callback((Fl_Callback*)cb_commentinput); + commentinput->align(FL_ALIGN_TOP_LEFT); + o->insert((char *)microtonal->Pcomment); + } // Fl_Input* commentinput + { Fl_Counter* o = new Fl_Counter(313, 69, 70, 20, "Shift"); + o->type(1); + o->labelsize(11); + o->minimum(-63); + o->maximum(64); + o->step(1); + o->textfont(1); + o->callback((Fl_Callback*)cb_Shift); + o->align(FL_ALIGN_TOP); + o->value(microtonal->Pscaleshift-64); + } // Fl_Counter* o + { Fl_Button* o = new Fl_Button(243, 411, 84, 15, "Import .SCL file"); + o->tooltip("Inport Scala .scl file (tunnings)"); + o->box(FL_THIN_UP_BOX); + o->labelfont(1); + o->labelsize(10); + o->callback((Fl_Callback*)cb_Import); + } // Fl_Button* o + { keymappinggroup = new Fl_Group(193, 144, 206, 264, "Keyboard Mapping"); + keymappinggroup->box(FL_ENGRAVED_BOX); + keymappinggroup->labelfont(1); + keymappinggroup->labelsize(11); + { mappinginput = new Fl_Input(250, 147, 146, 258); + mappinginput->type(4); + mappinginput->labelfont(1); + mappinginput->labelsize(11); + mappinginput->align(FL_ALIGN_TOP_LEFT); + mappinginput->when(FL_WHEN_NEVER); + updateMappingInput(); + } // Fl_Input* mappinginput + { Fl_Counter* o = firstnotecounter = new Fl_Counter(199, 195, 42, 18, "First note"); + firstnotecounter->tooltip("First MIDI note number"); + firstnotecounter->type(1); + firstnotecounter->labelsize(10); + firstnotecounter->minimum(0); + firstnotecounter->maximum(127); + firstnotecounter->step(1); + firstnotecounter->textfont(1); + firstnotecounter->textsize(11); + firstnotecounter->callback((Fl_Callback*)cb_firstnotecounter); + firstnotecounter->align(FL_ALIGN_TOP_LEFT); + o->value(microtonal->Pfirstkey); + } // Fl_Counter* firstnotecounter + { Fl_Counter* o = lastnotecounter = new Fl_Counter(199, 225, 42, 18, "Last note"); + lastnotecounter->tooltip("Last MIDI note number"); + lastnotecounter->type(1); + lastnotecounter->labelsize(10); + lastnotecounter->minimum(0); + lastnotecounter->maximum(127); + lastnotecounter->step(1); + lastnotecounter->value(127); + lastnotecounter->textfont(1); + lastnotecounter->textsize(11); + lastnotecounter->callback((Fl_Callback*)cb_lastnotecounter); + lastnotecounter->align(FL_ALIGN_TOP_LEFT); + o->value(microtonal->Plastkey); + } // Fl_Counter* lastnotecounter + { Fl_Counter* o = middlenotecounter = new Fl_Counter(199, 267, 42, 18, "Midle note"); + middlenotecounter->tooltip("Midle note (where scale degree 0 is mapped to)"); + middlenotecounter->type(1); + middlenotecounter->labelsize(10); + middlenotecounter->minimum(0); + middlenotecounter->maximum(127); + middlenotecounter->step(1); + middlenotecounter->value(60); + middlenotecounter->textfont(1); + middlenotecounter->textsize(11); + middlenotecounter->callback((Fl_Callback*)cb_middlenotecounter); + middlenotecounter->align(FL_ALIGN_TOP_LEFT); + o->value(microtonal->Pmiddlenote); + } // Fl_Counter* middlenotecounter + { Fl_Value_Output* o = mapsizeoutput = new Fl_Value_Output(201, 382, 44, 20, "Map Size"); + mapsizeoutput->labelsize(10); + mapsizeoutput->maximum(500); + mapsizeoutput->step(1); + mapsizeoutput->value(12); + mapsizeoutput->textfont(1); + mapsizeoutput->callback((Fl_Callback*)cb_mapsizeoutput); + mapsizeoutput->align(FL_ALIGN_TOP_LEFT); + o->value(microtonal->Pmapsize); + } // Fl_Value_Output* mapsizeoutput + keymappinggroup->end(); + } // Fl_Group* keymappinggroup + { Fl_Check_Button* o = mappingenabledbutton = new Fl_Check_Button(198, 150, 48, 21, "ON"); + mappingenabledbutton->tooltip("Enable the Mapping (otherwise the mapping is linear)"); + mappingenabledbutton->box(FL_FLAT_BOX); + mappingenabledbutton->down_box(FL_DOWN_BOX); + mappingenabledbutton->labelfont(1); + mappingenabledbutton->callback((Fl_Callback*)cb_mappingenabledbutton); + o->value(microtonal->Pmappingenabled); + if (microtonal->Pmappingenabled==0) keymappinggroup->deactivate(); + } // Fl_Check_Button* mappingenabledbutton + { Fl_Button* o = new Fl_Button(243, 428, 84, 16, "Import .kbm file"); + o->tooltip("Inport Scala .kbm file (keyboard mapping)"); + o->box(FL_THIN_UP_BOX); + o->labelfont(1); + o->labelsize(10); + o->callback((Fl_Callback*)cb_Import1); + } // Fl_Button* o + if (microtonal->Penabled==0) o->deactivate(); + microtonalgroup->end(); + } // Fl_Group* microtonalgroup + { Fl_Group* o = new Fl_Group(108, 2, 140, 45); + o->box(FL_ENGRAVED_FRAME); + { Fl_Counter* o = anotecounter = new Fl_Counter(173, 17, 65, 20, "\"A\" Note"); + anotecounter->tooltip("The \"A\" note (the reference note for which freq. (\"A\" freq) is given)"); + anotecounter->labelfont(1); + anotecounter->labelsize(10); + anotecounter->minimum(0); + anotecounter->maximum(127); + anotecounter->step(1); + anotecounter->value(69); + anotecounter->textfont(1); + anotecounter->textsize(10); + anotecounter->callback((Fl_Callback*)cb_anotecounter); + anotecounter->align(129); + o->lstep(12); + o->value(microtonal->PAnote); + } // Fl_Counter* anotecounter + { Fl_Value_Input* o = afreqinput = new Fl_Value_Input(118, 17, 45, 20, "\"A\" Freq."); + afreqinput->tooltip("The freq. of \"A\" note (default=440.0)"); + afreqinput->labelfont(1); + afreqinput->labelsize(10); + afreqinput->minimum(1); + afreqinput->maximum(20000); + afreqinput->step(0.001); + afreqinput->value(440); + afreqinput->textfont(1); + afreqinput->textsize(10); + afreqinput->callback((Fl_Callback*)cb_afreqinput); + afreqinput->align(FL_ALIGN_TOP); + o->value(microtonal->PAfreq); + } // Fl_Value_Input* afreqinput + o->end(); + } // Fl_Group* o + { Fl_Button* o = new Fl_Button(333, 413, 67, 28, "Close"); + o->box(FL_THIN_UP_BOX); + o->callback((Fl_Callback*)cb_Close); + } // Fl_Button* o + { Fl_Check_Button* o = new Fl_Check_Button(3, 3, 102, 45, "Enable Microtonal"); + o->box(FL_PLASTIC_UP_BOX); + o->down_box(FL_DOWN_BOX); + o->labelfont(1); + o->labelsize(11); + o->callback((Fl_Callback*)cb_Enable); + o->align(132|FL_ALIGN_INSIDE); + o->value(microtonal->Penabled); + } // Fl_Check_Button* o + microtonaluiwindow->end(); + } // Fl_Double_Window* microtonaluiwindow + return microtonaluiwindow; +} + +void MicrotonalUI::updateTuningsInput() { + char *tmpbuf=new char[100]; + +tuningsinput->cut(0,tuningsinput->maximum_size()); + +for (int i=0;igetoctavesize();i++){ + if (i!=0) tuningsinput->insert("\n"); + microtonal->tuningtoline(i,tmpbuf,100); + tuningsinput->insert(tmpbuf); +}; + +delete []tmpbuf; +} + +void MicrotonalUI::updateMappingInput() { + char *tmpbuf=new char[100]; + +mappinginput->cut(0,tuningsinput->maximum_size()); + +for (int i=0;iPmapsize;i++){ + if (i!=0) mappinginput->insert("\n"); + if ((microtonal->Pmapping[i])==-1) + snprintf(tmpbuf,100,"x"); + else snprintf(tmpbuf,100,"%d",microtonal->Pmapping[i]); + mappinginput->insert(tmpbuf); +}; + +delete []tmpbuf; +} + +MicrotonalUI::MicrotonalUI(Microtonal *microtonal_) { + microtonal=microtonal_; + +make_window(); +} + +MicrotonalUI::~MicrotonalUI() { + microtonaluiwindow->hide(); +delete(microtonaluiwindow); +} + +void MicrotonalUI::show() { + microtonaluiwindow->show(); +} + +void MicrotonalUI::apply() { + int err=microtonal->texttotunings(tuningsinput->value()); +if (err>=0) fl_alert("Parse Error: The input may contain only numbers (like 232.59)\n or divisions (like 121/64)."); +if (err==-2) fl_alert("Parse Error: The input is empty."); +octavesizeoutput->do_callback(); + +microtonal->texttomapping(mappinginput->value()); +mapsizeoutput->do_callback(); +anotecounter->do_callback(); + +//applybutton->color(FL_GRAY); +} diff --git a/plugins/zynaddsubfx/src/UI/MicrotonalUI.fl b/plugins/zynaddsubfx/src/UI/MicrotonalUI.fl new file mode 100644 index 000000000..adc08b551 --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/MicrotonalUI.fl @@ -0,0 +1,270 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0106 +header_name {.h} +code_name {.cc} +decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} + +decl {//License: GNU GPL version 2 or later} {} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include "../Misc/Microtonal.h"} {public +} + +class MicrotonalUI {} { + Function {make_window()} {} { + Fl_Window microtonaluiwindow { + label Scales + xywh {99 164 405 450} type Double hide + } { + Fl_Group {} { + tooltip {Center where the note's freqs. are turned upside-down} xywh {249 2 155 45} box ENGRAVED_FRAME + } { + Fl_Check_Button {} { + label {Invert keys} + callback {microtonal->Pinvertupdown=(int) o->value(); +if (microtonal->Pinvertupdown==0) centerinvertcounter->deactivate(); + else centerinvertcounter->activate();} + tooltip {Turn upside-down the note frequencies} xywh {254 13 55 30} down_box DOWN_BOX labelfont 1 labelsize 11 align 148 + code0 {o->value(microtonal->Pinvertupdown);} + } + Fl_Counter centerinvertcounter { + label Center + callback {microtonal->Pinvertupdowncenter=(int) o->value();} + xywh {319 13 80 20} labelfont 1 labelsize 11 align 130 minimum 0 maximum 127 step 1 textfont 1 + code0 {o->lstep(microtonal->getoctavesize());} + code1 {o->value(microtonal->Pinvertupdowncenter);} + code2 {if (microtonal->Pinvertupdown==0) o->deactivate();} + } + } + Fl_Group microtonalgroup {selected + xywh {3 49 402 398} box ENGRAVED_FRAME + code0 {if (microtonal->Penabled==0) o->deactivate();} + } { + Fl_Button applybutton { + label Retune + callback {apply();} + tooltip {Retune the synth accorging to the inputs from "Tunnings" and "Keyboard Mappings"} xywh {8 413 107 28} box THIN_UP_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 13 + } + Fl_Value_Output octavesizeoutput { + label {nts./oct.} + callback {o->value(microtonal->getoctavesize());} + tooltip {Notes/Octave} xywh {150 423 35 17} labelsize 10 align 5 maximum 500 step 1 value 12 textfont 1 + code0 {o->value(microtonal->getoctavesize());} + } + Fl_Input nameinput { + label {Name:} + callback {snprintf((char *)microtonal->Pname,MICROTONAL_MAX_NAME_LEN,"%s",o->value());} + xywh {8 64 285 25} labelfont 1 labelsize 11 align 5 + code0 {o->insert((char *)microtonal->Pname);} + } + Fl_Input tuningsinput { + label {Tunings:} + xywh {8 144 182 264} type Multiline labelfont 1 labelsize 11 align 5 when 2 + code0 {updateTuningsInput();} + } + Fl_Input commentinput { + label {Comment:} + callback {snprintf((char *)microtonal->Pcomment,MICROTONAL_MAX_NAME_LEN,"%s",o->value());} + xywh {8 104 391 25} labelfont 1 labelsize 11 align 5 + code0 {o->insert((char *)microtonal->Pcomment);} + } + Fl_Counter {} { + label Shift + callback {microtonal->Pscaleshift=(int) o->value()+64;} + xywh {313 69 70 20} type Simple labelsize 11 align 1 minimum -63 maximum 64 step 1 textfont 1 + code0 {o->value(microtonal->Pscaleshift-64);} + } + Fl_Button {} { + label {Import .SCL file} + callback {const char *filename; +filename=fl_file_chooser("Open:","(*.scl)",NULL,0); +if (filename==NULL) return; +int result=microtonal->loadscl(filename); +if (result==0) { + updateTuningsInput(); + nameinput->cut(0,nameinput->maximum_size()); + nameinput->insert((char *)microtonal->Pname); + nameinput->position(0); + commentinput->cut(0,commentinput->maximum_size()); + commentinput->insert((char *)microtonal->Pname); + commentinput->position(0); + tuningsinput->position(0); + octavesizeoutput->do_callback(); + } else { + fl_alert("Error: Could not load the file."); + };} + tooltip {Inport Scala .scl file (tunnings)} xywh {243 411 84 15} box THIN_UP_BOX labelfont 1 labelsize 10 + } + Fl_Group keymappinggroup { + label {Keyboard Mapping} open + xywh {193 144 206 264} box ENGRAVED_BOX labelfont 1 labelsize 11 + } { + Fl_Input mappinginput { + xywh {250 147 146 258} type Multiline labelfont 1 labelsize 11 align 5 when 2 + code0 {updateMappingInput();} + } + Fl_Counter firstnotecounter { + label {First note} + callback {microtonal->Pfirstkey=(int) o->value();} + tooltip {First MIDI note number} xywh {199 195 42 18} type Simple labelsize 10 align 5 minimum 0 maximum 127 step 1 textfont 1 textsize 11 + code0 {o->value(microtonal->Pfirstkey);} + } + Fl_Counter lastnotecounter { + label {Last note} + callback {microtonal->Plastkey=(int) o->value();} + tooltip {Last MIDI note number} xywh {199 225 42 18} type Simple labelsize 10 align 5 minimum 0 maximum 127 step 1 value 127 textfont 1 textsize 11 + code0 {o->value(microtonal->Plastkey);} + } + Fl_Counter middlenotecounter { + label {Midle note} + callback {microtonal->Pmiddlenote=(int) o->value();} + tooltip {Midle note (where scale degree 0 is mapped to)} xywh {199 267 42 18} type Simple labelsize 10 align 5 minimum 0 maximum 127 step 1 value 60 textfont 1 textsize 11 + code0 {o->value(microtonal->Pmiddlenote);} + } + Fl_Value_Output mapsizeoutput { + label {Map Size} + callback {o->value(microtonal->Pmapsize);} + xywh {201 382 44 20} labelsize 10 align 5 maximum 500 step 1 value 12 textfont 1 + code0 {o->value(microtonal->Pmapsize);} + } + } + Fl_Check_Button mappingenabledbutton { + label ON + callback {int x=(int) o->value(); +microtonal->Pmappingenabled=x; +if (x==0) keymappinggroup->deactivate(); + else keymappinggroup->activate(); +o->show();} + tooltip {Enable the Mapping (otherwise the mapping is linear)} xywh {198 150 48 21} box FLAT_BOX down_box DOWN_BOX labelfont 1 + code0 {o->value(microtonal->Pmappingenabled);} + code1 {if (microtonal->Pmappingenabled==0) keymappinggroup->deactivate();} + } + Fl_Button {} { + label {Import .kbm file} + callback {const char *filename; +filename=fl_file_chooser("Open:","(*.kbm)",NULL,0); +if (filename==NULL) return; +int result=microtonal->loadkbm(filename); +if (result==0) { + updateMappingInput(); + mappinginput->position(0); + mapsizeoutput->do_callback(); + firstnotecounter->value(microtonal->Pfirstkey); + lastnotecounter->value(microtonal->Plastkey); + middlenotecounter->value(microtonal->Pmiddlenote); + mapsizeoutput->do_callback(); + mappingenabledbutton->value(microtonal->Pmappingenabled); + mappingenabledbutton->do_callback(); + afreqinput->value(microtonal->PAfreq); + anotecounter->value(microtonal->PAnote); + anotecounter->do_callback(); + } else { + fl_alert("Error: Could not load the file."); + };} + tooltip {Inport Scala .kbm file (keyboard mapping)} xywh {243 428 84 16} box THIN_UP_BOX labelfont 1 labelsize 10 + } + } + Fl_Group {} { + xywh {108 2 140 45} box ENGRAVED_FRAME + } { + Fl_Counter anotecounter { + label {"A" Note} + callback {microtonal->PAnote=(int) o->value(); +if (microtonal->getnotefreq(microtonal->PAnote,0)<0.0) o->textcolor(FL_RED); + else o->textcolor(FL_BLACK); + +o->redraw();} + tooltip {The "A" note (the reference note for which freq. ("A" freq) is given)} xywh {173 17 65 20} labelfont 1 labelsize 10 align 129 minimum 0 maximum 127 step 1 value 69 textfont 1 textsize 10 + code0 {o->lstep(12);} + code1 {o->value(microtonal->PAnote);} + } + Fl_Value_Input afreqinput { + label {"A" Freq.} + callback {microtonal->PAfreq=o->value();} + tooltip {The freq. of "A" note (default=440.0)} xywh {118 17 45 20} labelfont 1 labelsize 10 align 1 minimum 1 maximum 20000 step 0.001 value 440 textfont 1 textsize 10 + code0 {o->value(microtonal->PAfreq);} + } + } + Fl_Button {} { + label Close + callback {microtonaluiwindow->hide();} + xywh {333 413 67 28} box THIN_UP_BOX + } + Fl_Check_Button {} { + label {Enable Microtonal} + callback {microtonal->Penabled=(int) o->value(); +if (microtonal->Penabled==0) microtonalgroup->deactivate(); + else microtonalgroup->activate();} + xywh {3 3 102 45} box PLASTIC_UP_BOX down_box DOWN_BOX labelfont 1 labelsize 11 align 148 + code0 {o->value(microtonal->Penabled);} + } + } + } + Function {updateTuningsInput()} {} { + code {char *tmpbuf=new char[100]; + +tuningsinput->cut(0,tuningsinput->maximum_size()); + +for (int i=0;igetoctavesize();i++){ + if (i!=0) tuningsinput->insert("\\n"); + microtonal->tuningtoline(i,tmpbuf,100); + tuningsinput->insert(tmpbuf); +}; + +delete []tmpbuf;} {} + } + Function {updateMappingInput()} {} { + code {char *tmpbuf=new char[100]; + +mappinginput->cut(0,tuningsinput->maximum_size()); + +for (int i=0;iPmapsize;i++){ + if (i!=0) mappinginput->insert("\\n"); + if ((microtonal->Pmapping[i])==-1) + snprintf(tmpbuf,100,"x"); + else snprintf(tmpbuf,100,"%d",microtonal->Pmapping[i]); + mappinginput->insert(tmpbuf); +}; + +delete []tmpbuf;} {} + } + Function {MicrotonalUI(Microtonal *microtonal_)} {} { + code {microtonal=microtonal_; + +make_window();} {} + } + Function {~MicrotonalUI()} {} { + code {microtonaluiwindow->hide(); +delete(microtonaluiwindow);} {} + } + Function {show()} {} { + code {microtonaluiwindow->show();} {} + } + Function {apply()} {} { + code {int err=microtonal->texttotunings(tuningsinput->value()); +if (err>=0) fl_alert("Parse Error: The input may contain only numbers (like 232.59)\\n or divisions (like 121/64)."); +if (err==-2) fl_alert("Parse Error: The input is empty."); +octavesizeoutput->do_callback(); + +microtonal->texttomapping(mappinginput->value()); +mapsizeoutput->do_callback(); +anotecounter->do_callback(); + +//applybutton->color(FL_GRAY);} {} + } + decl {Microtonal *microtonal;} {} +} diff --git a/plugins/zynaddsubfx/src/UI/MicrotonalUI.h b/plugins/zynaddsubfx/src/UI/MicrotonalUI.h new file mode 100644 index 000000000..626f2b983 --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/MicrotonalUI.h @@ -0,0 +1,112 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0109 + +#ifndef MicrotonalUI_h +#define MicrotonalUI_h +#include +#include +#include +#include +#include +#include +#include "../Misc/Microtonal.h" +#include +#include +#include +#include +#include +#include +#include +#include + +class MicrotonalUI { +public: + Fl_Double_Window* make_window(); + Fl_Double_Window *microtonaluiwindow; +private: + void cb_Invert_i(Fl_Check_Button*, void*); + static void cb_Invert(Fl_Check_Button*, void*); +public: + Fl_Counter *centerinvertcounter; +private: + void cb_centerinvertcounter_i(Fl_Counter*, void*); + static void cb_centerinvertcounter(Fl_Counter*, void*); +public: + Fl_Group *microtonalgroup; + Fl_Button *applybutton; +private: + void cb_applybutton_i(Fl_Button*, void*); + static void cb_applybutton(Fl_Button*, void*); +public: + Fl_Value_Output *octavesizeoutput; +private: + void cb_octavesizeoutput_i(Fl_Value_Output*, void*); + static void cb_octavesizeoutput(Fl_Value_Output*, void*); +public: + Fl_Input *nameinput; +private: + void cb_nameinput_i(Fl_Input*, void*); + static void cb_nameinput(Fl_Input*, void*); +public: + Fl_Input *tuningsinput; + Fl_Input *commentinput; +private: + void cb_commentinput_i(Fl_Input*, void*); + static void cb_commentinput(Fl_Input*, void*); + void cb_Shift_i(Fl_Counter*, void*); + static void cb_Shift(Fl_Counter*, void*); + void cb_Import_i(Fl_Button*, void*); + static void cb_Import(Fl_Button*, void*); +public: + Fl_Group *keymappinggroup; + Fl_Input *mappinginput; + Fl_Counter *firstnotecounter; +private: + void cb_firstnotecounter_i(Fl_Counter*, void*); + static void cb_firstnotecounter(Fl_Counter*, void*); +public: + Fl_Counter *lastnotecounter; +private: + void cb_lastnotecounter_i(Fl_Counter*, void*); + static void cb_lastnotecounter(Fl_Counter*, void*); +public: + Fl_Counter *middlenotecounter; +private: + void cb_middlenotecounter_i(Fl_Counter*, void*); + static void cb_middlenotecounter(Fl_Counter*, void*); +public: + Fl_Value_Output *mapsizeoutput; +private: + void cb_mapsizeoutput_i(Fl_Value_Output*, void*); + static void cb_mapsizeoutput(Fl_Value_Output*, void*); +public: + Fl_Check_Button *mappingenabledbutton; +private: + void cb_mappingenabledbutton_i(Fl_Check_Button*, void*); + static void cb_mappingenabledbutton(Fl_Check_Button*, void*); + void cb_Import1_i(Fl_Button*, void*); + static void cb_Import1(Fl_Button*, void*); +public: + Fl_Counter *anotecounter; +private: + void cb_anotecounter_i(Fl_Counter*, void*); + static void cb_anotecounter(Fl_Counter*, void*); +public: + Fl_Value_Input *afreqinput; +private: + void cb_afreqinput_i(Fl_Value_Input*, void*); + static void cb_afreqinput(Fl_Value_Input*, void*); + void cb_Close_i(Fl_Button*, void*); + static void cb_Close(Fl_Button*, void*); + void cb_Enable_i(Fl_Check_Button*, void*); + static void cb_Enable(Fl_Check_Button*, void*); +public: + void updateTuningsInput(); + void updateMappingInput(); + MicrotonalUI(Microtonal *microtonal_); + ~MicrotonalUI(); + void show(); + void apply(); +private: + Microtonal *microtonal; +}; +#endif diff --git a/plugins/zynaddsubfx/src/UI/OscilGenUI.cc b/plugins/zynaddsubfx/src/UI/OscilGenUI.cc new file mode 100644 index 000000000..20e016a5d --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/OscilGenUI.cc @@ -0,0 +1,1409 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0109 + +#include "OscilGenUI.h" +//Copyright (c) 2002-2005 Nasca Octavian Paul +//License: GNU GPL version 2 or later +#include +#include +#include +#include + +OscilSpectrum::OscilSpectrum(int x,int y, int w, int h, const char *label):Fl_Box(x,y,w,h,label) { + oscil=NULL; +} + +void OscilSpectrum::init(OscilGen *oscil_,int oscbase_,Master *master_) { + oscil=oscil_; +oscbase=oscbase_; +master=master_; +} + +void OscilSpectrum::draw() { + int ox=x(),oy=y(),lx=w(),ly=h(),i; +const int maxdb=60;//must be multiple of 10 +int GX=2; +int n=lx/GX-1; +if (n>OSCIL_SIZE/2) n=OSCIL_SIZE/2; + +REALTYPE x; +REALTYPE* spc=new REALTYPE[n]; +for (i=0;imutex); +if (oscbase==0) oscil->getspectrum(n,spc,0); + else oscil->getspectrum(n,spc,1); +pthread_mutex_unlock(&master->mutex); + +//normalize +REALTYPE max=0; +for (i=0;iactive_r()) fl_color(this->parent()->selection_color()); + else fl_color(this->parent()->color()); +fl_line_style(FL_DOT); + +for (i=1;iactive_r()) fl_color(this->parent()->labelcolor()); + else fl_color(this->parent()->color()); +fl_line_style(0); + +//draws the spectrum +for (i=0;idB2rap(-maxdb)) x=rap2dB(x)/maxdb+1; + else x=0; + + int val=(int) ((ly-2)*x); + if (val>0) fl_line(ox+tmp,oy+ly-2-val,ox+tmp,oy+ly-2); +} +delete [] spc; +} + +PSlider::PSlider(int x,int y, int w, int h, const char *label):Fl_Slider(x,y,w,h,label) { +} + +int PSlider::handle(int event) { + int X=x(),Y=y(),W=w(),H=h(); + +if ((!Fl::event_buttons())|| (event==0)||(Fl::event_shift()==0)) return(Fl_Slider::handle(event)); + +if (!Fl::event_inside(X,Y,W,H)) { + if (event==FL_DRAG){ + Fl_Slider::handle(FL_RELEASE); + Fl_Slider::handle(FL_LEAVE); + deactivate(); + activate(); + return(1); + }else{ + return(Fl_Slider::handle(event)); + }; +} else { + //Fl_Slider::handle(FL_FOCUS); + Fl_Slider::handle(FL_PUSH); +}; + +return(1); +} + +Oscilloscope::Oscilloscope(int x,int y, int w, int h, const char *label):Fl_Box(x,y,w,h,label) { + oscil=NULL; +phase=64; +oscbase=0; +} + +void Oscilloscope::init(OscilGen *oscil_,Master *master_) { + oscil=oscil_; +master=master_; +} + +void Oscilloscope::init(OscilGen *oscil_,int oscbase_,Master *master_) { + oscil=oscil_; +oscbase=oscbase_; +master=master_; +} + +void Oscilloscope::init(OscilGen *oscil_,int oscbase_,int phase_,Master *master_) { + oscil=oscil_; +oscbase=oscbase_; +phase=phase_; +master=master_; +} + +void Oscilloscope::draw() { + int ox=x(),oy=y(),lx=w(),ly=h()-1,i; +REALTYPE smps[OSCIL_SIZE]; +pthread_mutex_lock(&master->mutex); +if (oscbase==0) oscil->get(smps,-1.0); + else oscil->getcurrentbasefunction(smps); +pthread_mutex_unlock(&master->mutex); + +if (damage()!=1){ + fl_color(0,0,0); + fl_rectf(ox,oy,lx,ly); +}; + +//normalize +REALTYPE max=0; +for (i=0;iactive_r()) fl_color(this->parent()->labelcolor()); + else fl_color(this->parent()->color()); +int GX=16;if (lxactive_r()) fl_color(this->parent()->selection_color()); + else fl_color(this->parent()->labelcolor()); +int lw=1; +//if ((lx<135)||(ly<135)) lw=1; +fl_line_style(0,lw); +int ph=(int)((phase-64.0)/128.0*OSCIL_SIZE+OSCIL_SIZE); +for (i=1;ivalue(x); + else x=127-(int)o->value(); +if (x==64) o->selection_color(0); + else o->selection_color(222); + +pthread_mutex_lock(&master->mutex); + oscil->Phmag[n]=x; + if (x==64) { + oscil->Phphase[n]=64; + phase->value(64); + }; + oscil->prepare(); +pthread_mutex_unlock(&master->mutex); + +display->redraw(); +oldosc->redraw(); +if (cbwidget!=NULL) { + cbwidget->do_callback(); + applybutton->color(FL_RED); + applybutton->redraw(); +}; +} +void Oscilharmonic::cb_mag(PSlider* o, void* v) { + ((Oscilharmonic*)(o->parent()->user_data()))->cb_mag_i(o,v); +} + +void Oscilharmonic::cb_phase_i(PSlider* o, void*) { + int x=64; +if (Fl::event_button3()) o->value(x); + else x=(int)o->value(); + +pthread_mutex_lock(&master->mutex); + oscil->Phphase[n]=x; + oscil->prepare(); +pthread_mutex_unlock(&master->mutex); + +display->redraw(); +oldosc->redraw(); +if (cbwidget!=NULL) { + cbwidget->do_callback(); + applybutton->color(FL_RED); + applybutton->redraw(); +}; +} +void Oscilharmonic::cb_phase(PSlider* o, void* v) { + ((Oscilharmonic*)(o->parent()->user_data()))->cb_phase_i(o,v); +} + +Fl_Group* Oscilharmonic::make_window() { + { harmonic = new Fl_Group(0, 0, 90, 225); + harmonic->box(FL_FLAT_BOX); + harmonic->color(FL_BACKGROUND_COLOR); + harmonic->selection_color(FL_BACKGROUND_COLOR); + harmonic->labeltype(FL_NO_LABEL); + harmonic->labelfont(0); + harmonic->labelsize(14); + harmonic->labelcolor(FL_FOREGROUND_COLOR); + harmonic->user_data((void*)(this)); + harmonic->align(FL_ALIGN_TOP); + harmonic->when(FL_WHEN_RELEASE); + { PSlider* o = mag = new PSlider(0, 15, 15, 115); + mag->type(4); + mag->box(FL_FLAT_BOX); + mag->color(FL_BACKGROUND_COLOR); + mag->selection_color((Fl_Color)222); + mag->labeltype(FL_NORMAL_LABEL); + mag->labelfont(0); + mag->labelsize(14); + mag->labelcolor(FL_FOREGROUND_COLOR); + mag->maximum(127); + mag->step(1); + mag->value(64); + mag->callback((Fl_Callback*)cb_mag); + mag->align(FL_ALIGN_BOTTOM); + mag->when(FL_WHEN_CHANGED); + o->value(127-oscil->Phmag[n]); + if (oscil->Phmag[n]==64) o->selection_color(0); + } // PSlider* mag + { PSlider* o = phase = new PSlider(0, 135, 15, 75); + phase->type(4); + phase->box(FL_FLAT_BOX); + phase->color(FL_BACKGROUND_COLOR); + phase->selection_color((Fl_Color)222); + phase->labeltype(FL_NORMAL_LABEL); + phase->labelfont(0); + phase->labelsize(14); + phase->labelcolor(FL_FOREGROUND_COLOR); + phase->maximum(127); + phase->step(1); + phase->value(64); + phase->callback((Fl_Callback*)cb_phase); + phase->align(FL_ALIGN_BOTTOM); + phase->when(FL_WHEN_CHANGED); + o->value(oscil->Phphase[n]); + } // PSlider* phase + { Fl_Box* o = new Fl_Box(15, 70, 5, 5); + o->box(FL_FLAT_BOX); + o->color(FL_DARK2); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(15, 170, 5, 5); + o->box(FL_FLAT_BOX); + o->color(FL_DARK2); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(0, 210, 20, 15, "01"); + o->labelfont(1); + o->labelsize(9); + o->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE); + char tmp[10];snprintf(tmp,10,"%d",n+1);o->label(strdup(tmp)); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(0, 0, 20, 15, "01"); + o->labelfont(1); + o->labelsize(9); + o->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE); + char tmp[10];snprintf(tmp,10,"%d",n+1);o->label(strdup(tmp)); + } // Fl_Box* o + harmonic->end(); + } // Fl_Group* harmonic + return harmonic; +} + +Oscilharmonic::Oscilharmonic(int x,int y, int w, int h, const char *label):Fl_Group(x,y,w,h,label) { + n=0; +oscil=NULL; +display=NULL; +applybutton=NULL; +cbwidget=NULL; +} + +void Oscilharmonic::init(OscilGen *oscil_,int n_,Fl_Group *display_,Fl_Widget *oldosc_,Fl_Widget *cbwidget_,Fl_Widget *applybutton_, Master *master_) { + oscil=oscil_; +n=n_; +display=display_; +master=master_; +oldosc=oldosc_; +cbwidget=cbwidget_; +applybutton=applybutton_; +make_window(); +end(); +harmonic->show(); +} + +void Oscilharmonic::refresh() { + mag->value(127-oscil->Phmag[n]); +phase->value(oscil->Phphase[n]); + +if (oscil->Phmag[n]==64) mag->selection_color(0); + else mag->selection_color(222); +} + +Oscilharmonic::~Oscilharmonic() { + harmonic->hide(); +//delete(harmonic); +} + +void OscilEditor::cb_applybutton_i(Fl_Button*, void*) { + applybutton->color(FL_GRAY); +applybutton->redraw(); +if (cbapplywidget!=NULL) { + cbapplywidget->do_callback(); + cbapplywidget->color(FL_GRAY); + cbapplywidget->redraw(); +}; +} +void OscilEditor::cb_applybutton(Fl_Button* o, void* v) { + ((OscilEditor*)(o->parent()->user_data()))->cb_applybutton_i(o,v); +} + +void OscilEditor::cb_rndslider_i(Fl_Value_Slider* o, void*) { + oscil->Prand=(int)o->value()+64; +oscildisplaygroup->redraw(); +oldosc->redraw(); +} +void OscilEditor::cb_rndslider(Fl_Value_Slider* o, void* v) { + ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_rndslider_i(o,v); +} + +void OscilEditor::cb_hrndtype_i(Fl_Choice* o, void*) { + oscil->Pamprandtype=(int) o->value(); +} +void OscilEditor::cb_hrndtype(Fl_Choice* o, void* v) { + ((OscilEditor*)(o->parent()->parent()->parent()->user_data()))->cb_hrndtype_i(o,v); +} + +Fl_Menu_Item OscilEditor::menu_hrndtype[] = { + {"None", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Pow", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Sin", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void OscilEditor::cb_hrnddial_i(WidgetPDial* o, void*) { + oscil->Pamprandpower=(int) o->value(); +} +void OscilEditor::cb_hrnddial(WidgetPDial* o, void* v) { + ((OscilEditor*)(o->parent()->parent()->parent()->user_data()))->cb_hrnddial_i(o,v); +} + +void OscilEditor::cb_bfslider_i(WidgetPDial* o, void*) { + oscil->Pbasefuncpar=(int)o->value()+64; +basefuncdisplaygroup->redraw(); +bfparval->value(oscil->Pbasefuncpar-64); + +redrawoscil(); +} +void OscilEditor::cb_bfslider(WidgetPDial* o, void* v) { + ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_bfslider_i(o,v); +} + +void OscilEditor::cb_bftype_i(Fl_Choice* o, void*) { + oscil->Pcurrentbasefunc=(int) o->value(); + +basefuncdisplaygroup->redraw(); +redrawoscil(); + +if ((oscil->Pcurrentbasefunc==0)||(oscil->Pcurrentbasefunc==127)) basefuncmodulation->deactivate(); + else basefuncmodulation->activate(); +} +void OscilEditor::cb_bftype(Fl_Choice* o, void* v) { + ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_bftype_i(o,v); +} + +Fl_Menu_Item OscilEditor::menu_bftype[] = { + {"Sine", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"Triangle", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"Pulse", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"Saw", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"Power", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"Gauss", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"Diode", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"AbsSine", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"PulseSine", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"StrchSine", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"Chirp", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"AbsStrSine", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"Chebyshev", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"Sqr", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void OscilEditor::cb_bfmodtype_i(Fl_Choice* o, void*) { + oscil->Pbasefuncmodulation=(int) o->value(); +basefuncdisplaygroup->redraw(); +redrawoscil(); +} +void OscilEditor::cb_bfmodtype(Fl_Choice* o, void* v) { + ((OscilEditor*)(o->parent()->parent()->parent()->user_data()))->cb_bfmodtype_i(o,v); +} + +Fl_Menu_Item OscilEditor::menu_bfmodtype[] = { + {"None", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Rev", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Sine", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Pow", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void OscilEditor::cb_bfmodpar1_i(WidgetPDial* o, void*) { + oscil->Pbasefuncmodulationpar1=(int)o->value(); +basefuncdisplaygroup->redraw(); +redrawoscil(); +} +void OscilEditor::cb_bfmodpar1(WidgetPDial* o, void* v) { + ((OscilEditor*)(o->parent()->parent()->parent()->user_data()))->cb_bfmodpar1_i(o,v); +} + +void OscilEditor::cb_bfmodpar2_i(WidgetPDial* o, void*) { + oscil->Pbasefuncmodulationpar2=(int)o->value(); +basefuncdisplaygroup->redraw(); +redrawoscil(); +} +void OscilEditor::cb_bfmodpar2(WidgetPDial* o, void* v) { + ((OscilEditor*)(o->parent()->parent()->parent()->user_data()))->cb_bfmodpar2_i(o,v); +} + +void OscilEditor::cb_bfmodpar3_i(WidgetPDial* o, void*) { + oscil->Pbasefuncmodulationpar3=(int)o->value(); +basefuncdisplaygroup->redraw(); +redrawoscil(); +} +void OscilEditor::cb_bfmodpar3(WidgetPDial* o, void* v) { + ((OscilEditor*)(o->parent()->parent()->parent()->user_data()))->cb_bfmodpar3_i(o,v); +} + +void OscilEditor::cb_magtype_i(Fl_Choice* o, void*) { + oscil->Phmagtype=(int) o->value(); +basefuncdisplaygroup->redraw(); + +redrawoscil(); +} +void OscilEditor::cb_magtype(Fl_Choice* o, void* v) { + ((OscilEditor*)(o->parent()->user_data()))->cb_magtype_i(o,v); +} + +Fl_Menu_Item OscilEditor::menu_magtype[] = { + {"Linear", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"-40dB", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"-60dB", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"-80dB", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"-100dB", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void OscilEditor::cb_Use_i(Fl_Button*, void*) { + oscil->useasbase(); +if (autoclearbutton->value()){ + for (int i=0;imag->value(64); + oscil->Phmag[i]=64; + h[i]->phase->value(64); + oscil->Phphase[i]=64; + }; + oscil->Phmag[0]=127; + + oscil->Pharmonicshift=0; + harmonicshiftcounter->value(0); + + h[0]->mag->value(0); + wshbutton->value(0); + wshbutton->do_callback(); + fltbutton->value(0); + fltbutton->do_callback(); + sabutton->value(0); + sabutton->do_callback(); +}; + +pthread_mutex_lock(&master->mutex); + for (int i=0;iPhmag[i]==64) h[i]->mag->selection_color(0); + else h[i]->mag->selection_color(222); + }; + oscil->prepare(); +pthread_mutex_unlock(&master->mutex); + +basefuncdisplaygroup->redraw(); +redrawoscil(); +} +void OscilEditor::cb_Use(Fl_Button* o, void* v) { + ((OscilEditor*)(o->parent()->user_data()))->cb_Use_i(o,v); +} + +void OscilEditor::cb_Close_i(Fl_Button*, void*) { + osceditUI->hide(); +} +void OscilEditor::cb_Close(Fl_Button* o, void* v) { + ((OscilEditor*)(o->parent()->user_data()))->cb_Close_i(o,v); +} + +void OscilEditor::cb_Clear_i(Fl_Button*, void*) { + if (!fl_choice("Clear the harmonics settings?","No","Yes",NULL)) return; + +for (int i=0;imag->value(64); + oscil->Phmag[i]=64; + h[i]->phase->value(64); + oscil->Phphase[i]=64; +}; +oscil->Phmag[0]=127; +h[0]->mag->value(0); + +for (int i=0;iPhmag[i]==64) h[i]->mag->selection_color(0); + else h[i]->mag->selection_color(222); +}; + +//harmonics->redraw(); + +pthread_mutex_lock(&master->mutex); + oscil->prepare(); +pthread_mutex_unlock(&master->mutex); + +redrawoscil(); +} +void OscilEditor::cb_Clear(Fl_Button* o, void* v) { + ((OscilEditor*)(o->parent()->user_data()))->cb_Clear_i(o,v); +} + +void OscilEditor::cb_wshbutton_i(Fl_Choice* o, void*) { + oscil->Pwaveshapingfunction=(int) o->value(); +basefuncdisplaygroup->redraw(); +redrawoscil(); +} +void OscilEditor::cb_wshbutton(Fl_Choice* o, void* v) { + ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_wshbutton_i(o,v); +} + +Fl_Menu_Item OscilEditor::menu_wshbutton[] = { + {"None", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Atan", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Asym1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Pow", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Sine", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Qnts", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Zigzg", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Lmt", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"LmtU", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"LmtL", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"ILmt", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Clip", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Asym2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Pow2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Sgm", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void OscilEditor::cb_wshpar_i(WidgetPDial* o, void*) { + oscil->Pwaveshaping=(int)o->value()+64; +wsparval->value(oscil->Pwaveshaping-64); +redrawoscil(); +} +void OscilEditor::cb_wshpar(WidgetPDial* o, void* v) { + ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_wshpar_i(o,v); +} + +void OscilEditor::cb_fltbutton_i(Fl_Choice* o, void*) { + oscil->Pfiltertype=(int) o->value(); + +redrawoscil(); +} +void OscilEditor::cb_fltbutton(Fl_Choice* o, void* v) { + ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_fltbutton_i(o,v); +} + +Fl_Menu_Item OscilEditor::menu_fltbutton[] = { + {"None", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"LP1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"HP1a", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"HP1b", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"BP1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"BS1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"LP2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"HP2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"BP2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"BS2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Cos", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Sin", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"LSh", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"S", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void OscilEditor::cb_filtervalue1_i(WidgetPDial* o, void*) { + oscil->Pfilterpar1=(int)o->value(); + +redrawoscil(); +} +void OscilEditor::cb_filtervalue1(WidgetPDial* o, void* v) { + ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_filtervalue1_i(o,v); +} + +void OscilEditor::cb_filterpref_i(Fl_Check_Button* o, void*) { + oscil->Pfilterbeforews=(int)o->value(); + +redrawoscil(); +} +void OscilEditor::cb_filterpref(Fl_Check_Button* o, void* v) { + ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_filterpref_i(o,v); +} + +void OscilEditor::cb_filtervalue2_i(WidgetPDial* o, void*) { + oscil->Pfilterpar2=(int)o->value(); + +redrawoscil(); +} +void OscilEditor::cb_filtervalue2(WidgetPDial* o, void* v) { + ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_filtervalue2_i(o,v); +} + +void OscilEditor::cb_sabutton_i(Fl_Choice* o, void*) { + oscil->Psatype=(int) o->value(); +redrawoscil(); +} +void OscilEditor::cb_sabutton(Fl_Choice* o, void* v) { + ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_sabutton_i(o,v); +} + +Fl_Menu_Item OscilEditor::menu_sabutton[] = { + {"None", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Pow", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"ThrsD", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"ThrsU", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void OscilEditor::cb_sadjpar_i(WidgetPDial* o, void*) { + oscil->Psapar=(int)o->value(); +redrawoscil(); +} +void OscilEditor::cb_sadjpar(WidgetPDial* o, void* v) { + ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_sadjpar_i(o,v); +} + +void OscilEditor::cb_harmonicshiftcounter_i(Fl_Counter* o, void*) { + oscil->Pharmonicshift=(int)o->value(); +redrawoscil(); +} +void OscilEditor::cb_harmonicshiftcounter(Fl_Counter* o, void* v) { + ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_harmonicshiftcounter_i(o,v); +} + +void OscilEditor::cb_harmonicshiftpre_i(Fl_Check_Button* o, void*) { + oscil->Pharmonicshiftfirst=(int)o->value(); +redrawoscil(); +} +void OscilEditor::cb_harmonicshiftpre(Fl_Check_Button* o, void* v) { + ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_harmonicshiftpre_i(o,v); +} + +void OscilEditor::cb_R_i(Fl_Button*, void*) { + oscil->Pharmonicshift=0; +harmonicshiftcounter->value(0); +redrawoscil(); +} +void OscilEditor::cb_R(Fl_Button* o, void* v) { + ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_R_i(o,v); +} + +void OscilEditor::cb_adhrtype_i(Fl_Choice* o, void*) { + oscil->Padaptiveharmonics=(int) o->value(); +redrawoscil(); +} +void OscilEditor::cb_adhrtype(Fl_Choice* o, void* v) { + ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_adhrtype_i(o,v); +} + +Fl_Menu_Item OscilEditor::menu_adhrtype[] = { + {"OFF", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"ON", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Square", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"2xSub", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"2xAdd", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"3xSub", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"3xAdd", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"4xSub", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"4xAdd", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void OscilEditor::cb_adhrpow_i(WidgetPDial* o, void*) { + oscil->Padaptiveharmonicspower=(int)o->value(); +redrawoscil(); +} +void OscilEditor::cb_adhrpow(WidgetPDial* o, void* v) { + ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_adhrpow_i(o,v); +} + +void OscilEditor::cb_adhrbf_i(WidgetPDial* o, void*) { + oscil->Padaptiveharmonicsbasefreq=(int)o->value(); +redrawoscil(); +} +void OscilEditor::cb_adhrbf(WidgetPDial* o, void* v) { + ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_adhrbf_i(o,v); +} + +void OscilEditor::cb_adhrpar_i(Fl_Slider* o, void*) { + oscil->Padaptiveharmonicspar=(int)o->value(); +redrawoscil(); +} +void OscilEditor::cb_adhrpar(Fl_Slider* o, void* v) { + ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_adhrpar_i(o,v); +} + +void OscilEditor::cb_modtype_i(Fl_Choice* o, void*) { + oscil->Pmodulation=(int) o->value(); + +redrawoscil(); +} +void OscilEditor::cb_modtype(Fl_Choice* o, void* v) { + ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_modtype_i(o,v); +} + +Fl_Menu_Item OscilEditor::menu_modtype[] = { + {"None", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Rev", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Sine", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Pow", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void OscilEditor::cb_modpar1_i(WidgetPDial* o, void*) { + oscil->Pmodulationpar1=(int)o->value(); + +redrawoscil(); +} +void OscilEditor::cb_modpar1(WidgetPDial* o, void* v) { + ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_modpar1_i(o,v); +} + +void OscilEditor::cb_modpar2_i(WidgetPDial* o, void*) { + oscil->Pmodulationpar2=(int)o->value(); + +redrawoscil(); +} +void OscilEditor::cb_modpar2(WidgetPDial* o, void* v) { + ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_modpar2_i(o,v); +} + +void OscilEditor::cb_modpar3_i(WidgetPDial* o, void*) { + oscil->Pmodulationpar3=(int)o->value(); +redrawoscil(); +} +void OscilEditor::cb_modpar3(WidgetPDial* o, void* v) { + ((OscilEditor*)(o->parent()->parent()->user_data()))->cb_modpar3_i(o,v); +} + +void OscilEditor::cb_Sine_i(Fl_Button*, void*) { + if (!fl_choice("Convert to SINE?","No","Yes",NULL)) return; + +pthread_mutex_lock(&master->mutex); + oscil->convert2sine(0); +pthread_mutex_unlock(&master->mutex); + +redrawoscil(); +refresh(); +} +void OscilEditor::cb_Sine(Fl_Button* o, void* v) { + ((OscilEditor*)(o->parent()->user_data()))->cb_Sine_i(o,v); +} + +void OscilEditor::cb_C_i(Fl_Button*, void*) { + presetsui->copy(oscil); +} +void OscilEditor::cb_C(Fl_Button* o, void* v) { + ((OscilEditor*)(o->parent()->user_data()))->cb_C_i(o,v); +} + +void OscilEditor::cb_P_i(Fl_Button*, void*) { + presetsui->paste(oscil,this); +} +void OscilEditor::cb_P(Fl_Button* o, void* v) { + ((OscilEditor*)(o->parent()->user_data()))->cb_P_i(o,v); +} + +Fl_Double_Window* OscilEditor::make_window() { + { Fl_Double_Window* o = osceditUI = new Fl_Double_Window(735, 595, "ADsynth Oscillator Editor"); + osceditUI->user_data((void*)(this)); + { Fl_Button* o = applybutton = new Fl_Button(300, 280, 60, 20, "Apply"); + applybutton->box(FL_THIN_UP_BOX); + applybutton->labelfont(1); + applybutton->callback((Fl_Callback*)cb_applybutton); + if (!oscil->ADvsPAD) o->hide(); + } // Fl_Button* applybutton + { oscildisplaygroup = new Fl_Group(5, 5, 360, 300); + oscildisplaygroup->box(FL_ENGRAVED_FRAME); + { Fl_Group* o = new Fl_Group(10, 85, 350, 190); + o->box(FL_THIN_DOWN_BOX); + o->color(FL_GRAY0); + o->selection_color((Fl_Color)71); + o->labelcolor((Fl_Color)179); + Oscilloscope *osc=new Oscilloscope(o->x(),o->y(),o->w(),o->h(),""); + osc->init(oscil,master); + o->end(); + } // Fl_Group* o + { Fl_Box* o = new Fl_Box(120, 10, 110, 20, "Oscillator"); + o->box(FL_FLAT_BOX); + o->labelfont(1); + } // Fl_Box* o + { Fl_Value_Slider* o = rndslider = new Fl_Value_Slider(140, 285, 100, 10, "rnd"); + rndslider->tooltip("Oscilator Phase Randomness: smaller than 0 is \"group\", larger than 0 is for\ + each harmonic"); + rndslider->type(5); + rndslider->box(FL_FLAT_BOX); + rndslider->labelsize(10); + rndslider->minimum(-64); + rndslider->maximum(63); + rndslider->step(1); + rndslider->callback((Fl_Callback*)cb_rndslider); + rndslider->align(FL_ALIGN_TOP_LEFT); + if (oscil->ADvsPAD) o->hide(); + } // Fl_Value_Slider* rndslider + { Fl_Group* o = new Fl_Group(10, 30, 350, 50); + o->box(FL_THIN_DOWN_BOX); + o->color(FL_GRAY0); + o->selection_color((Fl_Color)218); + o->labelcolor(FL_GREEN); + OscilSpectrum *spc=new OscilSpectrum(o->x(),o->y(),o->w(),o->h(),""); + spc->init(oscil,0,master); + o->end(); + } // Fl_Group* o + { Fl_Group* o = new Fl_Group(246, 277, 115, 25); + o->box(FL_ENGRAVED_BOX); + { hrndtype = new Fl_Choice(281, 282, 50, 15, "H.rnd"); + hrndtype->tooltip("Harmonic Amplitude Randomness"); + hrndtype->down_box(FL_BORDER_BOX); + hrndtype->labelsize(10); + hrndtype->textsize(10); + hrndtype->callback((Fl_Callback*)cb_hrndtype); + hrndtype->menu(menu_hrndtype); + } // Fl_Choice* hrndtype + { hrnddial = new WidgetPDial(338, 280, 18, 18); + hrnddial->tooltip("Oscillator\'s spectrum adjust parameter"); + hrnddial->box(FL_OVAL_BOX); + hrnddial->color(FL_BACKGROUND_COLOR); + hrnddial->selection_color(FL_INACTIVE_COLOR); + hrnddial->labeltype(FL_NORMAL_LABEL); + hrnddial->labelfont(0); + hrnddial->labelsize(14); + hrnddial->labelcolor(FL_FOREGROUND_COLOR); + hrnddial->maximum(127); + hrnddial->step(1); + hrnddial->callback((Fl_Callback*)cb_hrnddial); + hrnddial->align(FL_ALIGN_BOTTOM); + hrnddial->when(FL_WHEN_CHANGED); + } // WidgetPDial* hrnddial + if (oscil->ADvsPAD) o->hide(); + o->end(); + } // Fl_Group* o + oscildisplaygroup->end(); + } // Fl_Group* oscildisplaygroup + { Fl_Box* o = new Fl_Box(495, 15, 110, 20, "Base Func."); + o->box(FL_FLAT_BOX); + o->labelfont(1); + } // Fl_Box* o + { basefuncdisplaygroup = new Fl_Group(365, 5, 360, 300); + basefuncdisplaygroup->box(FL_ENGRAVED_FRAME); + { Fl_Group* o = new Fl_Group(370, 85, 350, 190); + o->box(FL_THIN_DOWN_BOX); + o->color(FL_GRAY0); + o->selection_color((Fl_Color)71); + o->labelcolor((Fl_Color)179); + Oscilloscope *osc=new Oscilloscope(o->x(),o->y(),o->w(),o->h(),""); + osc->init(oscil,1,master); + o->end(); + } // Fl_Group* o + { bfslider = new WidgetPDial(520, 280, 20, 20); + bfslider->tooltip("Base Function Parameter"); + bfslider->box(FL_OVAL_BOX); + bfslider->color(FL_BACKGROUND_COLOR); + bfslider->selection_color(FL_INACTIVE_COLOR); + bfslider->labeltype(FL_NORMAL_LABEL); + bfslider->labelfont(0); + bfslider->labelsize(14); + bfslider->labelcolor(FL_FOREGROUND_COLOR); + bfslider->minimum(-64); + bfslider->maximum(63); + bfslider->step(1); + bfslider->callback((Fl_Callback*)cb_bfslider); + bfslider->align(FL_ALIGN_BOTTOM); + bfslider->when(FL_WHEN_CHANGED); + } // WidgetPDial* bfslider + { bftype = new Fl_Choice(370, 285, 90, 15, "Base.F.."); + bftype->down_box(FL_BORDER_BOX); + bftype->labelsize(10); + bftype->textsize(11); + bftype->callback((Fl_Callback*)cb_bftype); + bftype->align(FL_ALIGN_TOP_LEFT); + bftype->menu(menu_bftype); + } // Fl_Choice* bftype + { Fl_Box* o = new Fl_Box(480, 10, 110, 20, "Base Func."); + o->box(FL_FLAT_BOX); + o->labelfont(1); + } // Fl_Box* o + { Fl_Group* o = new Fl_Group(370, 30, 350, 50); + o->box(FL_THIN_DOWN_BOX); + o->color(FL_GRAY0); + o->selection_color((Fl_Color)218); + o->labelcolor(FL_GREEN); + OscilSpectrum *spc=new OscilSpectrum (o->x(),o->y(),o->w(),o->h(),""); + spc->init(oscil,1,master); + o->end(); + } // Fl_Group* o + { bfparval = new Fl_Value_Output(490, 285, 25, 15, "Par."); + bfparval->labelsize(12); + bfparval->minimum(-63); + bfparval->maximum(63); + bfparval->step(1); + } // Fl_Value_Output* bfparval + { basefuncmodulation = new Fl_Group(550, 276, 169, 25); + basefuncmodulation->box(FL_ENGRAVED_BOX); + { bfmodtype = new Fl_Choice(599, 281, 50, 15, "B.F.Mod."); + bfmodtype->tooltip("Base function modulation"); + bfmodtype->down_box(FL_BORDER_BOX); + bfmodtype->labelsize(10); + bfmodtype->textsize(10); + bfmodtype->callback((Fl_Callback*)cb_bfmodtype); + bfmodtype->menu(menu_bfmodtype); + } // Fl_Choice* bfmodtype + { bfmodpar1 = new WidgetPDial(659, 281, 15, 15); + bfmodpar1->tooltip("Oscillator\'s modulation parameter 1"); + bfmodpar1->box(FL_OVAL_BOX); + bfmodpar1->color(FL_BACKGROUND_COLOR); + bfmodpar1->selection_color(FL_INACTIVE_COLOR); + bfmodpar1->labeltype(FL_NORMAL_LABEL); + bfmodpar1->labelfont(0); + bfmodpar1->labelsize(14); + bfmodpar1->labelcolor(FL_FOREGROUND_COLOR); + bfmodpar1->maximum(127); + bfmodpar1->step(1); + bfmodpar1->callback((Fl_Callback*)cb_bfmodpar1); + bfmodpar1->align(FL_ALIGN_BOTTOM); + bfmodpar1->when(FL_WHEN_CHANGED); + } // WidgetPDial* bfmodpar1 + { bfmodpar2 = new WidgetPDial(679, 281, 15, 15); + bfmodpar2->tooltip("Oscillator\'s modulation parameter 2"); + bfmodpar2->box(FL_OVAL_BOX); + bfmodpar2->color(FL_BACKGROUND_COLOR); + bfmodpar2->selection_color(FL_INACTIVE_COLOR); + bfmodpar2->labeltype(FL_NORMAL_LABEL); + bfmodpar2->labelfont(0); + bfmodpar2->labelsize(14); + bfmodpar2->labelcolor(FL_FOREGROUND_COLOR); + bfmodpar2->maximum(127); + bfmodpar2->step(1); + bfmodpar2->callback((Fl_Callback*)cb_bfmodpar2); + bfmodpar2->align(FL_ALIGN_BOTTOM); + bfmodpar2->when(FL_WHEN_CHANGED); + } // WidgetPDial* bfmodpar2 + { bfmodpar3 = new WidgetPDial(699, 281, 15, 15); + bfmodpar3->tooltip("Oscillator\'s modulation parameter 3"); + bfmodpar3->box(FL_OVAL_BOX); + bfmodpar3->color(FL_BACKGROUND_COLOR); + bfmodpar3->selection_color(FL_INACTIVE_COLOR); + bfmodpar3->labeltype(FL_NORMAL_LABEL); + bfmodpar3->labelfont(0); + bfmodpar3->labelsize(14); + bfmodpar3->labelcolor(FL_FOREGROUND_COLOR); + bfmodpar3->maximum(127); + bfmodpar3->step(1); + bfmodpar3->callback((Fl_Callback*)cb_bfmodpar3); + bfmodpar3->align(FL_ALIGN_BOTTOM); + bfmodpar3->when(FL_WHEN_CHANGED); + } // WidgetPDial* bfmodpar3 + if ((oscil->Pcurrentbasefunc==0)||(oscil->Pcurrentbasefunc==127)) basefuncmodulation->deactivate(); + basefuncmodulation->end(); + } // Fl_Group* basefuncmodulation + basefuncdisplaygroup->end(); + } // Fl_Group* basefuncdisplaygroup + { magtype = new Fl_Choice(70, 280, 65, 20, "Mag.Type"); + magtype->down_box(FL_BORDER_BOX); + magtype->labelsize(11); + magtype->textsize(11); + magtype->callback((Fl_Callback*)cb_magtype); + magtype->menu(menu_magtype); + } // Fl_Choice* magtype + { Fl_Button* o = new Fl_Button(5, 313, 85, 20, "Use as base"); + o->tooltip("Use this Oscillator as base function"); + o->box(FL_THIN_UP_BOX); + o->labelfont(1); + o->labelsize(11); + o->callback((Fl_Callback*)cb_Use); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(668, 565, 62, 25, "Close"); + o->box(FL_THIN_UP_BOX); + o->callback((Fl_Callback*)cb_Close); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(670, 505, 55, 15, "Clear"); + o->box(FL_THIN_UP_BOX); + o->labelfont(1); + o->labelsize(11); + o->callback((Fl_Callback*)cb_Clear); + } // Fl_Button* o + { Fl_Group* o = new Fl_Group(135, 308, 150, 30); + o->box(FL_ENGRAVED_BOX); + { wshbutton = new Fl_Choice(165, 313, 55, 20, "Wsh."); + wshbutton->tooltip("Waveshaping function"); + wshbutton->down_box(FL_BORDER_BOX); + wshbutton->labelsize(10); + wshbutton->textsize(10); + wshbutton->callback((Fl_Callback*)cb_wshbutton); + wshbutton->menu(menu_wshbutton); + } // Fl_Choice* wshbutton + { wshpar = new WidgetPDial(260, 313, 20, 20); + wshpar->tooltip("Waveshaping Parameter"); + wshpar->box(FL_OVAL_BOX); + wshpar->color(FL_BACKGROUND_COLOR); + wshpar->selection_color(FL_INACTIVE_COLOR); + wshpar->labeltype(FL_NORMAL_LABEL); + wshpar->labelfont(0); + wshpar->labelsize(14); + wshpar->labelcolor(FL_FOREGROUND_COLOR); + wshpar->minimum(-64); + wshpar->maximum(63); + wshpar->step(1); + wshpar->callback((Fl_Callback*)cb_wshpar); + wshpar->align(FL_ALIGN_BOTTOM); + wshpar->when(FL_WHEN_CHANGED); + } // WidgetPDial* wshpar + { wsparval = new Fl_Value_Output(228, 316, 25, 15); + wsparval->labelsize(12); + wsparval->minimum(-63); + wsparval->maximum(63); + wsparval->step(1); + } // Fl_Value_Output* wsparval + o->end(); + } // Fl_Group* o + { autoclearbutton = new Fl_Light_Button(95, 313, 35, 20, "Clr."); + autoclearbutton->tooltip("Auto clear when using the oscillator as base function"); + autoclearbutton->box(FL_THIN_UP_BOX); + autoclearbutton->value(1); + autoclearbutton->labelfont(1); + autoclearbutton->labelsize(10); + } // Fl_Light_Button* autoclearbutton + { Fl_Group* o = new Fl_Group(285, 308, 155, 30); + o->box(FL_ENGRAVED_BOX); + { fltbutton = new Fl_Choice(315, 313, 50, 20, "Filter"); + fltbutton->tooltip("Oscillator\'s filter type"); + fltbutton->down_box(FL_BORDER_BOX); + fltbutton->labelsize(10); + fltbutton->textsize(10); + fltbutton->callback((Fl_Callback*)cb_fltbutton); + fltbutton->menu(menu_fltbutton); + } // Fl_Choice* fltbutton + { filtervalue1 = new WidgetPDial(367, 313, 20, 20); + filtervalue1->tooltip("Oscillator\'s filter parameter1"); + filtervalue1->box(FL_OVAL_BOX); + filtervalue1->color(FL_BACKGROUND_COLOR); + filtervalue1->selection_color(FL_INACTIVE_COLOR); + filtervalue1->labeltype(FL_NORMAL_LABEL); + filtervalue1->labelfont(0); + filtervalue1->labelsize(14); + filtervalue1->labelcolor(FL_FOREGROUND_COLOR); + filtervalue1->maximum(127); + filtervalue1->step(1); + filtervalue1->callback((Fl_Callback*)cb_filtervalue1); + filtervalue1->align(FL_ALIGN_BOTTOM); + filtervalue1->when(FL_WHEN_CHANGED); + } // WidgetPDial* filtervalue1 + { filterpref = new Fl_Check_Button(415, 313, 20, 20, "p"); + filterpref->tooltip("Apply the filter before the waveshaping"); + filterpref->down_box(FL_DOWN_BOX); + filterpref->labelsize(10); + filterpref->callback((Fl_Callback*)cb_filterpref); + filterpref->align(FL_ALIGN_RIGHT|FL_ALIGN_INSIDE); + } // Fl_Check_Button* filterpref + { filtervalue2 = new WidgetPDial(392, 313, 20, 20); + filtervalue2->tooltip("Oscillator\'s filter parameter2"); + filtervalue2->box(FL_OVAL_BOX); + filtervalue2->color(FL_BACKGROUND_COLOR); + filtervalue2->selection_color(FL_INACTIVE_COLOR); + filtervalue2->labeltype(FL_NORMAL_LABEL); + filtervalue2->labelfont(0); + filtervalue2->labelsize(14); + filtervalue2->labelcolor(FL_FOREGROUND_COLOR); + filtervalue2->maximum(127); + filtervalue2->step(1); + filtervalue2->callback((Fl_Callback*)cb_filtervalue2); + filtervalue2->align(FL_ALIGN_BOTTOM); + filtervalue2->when(FL_WHEN_CHANGED); + } // WidgetPDial* filtervalue2 + o->end(); + } // Fl_Group* o + { Fl_Group* o = new Fl_Group(590, 308, 135, 30); + o->box(FL_ENGRAVED_BOX); + { sabutton = new Fl_Choice(630, 313, 60, 20, "Sp.adj."); + sabutton->tooltip("Oscillator\'s spectrum adjust"); + sabutton->down_box(FL_BORDER_BOX); + sabutton->labelsize(10); + sabutton->textsize(10); + sabutton->callback((Fl_Callback*)cb_sabutton); + sabutton->menu(menu_sabutton); + } // Fl_Choice* sabutton + { sadjpar = new WidgetPDial(695, 313, 20, 20); + sadjpar->tooltip("Oscillator\'s spectrum adjust parameter"); + sadjpar->box(FL_OVAL_BOX); + sadjpar->color(FL_BACKGROUND_COLOR); + sadjpar->selection_color(FL_INACTIVE_COLOR); + sadjpar->labeltype(FL_NORMAL_LABEL); + sadjpar->labelfont(0); + sadjpar->labelsize(14); + sadjpar->labelcolor(FL_FOREGROUND_COLOR); + sadjpar->maximum(127); + sadjpar->step(1); + sadjpar->callback((Fl_Callback*)cb_sadjpar); + sadjpar->align(FL_ALIGN_BOTTOM); + sadjpar->when(FL_WHEN_CHANGED); + } // WidgetPDial* sadjpar + o->end(); + } // Fl_Group* o + { Fl_Group* o = new Fl_Group(665, 340, 65, 65); + o->box(FL_ENGRAVED_BOX); + { harmonicshiftcounter = new Fl_Counter(670, 365, 55, 15, "Harmonic Shift"); + harmonicshiftcounter->type(1); + harmonicshiftcounter->labelsize(10); + harmonicshiftcounter->minimum(-64); + harmonicshiftcounter->maximum(64); + harmonicshiftcounter->step(1); + harmonicshiftcounter->textfont(1); + harmonicshiftcounter->textsize(10); + harmonicshiftcounter->callback((Fl_Callback*)cb_harmonicshiftcounter); + harmonicshiftcounter->align(129); + } // Fl_Counter* harmonicshiftcounter + { harmonicshiftpre = new Fl_Check_Button(690, 385, 34, 15, "preH"); + harmonicshiftpre->tooltip("Apply the harmonic shift before the waveshaping and filtering"); + harmonicshiftpre->down_box(FL_DOWN_BOX); + harmonicshiftpre->labelsize(10); + harmonicshiftpre->callback((Fl_Callback*)cb_harmonicshiftpre); + harmonicshiftpre->align(FL_ALIGN_RIGHT|FL_ALIGN_INSIDE); + } // Fl_Check_Button* harmonicshiftpre + { Fl_Button* o = new Fl_Button(670, 385, 20, 15, "R"); + o->box(FL_THIN_UP_BOX); + o->labelfont(1); + o->labelsize(10); + o->callback((Fl_Callback*)cb_R); + } // Fl_Button* o + o->end(); + } // Fl_Group* o + { Fl_Group* o = new Fl_Group(665, 410, 65, 90); + o->box(FL_ENGRAVED_FRAME); + { adhrtype = new Fl_Choice(670, 425, 55, 15, "Adpt.Harm."); + adhrtype->tooltip("The type of the addaptive harmonics"); + adhrtype->down_box(FL_BORDER_BOX); + adhrtype->labelsize(10); + adhrtype->textsize(10); + adhrtype->callback((Fl_Callback*)cb_adhrtype); + adhrtype->align(129); + adhrtype->when(FL_WHEN_RELEASE_ALWAYS); + adhrtype->menu(menu_adhrtype); + } // Fl_Choice* adhrtype + { adhrpow = new WidgetPDial(700, 460, 25, 25, "pow"); + adhrpow->tooltip("Adaptive harmonics power"); + adhrpow->box(FL_OVAL_BOX); + adhrpow->color(FL_BACKGROUND_COLOR); + adhrpow->selection_color(FL_INACTIVE_COLOR); + adhrpow->labeltype(FL_NORMAL_LABEL); + adhrpow->labelfont(0); + adhrpow->labelsize(10); + adhrpow->labelcolor(FL_FOREGROUND_COLOR); + adhrpow->maximum(200); + adhrpow->step(1); + adhrpow->callback((Fl_Callback*)cb_adhrpow); + adhrpow->align(FL_ALIGN_BOTTOM); + adhrpow->when(FL_WHEN_CHANGED); + } // WidgetPDial* adhrpow + { adhrbf = new WidgetPDial(670, 460, 25, 25, "baseF"); + adhrbf->tooltip("Adaptive harmonics base frequency"); + adhrbf->box(FL_OVAL_BOX); + adhrbf->color(FL_BACKGROUND_COLOR); + adhrbf->selection_color(FL_INACTIVE_COLOR); + adhrbf->labeltype(FL_NORMAL_LABEL); + adhrbf->labelfont(0); + adhrbf->labelsize(10); + adhrbf->labelcolor(FL_FOREGROUND_COLOR); + adhrbf->maximum(255); + adhrbf->step(1); + adhrbf->callback((Fl_Callback*)cb_adhrbf); + adhrbf->align(FL_ALIGN_BOTTOM); + adhrbf->when(FL_WHEN_CHANGED); + } // WidgetPDial* adhrbf + { adhrpar = new Fl_Slider(670, 445, 55, 10); + adhrpar->type(5); + adhrpar->box(FL_FLAT_BOX); + adhrpar->maximum(100); + adhrpar->step(1); + adhrpar->value(50); + adhrpar->callback((Fl_Callback*)cb_adhrpar); + } // Fl_Slider* adhrpar + o->end(); + } // Fl_Group* o + { Fl_Group* o = new Fl_Group(440, 308, 150, 30); + o->box(FL_ENGRAVED_BOX); + { modtype = new Fl_Choice(470, 315, 50, 15, "Mod."); + modtype->tooltip("modulation"); + modtype->down_box(FL_BORDER_BOX); + modtype->labelsize(10); + modtype->textsize(10); + modtype->callback((Fl_Callback*)cb_modtype); + modtype->menu(menu_modtype); + } // Fl_Choice* modtype + { modpar1 = new WidgetPDial(530, 315, 15, 15); + modpar1->tooltip("Oscillator\'s modulation parameter 1"); + modpar1->box(FL_OVAL_BOX); + modpar1->color(FL_BACKGROUND_COLOR); + modpar1->selection_color(FL_INACTIVE_COLOR); + modpar1->labeltype(FL_NORMAL_LABEL); + modpar1->labelfont(0); + modpar1->labelsize(14); + modpar1->labelcolor(FL_FOREGROUND_COLOR); + modpar1->maximum(127); + modpar1->step(1); + modpar1->callback((Fl_Callback*)cb_modpar1); + modpar1->align(FL_ALIGN_BOTTOM); + modpar1->when(FL_WHEN_CHANGED); + } // WidgetPDial* modpar1 + { modpar2 = new WidgetPDial(550, 315, 15, 15); + modpar2->tooltip("Oscillator\'s modulation parameter 2"); + modpar2->box(FL_OVAL_BOX); + modpar2->color(FL_BACKGROUND_COLOR); + modpar2->selection_color(FL_INACTIVE_COLOR); + modpar2->labeltype(FL_NORMAL_LABEL); + modpar2->labelfont(0); + modpar2->labelsize(14); + modpar2->labelcolor(FL_FOREGROUND_COLOR); + modpar2->maximum(127); + modpar2->step(1); + modpar2->callback((Fl_Callback*)cb_modpar2); + modpar2->align(FL_ALIGN_BOTTOM); + modpar2->when(FL_WHEN_CHANGED); + } // WidgetPDial* modpar2 + { modpar3 = new WidgetPDial(570, 315, 15, 15); + modpar3->tooltip("Oscillator\'s modulation parameter 3"); + modpar3->box(FL_OVAL_BOX); + modpar3->color(FL_BACKGROUND_COLOR); + modpar3->selection_color(FL_INACTIVE_COLOR); + modpar3->labeltype(FL_NORMAL_LABEL); + modpar3->labelfont(0); + modpar3->labelsize(14); + modpar3->labelcolor(FL_FOREGROUND_COLOR); + modpar3->maximum(127); + modpar3->step(1); + modpar3->callback((Fl_Callback*)cb_modpar3); + modpar3->align(FL_ALIGN_BOTTOM); + modpar3->when(FL_WHEN_CHANGED); + } // WidgetPDial* modpar3 + o->end(); + } // Fl_Group* o + { Fl_Button* o = new Fl_Button(670, 525, 55, 15, "Sine"); + o->box(FL_THIN_UP_BOX); + o->labelfont(1); + o->labelsize(11); + o->callback((Fl_Callback*)cb_Sine); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(670, 545, 25, 15, "C"); + o->box(FL_THIN_UP_BOX); + o->color((Fl_Color)179); + o->labelfont(1); + o->labelsize(11); + o->labelcolor(FL_BACKGROUND2_COLOR); + o->callback((Fl_Callback*)cb_C); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(700, 545, 25, 15, "P"); + o->box(FL_THIN_UP_BOX); + o->color((Fl_Color)179); + o->labelfont(1); + o->labelsize(11); + o->labelcolor(FL_BACKGROUND2_COLOR); + o->callback((Fl_Callback*)cb_P); + } // Fl_Button* o + { _this_has_to_be_the_last = new Fl_Scroll(5, 340, 660, 250); + _this_has_to_be_the_last->type(1); + _this_has_to_be_the_last->box(FL_ENGRAVED_BOX); + { Fl_Pack* o = harmonics = new Fl_Pack(10, 345, 650, 225); + harmonics->type(1); + for (int i=0;ih(),"");h[i]->init(oscil,i,oscildisplaygroup,oldosc,cbwidget,applybutton,master);} + harmonics->end(); + } // Fl_Pack* harmonics + _this_has_to_be_the_last->end(); + } // Fl_Scroll* _this_has_to_be_the_last + if (oscil->ADvsPAD) o->label("PADsynth Harmonic Content Editor"); + osceditUI->end(); + } // Fl_Double_Window* osceditUI + return osceditUI; +} + +OscilEditor::OscilEditor(OscilGen *oscil_,Fl_Widget *oldosc_,Fl_Widget *cbwidget_,Fl_Widget *cbapplywidget_,Master *master_) { + oscil=oscil_; +oldosc=oldosc_; +cbwidget=cbwidget_; +cbapplywidget=cbapplywidget_; +master=master_; + +make_window(); + +refresh(); +osceditUI->show(); +} + +OscilEditor::~OscilEditor() { + osceditUI->hide(); +//for (int i=0;ivalue(oscil->Phmagtype); +rndslider->value(oscil->Prand-64); + +hrndtype->value(oscil->Pamprandtype); +hrnddial->value(oscil->Pamprandpower); + +bftype->value(oscil->Pcurrentbasefunc); +bfparval->value(oscil->Pbasefuncpar-64); +bfslider->value(oscil->Pbasefuncpar-64); + +bfmodtype->value(oscil->Pbasefuncmodulation); +bfmodpar1->value(oscil->Pbasefuncmodulationpar1); +bfmodpar2->value(oscil->Pbasefuncmodulationpar2); +bfmodpar3->value(oscil->Pbasefuncmodulationpar3); + +wshbutton->value(oscil->Pwaveshapingfunction); +wsparval->value(oscil->Pwaveshaping-64); +wshpar->value(oscil->Pwaveshaping-64); + +fltbutton->value(oscil->Pfiltertype); +filtervalue1->value(oscil->Pfilterpar1); +filtervalue2->value(oscil->Pfilterpar2); +filterpref->value(oscil->Pfilterbeforews); + +modtype->value(oscil->Pmodulation); +modpar1->value(oscil->Pmodulationpar1); +modpar2->value(oscil->Pmodulationpar2); +modpar3->value(oscil->Pmodulationpar3); + +sabutton->value(oscil->Psatype); +sadjpar->value(oscil->Psapar); + +harmonicshiftcounter->value(oscil->Pharmonicshift); +harmonicshiftpre->value(oscil->Pharmonicshiftfirst); + +adhrtype->value(oscil->Padaptiveharmonics); +adhrbf->value(oscil->Padaptiveharmonicsbasefreq); +adhrpow->value(oscil->Padaptiveharmonicspower); +adhrtype->value(oscil->Padaptiveharmonicspar); + +for (int i=0;irefresh(); + +pthread_mutex_lock(&master->mutex); + oscil->prepare(); +pthread_mutex_unlock(&master->mutex); + +basefuncdisplaygroup->redraw(); +redrawoscil(); +} + +void OscilEditor::redrawoscil() { + oscildisplaygroup->redraw(); +oldosc->redraw(); +if (cbwidget!=NULL) { + cbwidget->do_callback(); + applybutton->color(FL_RED); + applybutton->redraw(); +}; +} diff --git a/plugins/zynaddsubfx/src/UI/OscilGenUI.fl b/plugins/zynaddsubfx/src/UI/OscilGenUI.fl new file mode 100644 index 000000000..4d15dc8a0 --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/OscilGenUI.fl @@ -0,0 +1,1133 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0109 +header_name {.h} +code_name {.cc} +decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} + +decl {//License: GNU GPL version 2 or later} {} + +decl {\#include "../Synth/OscilGen.h"} {public +} + +decl {\#include "../Misc/Util.h"} {public +} + +decl {\#include "../Misc/Master.h"} {public +} + +decl {\#include "ResonanceUI.h"} {public +} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include } {} + +decl {\#include } {} + +decl {\#include } {} + +decl {\#include } {} + +decl {\#include "WidgetPDial.h"} {public +} + +decl {\#include "EnvelopeUI.h"} {public +} + +decl {\#include "LFOUI.h"} {public +} + +decl {\#include "FilterUI.h"} {public +} + +decl {\#include "PresetsUI.h"} {public +} + +class OscilSpectrum {: {public Fl_Box} +} { + Function {OscilSpectrum(int x,int y, int w, int h, const char *label=0):Fl_Box(x,y,w,h,label)} {} { + code {oscil=NULL;} {} + } + Function {init(OscilGen *oscil_,int oscbase_,Master *master_)} {} { + code {oscil=oscil_; +oscbase=oscbase_; +master=master_;} {} + } + Function {draw()} {} { + code {int ox=x(),oy=y(),lx=w(),ly=h(),i; +const int maxdb=60;//must be multiple of 10 +int GX=2; +int n=lx/GX-1; +if (n>OSCIL_SIZE/2) n=OSCIL_SIZE/2; + +REALTYPE x; +REALTYPE* spc=new REALTYPE[n]; +for (i=0;imutex); +if (oscbase==0) oscil->getspectrum(n,spc,0); + else oscil->getspectrum(n,spc,1); +pthread_mutex_unlock(&master->mutex); + +//normalize +REALTYPE max=0; +for (i=0;iactive_r()) fl_color(this->parent()->selection_color()); + else fl_color(this->parent()->color()); +fl_line_style(FL_DOT); + +for (i=1;iactive_r()) fl_color(this->parent()->labelcolor()); + else fl_color(this->parent()->color()); +fl_line_style(0); + +//draws the spectrum +for (i=0;idB2rap(-maxdb)) x=rap2dB(x)/maxdb+1; + else x=0; + + int val=(int) ((ly-2)*x); + if (val>0) fl_line(ox+tmp,oy+ly-2-val,ox+tmp,oy+ly-2); +} +delete [] spc;} {selected + } + } + decl {OscilGen *oscil;} {} + decl {int oscbase;} {} + decl {Master *master;} {} +} + +class PSlider {: {public Fl_Slider} +} { + Function {PSlider(int x,int y, int w, int h, const char *label=0):Fl_Slider(x,y,w,h,label)} {} {} + Function {handle(int event)} {return_type int + } { + code {int X=x(),Y=y(),W=w(),H=h(); + +if ((!Fl::event_buttons())|| (event==0)||(Fl::event_shift()==0)) return(Fl_Slider::handle(event)); + +if (!Fl::event_inside(X,Y,W,H)) { + if (event==FL_DRAG){ + Fl_Slider::handle(FL_RELEASE); + Fl_Slider::handle(FL_LEAVE); + deactivate(); + activate(); + return(1); + }else{ + return(Fl_Slider::handle(event)); + }; +} else { + //Fl_Slider::handle(FL_FOCUS); + Fl_Slider::handle(FL_PUSH); +}; + +return(1);} {} + } +} + +class Oscilloscope {: {public Fl_Box} +} { + Function {Oscilloscope(int x,int y, int w, int h, const char *label=0):Fl_Box(x,y,w,h,label)} {} { + code {oscil=NULL; +phase=64; +oscbase=0;} {} + } + Function {init(OscilGen *oscil_,Master *master_)} {} { + code {oscil=oscil_; +master=master_;} {} + } + Function {init(OscilGen *oscil_,int oscbase_,Master *master_)} {} { + code {oscil=oscil_; +oscbase=oscbase_; +master=master_;} {} + } + Function {init(OscilGen *oscil_,int oscbase_,int phase_,Master *master_)} {} { + code {oscil=oscil_; +oscbase=oscbase_; +phase=phase_; +master=master_;} {} + } + Function {draw()} {} { + code {int ox=x(),oy=y(),lx=w(),ly=h()-1,i; +REALTYPE smps[OSCIL_SIZE]; +pthread_mutex_lock(&master->mutex); +if (oscbase==0) oscil->get(smps,-1.0); + else oscil->getcurrentbasefunction(smps); +pthread_mutex_unlock(&master->mutex); + +if (damage()!=1){ + fl_color(0,0,0); + fl_rectf(ox,oy,lx,ly); +}; + +//normalize +REALTYPE max=0; +for (i=0;iactive_r()) fl_color(this->parent()->labelcolor()); + else fl_color(this->parent()->color()); +int GX=16;if (lxactive_r()) fl_color(this->parent()->selection_color()); + else fl_color(this->parent()->labelcolor()); +int lw=1; +//if ((lx<135)||(ly<135)) lw=1; +fl_line_style(0,lw); +int ph=(int)((phase-64.0)/128.0*OSCIL_SIZE+OSCIL_SIZE); +for (i=1;ivalue(x); + else x=127-(int)o->value(); +if (x==64) o->selection_color(0); + else o->selection_color(222); + +pthread_mutex_lock(&master->mutex); + oscil->Phmag[n]=x; + if (x==64) { + oscil->Phphase[n]=64; + phase->value(64); + }; + oscil->prepare(); +pthread_mutex_unlock(&master->mutex); + +display->redraw(); +oldosc->redraw(); +if (cbwidget!=NULL) { + cbwidget->do_callback(); + applybutton->color(FL_RED); + applybutton->redraw(); +};} + xywh {0 15 15 115} type {Vert Knob} box FLAT_BOX selection_color 222 maximum 127 step 1 value 64 + code0 {o->value(127-oscil->Phmag[n]);} + code1 {if (oscil->Phmag[n]==64) o->selection_color(0);} + class PSlider + } + Fl_Slider phase { + callback {int x=64; +if (Fl::event_button3()) o->value(x); + else x=(int)o->value(); + +pthread_mutex_lock(&master->mutex); + oscil->Phphase[n]=x; + oscil->prepare(); +pthread_mutex_unlock(&master->mutex); + +display->redraw(); +oldosc->redraw(); +if (cbwidget!=NULL) { + cbwidget->do_callback(); + applybutton->color(FL_RED); + applybutton->redraw(); +};} + xywh {0 135 15 75} type {Vert Knob} box FLAT_BOX selection_color 222 maximum 127 step 1 value 64 + code0 {o->value(oscil->Phphase[n]);} + class PSlider + } + Fl_Box {} { + xywh {15 70 5 5} box FLAT_BOX color 45 + } + Fl_Box {} { + xywh {15 170 5 5} box FLAT_BOX color 45 + } + Fl_Box {} { + label 01 + xywh {0 210 20 15} labelfont 1 labelsize 9 align 20 + code0 {char tmp[10];snprintf(tmp,10,"%d",n+1);o->label(strdup(tmp));} + } + Fl_Box {} { + label 01 + xywh {0 0 20 15} labelfont 1 labelsize 9 align 20 + code0 {char tmp[10];snprintf(tmp,10,"%d",n+1);o->label(strdup(tmp));} + } + } + } + Function {Oscilharmonic(int x,int y, int w, int h, const char *label=0):Fl_Group(x,y,w,h,label)} {} { + code {n=0; +oscil=NULL; +display=NULL; +applybutton=NULL; +cbwidget=NULL;} {} + } + Function {init(OscilGen *oscil_,int n_,Fl_Group *display_,Fl_Widget *oldosc_,Fl_Widget *cbwidget_,Fl_Widget *applybutton_, Master *master_)} {} { + code {oscil=oscil_; +n=n_; +display=display_; +master=master_; +oldosc=oldosc_; +cbwidget=cbwidget_; +applybutton=applybutton_; +make_window(); +end(); +harmonic->show();} {} + } + Function {refresh()} {} { + code {mag->value(127-oscil->Phmag[n]); +phase->value(oscil->Phphase[n]); + +if (oscil->Phmag[n]==64) mag->selection_color(0); + else mag->selection_color(222);} {} + } + Function {~Oscilharmonic()} {} { + code {harmonic->hide(); +//delete(harmonic);} {} + } + decl {OscilGen *oscil;} {} + decl {Fl_Group *display;} {} + decl {int n;} {} + decl {Fl_Widget *oldosc,*cbwidget,*applybutton;} {} + decl {Master *master;} {} +} + +class OscilEditor {: {public PresetsUI_} +} { + Function {make_window()} {} { + Fl_Window osceditUI { + label {ADsynth Oscillator Editor} + xywh {131 90 735 595} type Double hide + code0 {if (oscil->ADvsPAD) o->label("PADsynth Harmonic Content Editor");} + } { + Fl_Button applybutton { + label Apply + callback {applybutton->color(FL_GRAY); +applybutton->redraw(); +if (cbapplywidget!=NULL) { + cbapplywidget->do_callback(); + cbapplywidget->color(FL_GRAY); + cbapplywidget->redraw(); +};} + xywh {300 280 60 20} box THIN_UP_BOX labelfont 1 + code0 {if (!oscil->ADvsPAD) o->hide();} + } + Fl_Group oscildisplaygroup { + xywh {5 5 360 300} box ENGRAVED_FRAME + } { + Fl_Group {} {open + xywh {10 85 350 190} box THIN_DOWN_BOX color 32 selection_color 71 labelcolor 179 + code0 {Oscilloscope *osc=new Oscilloscope(o->x(),o->y(),o->w(),o->h(),"");} + code1 {osc->init(oscil,master);} + } {} + Fl_Box {} { + label Oscillator + xywh {120 10 110 20} box FLAT_BOX labelfont 1 + } + Fl_Value_Slider rndslider { + label rnd + callback {oscil->Prand=(int)o->value()+64; +oscildisplaygroup->redraw(); +oldosc->redraw();} + tooltip {Oscilator Phase Randomness: smaller than 0 is "group", larger than 0 is for each harmonic} xywh {140 285 100 10} type {Horz Knob} box FLAT_BOX labelsize 10 align 5 minimum -64 maximum 63 step 1 + code0 {if (oscil->ADvsPAD) o->hide();} + } + Fl_Group {} {open + xywh {10 30 350 50} box THIN_DOWN_BOX color 32 selection_color 218 labelcolor 63 + code0 {OscilSpectrum *spc=new OscilSpectrum(o->x(),o->y(),o->w(),o->h(),"");} + code1 {spc->init(oscil,0,master);} + } {} + Fl_Group {} { + xywh {246 277 115 25} box ENGRAVED_BOX + code0 {if (oscil->ADvsPAD) o->hide();} + } { + Fl_Choice hrndtype { + label {H.rnd} + callback {oscil->Pamprandtype=(int) o->value();} + tooltip {Harmonic Amplitude Randomness} xywh {281 282 50 15} down_box BORDER_BOX labelsize 10 textsize 10 + } { + MenuItem {} { + label None + xywh {60 60 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Pow + xywh {70 70 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Sin + xywh {80 80 100 20} labelfont 1 labelsize 10 + } + } + Fl_Dial hrnddial { + callback {oscil->Pamprandpower=(int) o->value();} + tooltip {Oscillator's spectrum adjust parameter} xywh {338 280 18 18} maximum 127 step 1 + class WidgetPDial + } + } + } + Fl_Box {} { + label {Base Func.} + xywh {495 15 110 20} box FLAT_BOX labelfont 1 + } + Fl_Group basefuncdisplaygroup { + xywh {365 5 360 300} box ENGRAVED_FRAME + } { + Fl_Group {} { + xywh {370 85 350 190} box THIN_DOWN_BOX color 32 selection_color 71 labelcolor 179 + code0 {Oscilloscope *osc=new Oscilloscope(o->x(),o->y(),o->w(),o->h(),"");} + code1 {osc->init(oscil,1,master);} + } {} + Fl_Dial bfslider { + callback {oscil->Pbasefuncpar=(int)o->value()+64; +basefuncdisplaygroup->redraw(); +bfparval->value(oscil->Pbasefuncpar-64); + +redrawoscil();} + tooltip {Base Function Parameter} xywh {520 280 20 20} minimum -64 maximum 63 step 1 + class WidgetPDial + } + Fl_Choice bftype { + label {Base.F..} + callback {oscil->Pcurrentbasefunc=(int) o->value(); + +basefuncdisplaygroup->redraw(); +redrawoscil(); + +if ((oscil->Pcurrentbasefunc==0)||(oscil->Pcurrentbasefunc==127)) basefuncmodulation->deactivate(); + else basefuncmodulation->activate();} + xywh {370 285 90 15} down_box BORDER_BOX labelsize 10 align 5 textsize 11 + } { + MenuItem {} { + label Sine + xywh {10 10 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label Triangle + xywh {20 20 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label Pulse + xywh {30 30 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label Saw + xywh {40 40 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label Power + xywh {50 50 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label Gauss + xywh {50 50 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label Diode + xywh {60 60 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label AbsSine + xywh {70 70 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label PulseSine + xywh {80 80 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label StrchSine + xywh {90 90 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label Chirp + xywh {100 100 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label AbsStrSine + xywh {102 102 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label Chebyshev + xywh {112 112 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label Sqr + xywh {122 122 100 20} labelfont 1 labelsize 11 + } + } + Fl_Box {} { + label {Base Func.} + xywh {480 10 110 20} box FLAT_BOX labelfont 1 + } + Fl_Group {} {open + xywh {370 30 350 50} box THIN_DOWN_BOX color 32 selection_color 218 labelcolor 63 + code0 {OscilSpectrum *spc=new OscilSpectrum (o->x(),o->y(),o->w(),o->h(),"");} + code1 {spc->init(oscil,1,master);} + } {} + Fl_Value_Output bfparval { + label {Par.} + xywh {490 285 25 15} labelsize 12 minimum -63 maximum 63 step 1 + } + Fl_Group basefuncmodulation { + xywh {550 276 169 25} box ENGRAVED_BOX + code0 {if ((oscil->Pcurrentbasefunc==0)||(oscil->Pcurrentbasefunc==127)) basefuncmodulation->deactivate();} + } { + Fl_Choice bfmodtype { + label {B.F.Mod.} + callback {oscil->Pbasefuncmodulation=(int) o->value(); +basefuncdisplaygroup->redraw(); +redrawoscil();} + tooltip {Base function modulation} xywh {599 281 50 15} down_box BORDER_BOX labelsize 10 textsize 10 + } { + MenuItem {} { + label None + xywh {50 50 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Rev + xywh {60 60 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Sine + xywh {70 70 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Pow + xywh {80 80 100 20} labelfont 1 labelsize 10 + } + } + Fl_Dial bfmodpar1 { + callback {oscil->Pbasefuncmodulationpar1=(int)o->value(); +basefuncdisplaygroup->redraw(); +redrawoscil();} + tooltip {Oscillator's modulation parameter 1} xywh {659 281 15 15} maximum 127 step 1 + class WidgetPDial + } + Fl_Dial bfmodpar2 { + callback {oscil->Pbasefuncmodulationpar2=(int)o->value(); +basefuncdisplaygroup->redraw(); +redrawoscil();} + tooltip {Oscillator's modulation parameter 2} xywh {679 281 15 15} maximum 127 step 1 + class WidgetPDial + } + Fl_Dial bfmodpar3 { + callback {oscil->Pbasefuncmodulationpar3=(int)o->value(); +basefuncdisplaygroup->redraw(); +redrawoscil();} + tooltip {Oscillator's modulation parameter 3} xywh {699 281 15 15} maximum 127 step 1 + class WidgetPDial + } + } + } + Fl_Choice magtype { + label {Mag.Type} + callback {oscil->Phmagtype=(int) o->value(); +basefuncdisplaygroup->redraw(); + +redrawoscil();} + xywh {70 280 65 20} down_box BORDER_BOX labelsize 11 textsize 11 + } { + MenuItem {} { + label Linear + xywh {0 0 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label {-40dB} + xywh {10 10 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label {-60dB} + xywh {20 20 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label {-80dB} + xywh {30 30 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label {-100dB} + xywh {40 40 100 20} labelfont 1 labelsize 11 + } + } + Fl_Button {} { + label {Use as base} + callback {oscil->useasbase(); +if (autoclearbutton->value()){ + for (int i=0;imag->value(64); + oscil->Phmag[i]=64; + h[i]->phase->value(64); + oscil->Phphase[i]=64; + }; + oscil->Phmag[0]=127; + + oscil->Pharmonicshift=0; + harmonicshiftcounter->value(0); + + h[0]->mag->value(0); + wshbutton->value(0); + wshbutton->do_callback(); + fltbutton->value(0); + fltbutton->do_callback(); + sabutton->value(0); + sabutton->do_callback(); +}; + +pthread_mutex_lock(&master->mutex); + for (int i=0;iPhmag[i]==64) h[i]->mag->selection_color(0); + else h[i]->mag->selection_color(222); + }; + oscil->prepare(); +pthread_mutex_unlock(&master->mutex); + +basefuncdisplaygroup->redraw(); +redrawoscil();} + tooltip {Use this Oscillator as base function} xywh {5 313 85 20} box THIN_UP_BOX labelfont 1 labelsize 11 + } + Fl_Button {} { + label Close + callback {osceditUI->hide();} + xywh {668 565 62 25} box THIN_UP_BOX + } + Fl_Button {} { + label Clear + callback {if (!fl_choice("Clear the harmonics settings?","No","Yes",NULL)) return; + +for (int i=0;imag->value(64); + oscil->Phmag[i]=64; + h[i]->phase->value(64); + oscil->Phphase[i]=64; +}; +oscil->Phmag[0]=127; +h[0]->mag->value(0); + +for (int i=0;iPhmag[i]==64) h[i]->mag->selection_color(0); + else h[i]->mag->selection_color(222); +}; + +//harmonics->redraw(); + +pthread_mutex_lock(&master->mutex); + oscil->prepare(); +pthread_mutex_unlock(&master->mutex); + +redrawoscil();} + xywh {670 505 55 15} box THIN_UP_BOX labelfont 1 labelsize 11 + } + Fl_Group {} { + xywh {135 308 150 30} box ENGRAVED_BOX + } { + Fl_Choice wshbutton { + label {Wsh.} + callback {oscil->Pwaveshapingfunction=(int) o->value(); +basefuncdisplaygroup->redraw(); +redrawoscil();} open + tooltip {Waveshaping function} xywh {165 313 55 20} down_box BORDER_BOX labelsize 10 textsize 10 + } { + MenuItem {} { + label None + xywh {25 25 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Atan + xywh {35 35 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Asym1 + xywh {45 45 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Pow + xywh {55 55 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Sine + xywh {65 65 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Qnts + xywh {75 75 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Zigzg + xywh {85 85 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Lmt + xywh {95 95 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label LmtU + xywh {105 105 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label LmtL + xywh {115 115 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label ILmt + xywh {127 127 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Clip + xywh {137 137 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Asym2 + xywh {85 85 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Pow2 + xywh {95 95 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Sgm + xywh {90 90 100 20} labelfont 1 labelsize 10 + } + } + Fl_Dial wshpar { + callback {oscil->Pwaveshaping=(int)o->value()+64; +wsparval->value(oscil->Pwaveshaping-64); +redrawoscil();} + tooltip {Waveshaping Parameter} xywh {260 313 20 20} minimum -64 maximum 63 step 1 + class WidgetPDial + } + Fl_Value_Output wsparval { + xywh {228 316 25 15} labelsize 12 minimum -63 maximum 63 step 1 + } + } + Fl_Light_Button autoclearbutton { + label {Clr.} + tooltip {Auto clear when using the oscillator as base function} xywh {95 313 35 20} box THIN_UP_BOX value 1 labelfont 1 labelsize 10 + } + Fl_Group {} { + xywh {285 308 155 30} box ENGRAVED_BOX + } { + Fl_Choice fltbutton { + label Filter + callback {oscil->Pfiltertype=(int) o->value(); + +redrawoscil();} + tooltip {Oscillator's filter type} xywh {315 313 50 20} down_box BORDER_BOX labelsize 10 textsize 10 + } { + MenuItem {} { + label None + xywh {35 35 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label LP1 + xywh {45 45 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label HP1a + xywh {55 55 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label HP1b + xywh {65 65 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label BP1 + xywh {75 75 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label BS1 + xywh {85 85 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label LP2 + xywh {55 55 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label HP2 + xywh {65 65 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label BP2 + xywh {65 65 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label BS2 + xywh {75 75 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Cos + xywh {75 75 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Sin + xywh {85 85 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label LSh + xywh {95 95 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label S + xywh {105 105 100 20} labelfont 1 labelsize 10 + } + } + Fl_Dial filtervalue1 { + callback {oscil->Pfilterpar1=(int)o->value(); + +redrawoscil();} + tooltip {Oscillator's filter parameter1} xywh {367 313 20 20} maximum 127 step 1 + class WidgetPDial + } + Fl_Check_Button filterpref { + label p + callback {oscil->Pfilterbeforews=(int)o->value(); + +redrawoscil();} + tooltip {Apply the filter before the waveshaping} xywh {415 313 20 20} down_box DOWN_BOX labelsize 10 align 24 + } + Fl_Dial filtervalue2 { + callback {oscil->Pfilterpar2=(int)o->value(); + +redrawoscil();} + tooltip {Oscillator's filter parameter2} xywh {392 313 20 20} maximum 127 step 1 + class WidgetPDial + } + } + Fl_Group {} { + xywh {590 308 135 30} box ENGRAVED_BOX + } { + Fl_Choice sabutton { + label {Sp.adj.} + callback {oscil->Psatype=(int) o->value(); +redrawoscil();} + tooltip {Oscillator's spectrum adjust} xywh {630 313 60 20} down_box BORDER_BOX labelsize 10 textsize 10 + } { + MenuItem {} { + label None + xywh {55 55 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Pow + xywh {65 65 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label ThrsD + xywh {75 75 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label ThrsU + xywh {85 85 100 20} labelfont 1 labelsize 10 + } + } + Fl_Dial sadjpar { + callback {oscil->Psapar=(int)o->value(); +redrawoscil();} + tooltip {Oscillator's spectrum adjust parameter} xywh {695 313 20 20} maximum 127 step 1 + class WidgetPDial + } + } + Fl_Group {} { + xywh {665 340 65 65} box ENGRAVED_BOX + } { + Fl_Counter harmonicshiftcounter { + label {Harmonic Shift} + callback {oscil->Pharmonicshift=(int)o->value(); +redrawoscil();} + xywh {670 365 55 15} type Simple labelsize 10 align 129 minimum -64 maximum 64 step 1 textfont 1 textsize 10 + } + Fl_Check_Button harmonicshiftpre { + label preH + callback {oscil->Pharmonicshiftfirst=(int)o->value(); +redrawoscil();} + tooltip {Apply the harmonic shift before the waveshaping and filtering} xywh {690 385 34 15} down_box DOWN_BOX labelsize 10 align 24 + } + Fl_Button {} { + label R + callback {oscil->Pharmonicshift=0; +harmonicshiftcounter->value(0); +redrawoscil();} + xywh {670 385 20 15} box THIN_UP_BOX labelfont 1 labelsize 10 + } + } + Fl_Group {} { + xywh {665 410 65 90} box ENGRAVED_FRAME + } { + Fl_Choice adhrtype { + label {Adpt.Harm.} + callback {oscil->Padaptiveharmonics=(int) o->value(); +redrawoscil();} + tooltip {The type of the addaptive harmonics} xywh {670 425 55 15} down_box BORDER_BOX labelsize 10 align 129 when 6 textsize 10 + } { + MenuItem {} { + label OFF + xywh {80 80 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label ON + xywh {90 90 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Square + xywh {100 100 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label 2xSub + xywh {110 110 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label 2xAdd + xywh {120 120 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label 3xSub + xywh {120 120 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label 3xAdd + xywh {130 130 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label 4xSub + xywh {130 130 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label 4xAdd + xywh {140 140 100 20} labelfont 1 labelsize 10 + } + } + Fl_Dial adhrpow { + label pow + callback {oscil->Padaptiveharmonicspower=(int)o->value(); +redrawoscil();} + tooltip {Adaptive harmonics power} xywh {700 460 25 25} labelsize 10 maximum 200 step 1 + class WidgetPDial + } + Fl_Dial adhrbf { + label baseF + callback {oscil->Padaptiveharmonicsbasefreq=(int)o->value(); +redrawoscil();} + tooltip {Adaptive harmonics base frequency} xywh {670 460 25 25} labelsize 10 maximum 255 step 1 + class WidgetPDial + } + Fl_Slider adhrpar { + callback {oscil->Padaptiveharmonicspar=(int)o->value(); +redrawoscil();} + xywh {670 445 55 10} type {Horz Knob} box FLAT_BOX maximum 100 step 1 value 50 + } + } + Fl_Group {} { + xywh {440 308 150 30} box ENGRAVED_BOX + } { + Fl_Choice modtype { + label {Mod.} + callback {oscil->Pmodulation=(int) o->value(); + +redrawoscil();} + tooltip modulation xywh {470 315 50 15} down_box BORDER_BOX labelsize 10 textsize 10 + } { + MenuItem {} { + label None + xywh {60 60 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Rev + xywh {70 70 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Sine + xywh {80 80 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Pow + xywh {90 90 100 20} labelfont 1 labelsize 10 + } + } + Fl_Dial modpar1 { + callback {oscil->Pmodulationpar1=(int)o->value(); + +redrawoscil();} + tooltip {Oscillator's modulation parameter 1} xywh {530 315 15 15} maximum 127 step 1 + class WidgetPDial + } + Fl_Dial modpar2 { + callback {oscil->Pmodulationpar2=(int)o->value(); + +redrawoscil();} + tooltip {Oscillator's modulation parameter 2} xywh {550 315 15 15} maximum 127 step 1 + class WidgetPDial + } + Fl_Dial modpar3 { + callback {oscil->Pmodulationpar3=(int)o->value(); +redrawoscil();} + tooltip {Oscillator's modulation parameter 3} xywh {570 315 15 15} maximum 127 step 1 + class WidgetPDial + } + } + Fl_Button {} { + label Sine + callback {if (!fl_choice("Convert to SINE?","No","Yes",NULL)) return; + +pthread_mutex_lock(&master->mutex); + oscil->convert2sine(0); +pthread_mutex_unlock(&master->mutex); + +redrawoscil(); +refresh();} + xywh {670 525 55 15} box THIN_UP_BOX labelfont 1 labelsize 11 + } + Fl_Button {} { + label C + callback {presetsui->copy(oscil);} + xywh {670 545 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 11 labelcolor 7 + } + Fl_Button {} { + label P + callback {presetsui->paste(oscil,this);} + xywh {700 545 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 11 labelcolor 7 + } + Fl_Scroll _this_has_to_be_the_last { + xywh {5 340 660 250} type HORIZONTAL box ENGRAVED_BOX + } { + Fl_Pack harmonics {open + xywh {10 345 650 225} type HORIZONTAL + code0 {for (int i=0;ih(),"");h[i]->init(oscil,i,oscildisplaygroup,oldosc,cbwidget,applybutton,master);}} + } {} + } + } + } + Function {OscilEditor(OscilGen *oscil_,Fl_Widget *oldosc_,Fl_Widget *cbwidget_,Fl_Widget *cbapplywidget_,Master *master_)} {} { + code {oscil=oscil_; +oldosc=oldosc_; +cbwidget=cbwidget_; +cbapplywidget=cbapplywidget_; +master=master_; + +make_window(); + +refresh(); +osceditUI->show();} {} + } + Function {~OscilEditor()} {} { + code {osceditUI->hide(); +//for (int i=0;ivalue(oscil->Phmagtype); +rndslider->value(oscil->Prand-64); + +hrndtype->value(oscil->Pamprandtype); +hrnddial->value(oscil->Pamprandpower); + +bftype->value(oscil->Pcurrentbasefunc); +bfparval->value(oscil->Pbasefuncpar-64); +bfslider->value(oscil->Pbasefuncpar-64); + +bfmodtype->value(oscil->Pbasefuncmodulation); +bfmodpar1->value(oscil->Pbasefuncmodulationpar1); +bfmodpar2->value(oscil->Pbasefuncmodulationpar2); +bfmodpar3->value(oscil->Pbasefuncmodulationpar3); + +wshbutton->value(oscil->Pwaveshapingfunction); +wsparval->value(oscil->Pwaveshaping-64); +wshpar->value(oscil->Pwaveshaping-64); + +fltbutton->value(oscil->Pfiltertype); +filtervalue1->value(oscil->Pfilterpar1); +filtervalue2->value(oscil->Pfilterpar2); +filterpref->value(oscil->Pfilterbeforews); + +modtype->value(oscil->Pmodulation); +modpar1->value(oscil->Pmodulationpar1); +modpar2->value(oscil->Pmodulationpar2); +modpar3->value(oscil->Pmodulationpar3); + +sabutton->value(oscil->Psatype); +sadjpar->value(oscil->Psapar); + +harmonicshiftcounter->value(oscil->Pharmonicshift); +harmonicshiftpre->value(oscil->Pharmonicshiftfirst); + +adhrtype->value(oscil->Padaptiveharmonics); +adhrbf->value(oscil->Padaptiveharmonicsbasefreq); +adhrpow->value(oscil->Padaptiveharmonicspower); +adhrtype->value(oscil->Padaptiveharmonicspar); + +for (int i=0;irefresh(); + +pthread_mutex_lock(&master->mutex); + oscil->prepare(); +pthread_mutex_unlock(&master->mutex); + +basefuncdisplaygroup->redraw(); +redrawoscil();} {} + } + Function {redrawoscil()} {} { + code {oscildisplaygroup->redraw(); +oldosc->redraw(); +if (cbwidget!=NULL) { + cbwidget->do_callback(); + applybutton->color(FL_RED); + applybutton->redraw(); +};} {} + } + decl {OscilGen *oscil;} {} + decl {Fl_Widget *oldosc,*cbwidget,*cbapplywidget;} {} + decl {Oscilharmonic *h[MAX_AD_HARMONICS];} {} + decl {Master *master;} {} +} diff --git a/plugins/zynaddsubfx/src/UI/OscilGenUI.h b/plugins/zynaddsubfx/src/UI/OscilGenUI.h new file mode 100644 index 000000000..7ccf1c28f --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/OscilGenUI.h @@ -0,0 +1,281 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0109 + +#ifndef OscilGenUI_h +#define OscilGenUI_h +#include +#include "../Synth/OscilGen.h" +#include "../Misc/Util.h" +#include "../Misc/Master.h" +#include "ResonanceUI.h" +#include +#include +#include +#include "WidgetPDial.h" +#include "EnvelopeUI.h" +#include "LFOUI.h" +#include "FilterUI.h" +#include "PresetsUI.h" + +class OscilSpectrum : public Fl_Box { +public: + OscilSpectrum(int x,int y, int w, int h, const char *label=0); + void init(OscilGen *oscil_,int oscbase_,Master *master_); + void draw(); +private: + OscilGen *oscil; + int oscbase; + Master *master; +}; + +class PSlider : public Fl_Slider { +public: + PSlider(int x,int y, int w, int h, const char *label=0); + int handle(int event); +}; + +class Oscilloscope : public Fl_Box { +public: + Oscilloscope(int x,int y, int w, int h, const char *label=0); + void init(OscilGen *oscil_,Master *master_); + void init(OscilGen *oscil_,int oscbase_,Master *master_); + void init(OscilGen *oscil_,int oscbase_,int phase_,Master *master_); + void draw(); +private: + OscilGen *oscil; + int oscbase; +public: + int phase; +private: + Master *master; +}; +#include + +class Oscilharmonic : public Fl_Group { + Fl_Group* make_window(); + Fl_Group *harmonic; +public: + PSlider *mag; +private: + void cb_mag_i(PSlider*, void*); + static void cb_mag(PSlider*, void*); +public: + PSlider *phase; +private: + void cb_phase_i(PSlider*, void*); + static void cb_phase(PSlider*, void*); +public: + Oscilharmonic(int x,int y, int w, int h, const char *label=0); + void init(OscilGen *oscil_,int n_,Fl_Group *display_,Fl_Widget *oldosc_,Fl_Widget *cbwidget_,Fl_Widget *applybutton_, Master *master_); + void refresh(); + ~Oscilharmonic(); +private: + OscilGen *oscil; + Fl_Group *display; + int n; + Fl_Widget *oldosc,*cbwidget,*applybutton; + Master *master; +}; +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class OscilEditor : public PresetsUI_ { +public: + Fl_Double_Window* make_window(); + Fl_Double_Window *osceditUI; + Fl_Button *applybutton; +private: + void cb_applybutton_i(Fl_Button*, void*); + static void cb_applybutton(Fl_Button*, void*); +public: + Fl_Group *oscildisplaygroup; + Fl_Value_Slider *rndslider; +private: + void cb_rndslider_i(Fl_Value_Slider*, void*); + static void cb_rndslider(Fl_Value_Slider*, void*); +public: + Fl_Choice *hrndtype; +private: + void cb_hrndtype_i(Fl_Choice*, void*); + static void cb_hrndtype(Fl_Choice*, void*); + static Fl_Menu_Item menu_hrndtype[]; +public: + WidgetPDial *hrnddial; +private: + void cb_hrnddial_i(WidgetPDial*, void*); + static void cb_hrnddial(WidgetPDial*, void*); +public: + Fl_Group *basefuncdisplaygroup; + WidgetPDial *bfslider; +private: + void cb_bfslider_i(WidgetPDial*, void*); + static void cb_bfslider(WidgetPDial*, void*); +public: + Fl_Choice *bftype; +private: + void cb_bftype_i(Fl_Choice*, void*); + static void cb_bftype(Fl_Choice*, void*); + static Fl_Menu_Item menu_bftype[]; +public: + Fl_Value_Output *bfparval; + Fl_Group *basefuncmodulation; + Fl_Choice *bfmodtype; +private: + void cb_bfmodtype_i(Fl_Choice*, void*); + static void cb_bfmodtype(Fl_Choice*, void*); + static Fl_Menu_Item menu_bfmodtype[]; +public: + WidgetPDial *bfmodpar1; +private: + void cb_bfmodpar1_i(WidgetPDial*, void*); + static void cb_bfmodpar1(WidgetPDial*, void*); +public: + WidgetPDial *bfmodpar2; +private: + void cb_bfmodpar2_i(WidgetPDial*, void*); + static void cb_bfmodpar2(WidgetPDial*, void*); +public: + WidgetPDial *bfmodpar3; +private: + void cb_bfmodpar3_i(WidgetPDial*, void*); + static void cb_bfmodpar3(WidgetPDial*, void*); +public: + Fl_Choice *magtype; +private: + void cb_magtype_i(Fl_Choice*, void*); + static void cb_magtype(Fl_Choice*, void*); + static Fl_Menu_Item menu_magtype[]; + void cb_Use_i(Fl_Button*, void*); + static void cb_Use(Fl_Button*, void*); + void cb_Close_i(Fl_Button*, void*); + static void cb_Close(Fl_Button*, void*); + void cb_Clear_i(Fl_Button*, void*); + static void cb_Clear(Fl_Button*, void*); +public: + Fl_Choice *wshbutton; +private: + void cb_wshbutton_i(Fl_Choice*, void*); + static void cb_wshbutton(Fl_Choice*, void*); + static Fl_Menu_Item menu_wshbutton[]; +public: + WidgetPDial *wshpar; +private: + void cb_wshpar_i(WidgetPDial*, void*); + static void cb_wshpar(WidgetPDial*, void*); +public: + Fl_Value_Output *wsparval; + Fl_Light_Button *autoclearbutton; + Fl_Choice *fltbutton; +private: + void cb_fltbutton_i(Fl_Choice*, void*); + static void cb_fltbutton(Fl_Choice*, void*); + static Fl_Menu_Item menu_fltbutton[]; +public: + WidgetPDial *filtervalue1; +private: + void cb_filtervalue1_i(WidgetPDial*, void*); + static void cb_filtervalue1(WidgetPDial*, void*); +public: + Fl_Check_Button *filterpref; +private: + void cb_filterpref_i(Fl_Check_Button*, void*); + static void cb_filterpref(Fl_Check_Button*, void*); +public: + WidgetPDial *filtervalue2; +private: + void cb_filtervalue2_i(WidgetPDial*, void*); + static void cb_filtervalue2(WidgetPDial*, void*); +public: + Fl_Choice *sabutton; +private: + void cb_sabutton_i(Fl_Choice*, void*); + static void cb_sabutton(Fl_Choice*, void*); + static Fl_Menu_Item menu_sabutton[]; +public: + WidgetPDial *sadjpar; +private: + void cb_sadjpar_i(WidgetPDial*, void*); + static void cb_sadjpar(WidgetPDial*, void*); +public: + Fl_Counter *harmonicshiftcounter; +private: + void cb_harmonicshiftcounter_i(Fl_Counter*, void*); + static void cb_harmonicshiftcounter(Fl_Counter*, void*); +public: + Fl_Check_Button *harmonicshiftpre; +private: + void cb_harmonicshiftpre_i(Fl_Check_Button*, void*); + static void cb_harmonicshiftpre(Fl_Check_Button*, void*); + void cb_R_i(Fl_Button*, void*); + static void cb_R(Fl_Button*, void*); +public: + Fl_Choice *adhrtype; +private: + void cb_adhrtype_i(Fl_Choice*, void*); + static void cb_adhrtype(Fl_Choice*, void*); + static Fl_Menu_Item menu_adhrtype[]; +public: + WidgetPDial *adhrpow; +private: + void cb_adhrpow_i(WidgetPDial*, void*); + static void cb_adhrpow(WidgetPDial*, void*); +public: + WidgetPDial *adhrbf; +private: + void cb_adhrbf_i(WidgetPDial*, void*); + static void cb_adhrbf(WidgetPDial*, void*); +public: + Fl_Slider *adhrpar; +private: + void cb_adhrpar_i(Fl_Slider*, void*); + static void cb_adhrpar(Fl_Slider*, void*); +public: + Fl_Choice *modtype; +private: + void cb_modtype_i(Fl_Choice*, void*); + static void cb_modtype(Fl_Choice*, void*); + static Fl_Menu_Item menu_modtype[]; +public: + WidgetPDial *modpar1; +private: + void cb_modpar1_i(WidgetPDial*, void*); + static void cb_modpar1(WidgetPDial*, void*); +public: + WidgetPDial *modpar2; +private: + void cb_modpar2_i(WidgetPDial*, void*); + static void cb_modpar2(WidgetPDial*, void*); +public: + WidgetPDial *modpar3; +private: + void cb_modpar3_i(WidgetPDial*, void*); + static void cb_modpar3(WidgetPDial*, void*); + void cb_Sine_i(Fl_Button*, void*); + static void cb_Sine(Fl_Button*, void*); + void cb_C_i(Fl_Button*, void*); + static void cb_C(Fl_Button*, void*); + void cb_P_i(Fl_Button*, void*); + static void cb_P(Fl_Button*, void*); +public: + Fl_Scroll *_this_has_to_be_the_last; + Fl_Pack *harmonics; + OscilEditor(OscilGen *oscil_,Fl_Widget *oldosc_,Fl_Widget *cbwidget_,Fl_Widget *cbapplywidget_,Master *master_); + ~OscilEditor(); + void refresh(); + void redrawoscil(); +private: + OscilGen *oscil; + Fl_Widget *oldosc,*cbwidget,*cbapplywidget; + Oscilharmonic *h[MAX_AD_HARMONICS]; + Master *master; +}; +#endif diff --git a/plugins/zynaddsubfx/src/UI/PADnoteUI.cc b/plugins/zynaddsubfx/src/UI/PADnoteUI.cc new file mode 100644 index 000000000..45a14121a --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/PADnoteUI.cc @@ -0,0 +1,1504 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0109 + +#include "PADnoteUI.h" +#include +#include +#include +#include + +PADnoteHarmonicProfile::PADnoteHarmonicProfile(int x,int y, int w, int h, const char *label):Fl_Box(x,y,w,h,label) { + pars=NULL; +} + +void PADnoteHarmonicProfile::init(PADnoteParameters *pars,Master *master_) { + master=master_; +this->pars=pars; +} + +void PADnoteHarmonicProfile::draw() { + int ox=x(),oy=y(),lx=w(),ly=h(); +if (!visible()) return; +REALTYPE smps[lx]; + +REALTYPE realbw=pars->getprofile(smps,lx); +bool active=active_r(); + +//draw the equivalent bandwidth +if (active) fl_color(220,220,220); + else fl_color(160,165,165); +fl_line_style(0); +int rbw=(int)(realbw*(lx-1.0)/2.0); +for (int i=lx/2-rbw;i<(lx/2+rbw);i++) fl_line(ox+i,oy,ox+i,oy+ly-1); + +fl_line_style(0); +if (active) fl_color(200,200,200); + else fl_color(160,160,160); +for (int i=1;i<10;i++){ + int kx=(int)(lx/10.0*i); + fl_line(ox+kx,oy,ox+kx,oy+ly-1); +}; +for (int i=1;i<5;i++){ + int ky=(int)(ly/5.0*i); + fl_line(ox,oy+ly-ky,ox+lx,oy+ly-ky-1); +}; + + +fl_color(120,120,120); +fl_line_style(FL_DOT); +fl_line(ox+lx/2,oy,ox+lx/2,oy+ly); + +//draw the graph +fl_line_style(0); +int old=0; +for (int i=0;i0) fl_line(ox+i-1,oy+ly-2-old,ox+i,oy+ly-2-val); + old=val; +}; + + +fl_line_style(FL_DASH); +if (active) fl_color(0,100,220); + else fl_color(150,160,170); +fl_line(ox+lx/2-rbw,oy,ox+lx/2-rbw,oy+ly-1); +fl_line(ox+lx/2+rbw,oy,ox+lx/2+rbw,oy+ly-1); + +fl_line_style(0); +} + +PADnoteOvertonePosition::PADnoteOvertonePosition(int x,int y, int w, int h, const char *label):Fl_Box(x,y,w,h,label) { + pars=NULL; +} + +void PADnoteOvertonePosition::init(PADnoteParameters *pars,Master *master_) { + master=master_; +this->pars=pars; +} + +void PADnoteOvertonePosition::draw() { + if (!visible()) return; +const int maxdb=60; + +int ox=x(),oy=y(),lx=w(),ly=h(); +const int maxharmonic=64; + + +for (int i=1;imutex); +pars->oscilgen->getspectrum(n,spc,0); +pthread_mutex_unlock(&master->mutex); + + +//normalize +REALTYPE max=0; +for (int i=0;igetNhr(i); + int kx=(int)(lx/(REALTYPE)maxharmonic*nhr); + if ((kx<0)||(kx>lx)) continue; + + spectrum[kx]=spc[i-1]/max+1e-9; + +}; + +fl_color(180,0,0); +fl_line_style(0); + +if (pars->Pmode==2){ + int old=0; + for (int i=1;i1e-10)||(i==(lx-1))){ + int delta=i-old; + REALTYPE val1=spectrum[old]; + REALTYPE val2=spectrum[i]; + + REALTYPE idelta=1.0/delta; + for (int j=0;jdB2rap(-maxdb)) x=rap2dB(x)/maxdb+1; + else continue; + int yy=(int)(x*ly); + fl_line(ox+i,oy+ly-1-yy,ox+i,oy+ly-1); + +}; +} + +void PADnoteUI::cb__i(Fl_Tabs* o, void*) { + if (o->value()!=harmonicstructuregroup) applybutton->hide(); + else applybutton->show(); +} +void PADnoteUI::cb_(Fl_Tabs* o, void* v) { + ((PADnoteUI*)(o->parent()->user_data()))->cb__i(o,v); +} + +void PADnoteUI::cb_hpbasepar1_i(WidgetPDial* o, void*) { + pars->Php.base.par1=(int) o->value(); +hprofile->redraw(); +cbwidget->do_callback(); +} +void PADnoteUI::cb_hpbasepar1(WidgetPDial* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_hpbasepar1_i(o,v); +} + +void PADnoteUI::cb_hpbasetype_i(Fl_Choice* o, void*) { + pars->Php.base.type=o->value(); +hprofile->redraw(); +cbwidget->do_callback(); +} +void PADnoteUI::cb_hpbasetype(Fl_Choice* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_hpbasetype_i(o,v); +} + +Fl_Menu_Item PADnoteUI::menu_hpbasetype[] = { + {"Gauss", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Square", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"DoubleExp", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void PADnoteUI::cb_hpfreqmult_i(WidgetPDial* o, void*) { + pars->Php.freqmult=(int) o->value(); +hprofile->redraw(); +cbwidget->do_callback(); +} +void PADnoteUI::cb_hpfreqmult(WidgetPDial* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_hpfreqmult_i(o,v); +} + +void PADnoteUI::cb_hpmpar1_i(WidgetPDial* o, void*) { + pars->Php.modulator.par1=(int) o->value(); +hprofile->redraw(); +cbwidget->do_callback(); +} +void PADnoteUI::cb_hpmpar1(WidgetPDial* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_hpmpar1_i(o,v); +} + +void PADnoteUI::cb_hpmfreq_i(WidgetPDial* o, void*) { + pars->Php.modulator.freq=(int) o->value(); +hprofile->redraw(); +cbwidget->do_callback(); +} +void PADnoteUI::cb_hpmfreq(WidgetPDial* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_hpmfreq_i(o,v); +} + +void PADnoteUI::cb_hpamptype_i(Fl_Choice* o, void*) { + pars->Php.amp.type=o->value(); +hprofile->redraw(); +cbwidget->do_callback(); +} +void PADnoteUI::cb_hpamptype(Fl_Choice* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->parent()->parent()->user_data()))->cb_hpamptype_i(o,v); +} + +Fl_Menu_Item PADnoteUI::menu_hpamptype[] = { + {"OFF", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Gauss", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Sine", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Flat", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void PADnoteUI::cb_hpampmode_i(Fl_Choice* o, void*) { + pars->Php.amp.mode=o->value(); +hprofile->redraw(); +cbwidget->do_callback(); +} +void PADnoteUI::cb_hpampmode(Fl_Choice* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->parent()->parent()->user_data()))->cb_hpampmode_i(o,v); +} + +Fl_Menu_Item PADnoteUI::menu_hpampmode[] = { + {"Sum", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Mult", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Div1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Div2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void PADnoteUI::cb_hpamppar1_i(WidgetPDial* o, void*) { + pars->Php.amp.par1=(int) o->value(); +hprofile->redraw(); +cbwidget->do_callback(); +} +void PADnoteUI::cb_hpamppar1(WidgetPDial* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->parent()->parent()->user_data()))->cb_hpamppar1_i(o,v); +} + +void PADnoteUI::cb_hpamppar2_i(WidgetPDial* o, void*) { + pars->Php.amp.par2=(int) o->value(); +hprofile->redraw(); +cbwidget->do_callback(); +} +void PADnoteUI::cb_hpamppar2(WidgetPDial* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->parent()->parent()->user_data()))->cb_hpamppar2_i(o,v); +} + +void PADnoteUI::cb_hpautoscale_i(Fl_Check_Button* o, void*) { + pars->Php.autoscale=(int) o->value(); +hprofile->redraw(); +cbwidget->do_callback(); +} +void PADnoteUI::cb_hpautoscale(Fl_Check_Button* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_hpautoscale_i(o,v); +} + +void PADnoteUI::cb_hponehalf_i(Fl_Choice* o, void*) { + pars->Php.onehalf=o->value(); +hprofile->redraw(); +cbwidget->do_callback(); +} +void PADnoteUI::cb_hponehalf(Fl_Choice* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_hponehalf_i(o,v); +} + +Fl_Menu_Item PADnoteUI::menu_hponehalf[] = { + {"Full", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Upper Half", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Lower Half", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void PADnoteUI::cb_hpwidth_i(WidgetPDial* o, void*) { + pars->Php.width=(int) o->value(); +hprofile->redraw(); +cbwidget->do_callback(); +} +void PADnoteUI::cb_hpwidth(WidgetPDial* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_hpwidth_i(o,v); +} + +void PADnoteUI::cb_Change_i(Fl_Button*, void*) { + if (oscui!=NULL) delete (oscui); +oscui=new OscilEditor(pars->oscilgen,osc,cbwidget,applybutton,master); +} +void PADnoteUI::cb_Change(Fl_Button* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->user_data()))->cb_Change_i(o,v); +} + +void PADnoteUI::cb_cbwidget_i(Fl_Box*, void*) { + overtonepos->redraw(); +applybutton->color(FL_RED); +applybutton->redraw(); +} +void PADnoteUI::cb_cbwidget(Fl_Box* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->user_data()))->cb_cbwidget_i(o,v); +} + +void PADnoteUI::cb_Resonance_i(Fl_Button*, void*) { + resui->resonancewindow->redraw(); +resui->resonancewindow->show(); +resui->setcbwidget(cbwidget,applybutton); +} +void PADnoteUI::cb_Resonance(Fl_Button* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->user_data()))->cb_Resonance_i(o,v); +} + +void PADnoteUI::cb_bwdial_i(WidgetPDial* o, void*) { + bwcents->value(pars->setPbandwidth((int) o->value())); +cbwidget->do_callback(); +} +void PADnoteUI::cb_bwdial(WidgetPDial* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->user_data()))->cb_bwdial_i(o,v); +} + +void PADnoteUI::cb_hrpostype_i(Fl_Choice* o, void*) { + pars->Phrpos.type=o->value(); +overtonepos->redraw(); +cbwidget->do_callback(); +} +void PADnoteUI::cb_hrpostype(Fl_Choice* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_hrpostype_i(o,v); +} + +Fl_Menu_Item PADnoteUI::menu_hrpostype[] = { + {"Harmonic", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"ShiftU", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"ShiftL", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"PowerU", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"PowerL", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"Sine", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"Power", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void PADnoteUI::cb_hrpospar1_i(WidgetPDial* o, void*) { + pars->Phrpos.par1=(int) o->value(); +overtonepos->redraw(); +cbwidget->do_callback(); +} +void PADnoteUI::cb_hrpospar1(WidgetPDial* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_hrpospar1_i(o,v); +} + +void PADnoteUI::cb_hrpospar2_i(WidgetPDial* o, void*) { + pars->Phrpos.par2=(int) o->value(); +overtonepos->redraw(); +cbwidget->do_callback(); +} +void PADnoteUI::cb_hrpospar2(WidgetPDial* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_hrpospar2_i(o,v); +} + +void PADnoteUI::cb_hrpospar3_i(WidgetPDial* o, void*) { + pars->Phrpos.par3=(int) o->value(); +overtonepos->redraw(); +cbwidget->do_callback(); +} +void PADnoteUI::cb_hrpospar3(WidgetPDial* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_hrpospar3_i(o,v); +} + +void PADnoteUI::cb_bwscale_i(Fl_Choice* o, void*) { + pars->Pbwscale=(int) o->value(); +cbwidget->do_callback(); +} +void PADnoteUI::cb_bwscale(Fl_Choice* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->user_data()))->cb_bwscale_i(o,v); +} + +Fl_Menu_Item PADnoteUI::menu_bwscale[] = { + {"Normal", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"EqualHz", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"Quater", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"Half", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"75%", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"150%", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"Double", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"Inv.Half", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void PADnoteUI::cb_qsamplesize_i(Fl_Choice* o, void*) { + pars->Pquality.samplesize=(int) o->value(); +cbwidget->do_callback(); +} +void PADnoteUI::cb_qsamplesize(Fl_Choice* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->user_data()))->cb_qsamplesize_i(o,v); +} + +Fl_Menu_Item PADnoteUI::menu_qsamplesize[] = { + {"16k (Tiny)", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"32k", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"64k (Small)", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"128k", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"256k (Normal)", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"512k", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"1M (Big)", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void PADnoteUI::cb_qsmpoct_i(Fl_Choice* o, void*) { + pars->Pquality.smpoct=(int) o->value(); +cbwidget->do_callback(); +} +void PADnoteUI::cb_qsmpoct(Fl_Choice* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->user_data()))->cb_qsmpoct_i(o,v); +} + +Fl_Menu_Item PADnoteUI::menu_qsmpoct[] = { + {"0.5", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"3", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"4", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"6", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"12", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void PADnoteUI::cb_qoct_i(Fl_Choice* o, void*) { + pars->Pquality.oct=(int) o->value(); +cbwidget->do_callback(); +} +void PADnoteUI::cb_qoct(Fl_Choice* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->user_data()))->cb_qoct_i(o,v); +} + +Fl_Menu_Item PADnoteUI::menu_qoct[] = { + {"1", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"3", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"4", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"5", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"6", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"7", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"8", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void PADnoteUI::cb_qbasenote_i(Fl_Choice* o, void*) { + pars->Pquality.basenote=(int) o->value(); +cbwidget->do_callback(); +} +void PADnoteUI::cb_qbasenote(Fl_Choice* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->user_data()))->cb_qbasenote_i(o,v); +} + +Fl_Menu_Item PADnoteUI::menu_qbasenote[] = { + {"C-2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 14, 0}, + {"G-2", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 14, 0}, + {"C-3", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 14, 0}, + {"G-3", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 14, 0}, + {"C-4", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 14, 0}, + {"G-4", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 14, 0}, + {"C-5", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 14, 0}, + {"G-5", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 14, 0}, + {"G-6", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 14, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void PADnoteUI::cb_spectrummode_i(Fl_Choice* o, void*) { + pars->Pmode=(int) o->value(); + +if (pars->Pmode==0){ + bwprofilegroup->activate(); + bwdial->activate(); + bwcents->activate(); + hprofile->activate(); + hprofile->color(54); + bwscale->activate(); +} else { + bwprofilegroup->deactivate(); + bwdial->deactivate(); + bwcents->deactivate(); + hprofile->deactivate(); + hprofile->color(48); + bwscale->deactivate(); +}; + +cbwidget->do_callback(); +} +void PADnoteUI::cb_spectrummode(Fl_Choice* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->user_data()))->cb_spectrummode_i(o,v); +} + +Fl_Menu_Item PADnoteUI::menu_spectrummode[] = { + {"Bandwidth", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"Discrete", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"Continous", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void PADnoteUI::cb_octave_i(Fl_Counter* o, void*) { + int k=(int) o->value(); +if (k<0) k+=16; +pars->PCoarseDetune = k*1024+ + pars->PCoarseDetune%1024; +} +void PADnoteUI::cb_octave(Fl_Counter* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_octave_i(o,v); +} + +void PADnoteUI::cb_coarsedet_i(Fl_Counter* o, void*) { + int k=(int) o->value(); +if (k<0) k+=1024; +pars->PCoarseDetune = k+ + (pars->PCoarseDetune/1024)*1024; +} +void PADnoteUI::cb_coarsedet(Fl_Counter* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_coarsedet_i(o,v); +} + +void PADnoteUI::cb_detune_i(Fl_Slider* o, void*) { + pars->PDetune=(int)o->value()+8192; +detunevalueoutput->do_callback(); +} +void PADnoteUI::cb_detune(Fl_Slider* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_detune_i(o,v); +} + +void PADnoteUI::cb_detunevalueoutput_i(Fl_Value_Output* o, void*) { + o->value(getdetune(pars->PDetuneType,0,pars->PDetune)); +} +void PADnoteUI::cb_detunevalueoutput(Fl_Value_Output* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_detunevalueoutput_i(o,v); +} + +void PADnoteUI::cb_detunetype_i(Fl_Choice* o, void*) { + pars->PDetuneType=(int) o->value()+1; +detunevalueoutput->do_callback(); +} +void PADnoteUI::cb_detunetype(Fl_Choice* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_detunetype_i(o,v); +} + +void PADnoteUI::cb_hz440_i(Fl_Check_Button* o, void*) { + int x=(int) o->value(); +pars->Pfixedfreq=x; +if (x==0) fixedfreqetdial->deactivate(); + else fixedfreqetdial->activate(); +} +void PADnoteUI::cb_hz440(Fl_Check_Button* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_hz440_i(o,v); +} + +void PADnoteUI::cb_fixedfreqetdial_i(WidgetPDial* o, void*) { + pars->PfixedfreqET=(int) o->value(); +} +void PADnoteUI::cb_fixedfreqetdial(WidgetPDial* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_fixedfreqetdial_i(o,v); +} + +void PADnoteUI::cb_volume_i(Fl_Value_Slider* o, void*) { + pars->PVolume=(int)o->value(); +} +void PADnoteUI::cb_volume(Fl_Value_Slider* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_volume_i(o,v); +} + +void PADnoteUI::cb_vsns_i(Fl_Value_Slider* o, void*) { + pars->PAmpVelocityScaleFunction=(int) o->value(); +} +void PADnoteUI::cb_vsns(Fl_Value_Slider* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_vsns_i(o,v); +} + +void PADnoteUI::cb_pan_i(WidgetPDial* o, void*) { + pars->PPanning=(int) o->value(); +} +void PADnoteUI::cb_pan(WidgetPDial* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_pan_i(o,v); +} + +void PADnoteUI::cb_pstr_i(WidgetPDial* o, void*) { + pars->PPunchStrength=(int) o->value(); +} +void PADnoteUI::cb_pstr(WidgetPDial* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_pstr_i(o,v); +} + +void PADnoteUI::cb_pt_i(WidgetPDial* o, void*) { + pars->PPunchTime=(int) o->value(); +} +void PADnoteUI::cb_pt(WidgetPDial* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_pt_i(o,v); +} + +void PADnoteUI::cb_pstc_i(WidgetPDial* o, void*) { + pars->PPunchStretch=(int) o->value(); +} +void PADnoteUI::cb_pstc(WidgetPDial* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_pstc_i(o,v); +} + +void PADnoteUI::cb_pvel_i(WidgetPDial* o, void*) { + pars->PPunchVelocitySensing=(int) o->value(); +} +void PADnoteUI::cb_pvel(WidgetPDial* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_pvel_i(o,v); +} + +void PADnoteUI::cb_stereo_i(Fl_Check_Button* o, void*) { + pars->PStereo=(int) o->value(); +hprofile->redraw(); +} +void PADnoteUI::cb_stereo(Fl_Check_Button* o, void* v) { + ((PADnoteUI*)(o->parent()->parent()->parent()->parent()->user_data()))->cb_stereo_i(o,v); +} + +void PADnoteUI::cb_applybutton_i(Fl_Button* o, void*) { + pars->applyparameters(true); +o->color(FL_GRAY); +if (oscui!=NULL) { + oscui->applybutton->color(FL_GRAY); + oscui->applybutton->redraw(); +}; +if (resui!=NULL) { + resui->applybutton->color(FL_GRAY); + resui->applybutton->redraw(); +}; +} +void PADnoteUI::cb_applybutton(Fl_Button* o, void* v) { + ((PADnoteUI*)(o->parent()->user_data()))->cb_applybutton_i(o,v); +} + +void PADnoteUI::cb_Close_i(Fl_Button*, void*) { + padnotewindow->hide(); +} +void PADnoteUI::cb_Close(Fl_Button* o, void* v) { + ((PADnoteUI*)(o->parent()->user_data()))->cb_Close_i(o,v); +} + +void PADnoteUI::cb_C_i(Fl_Button*, void*) { + presetsui->copy(pars); +} +void PADnoteUI::cb_C(Fl_Button* o, void* v) { + ((PADnoteUI*)(o->parent()->user_data()))->cb_C_i(o,v); +} + +void PADnoteUI::cb_P_i(Fl_Button*, void*) { + presetsui->paste(pars,this); +} +void PADnoteUI::cb_P(Fl_Button* o, void* v) { + ((PADnoteUI*)(o->parent()->user_data()))->cb_P_i(o,v); +} + +void PADnoteUI::cb_export_i(Fl_Button*, void*) { + char *filename; +filename=fl_file_chooser("Export samples:","(*.wav)",NULL,0); +if (filename==NULL) return; +fl_filename_setext(filename,""); + + + +pars->export2wav(filename); +} +void PADnoteUI::cb_export(Fl_Button* o, void* v) { + ((PADnoteUI*)(o->parent()->user_data()))->cb_export_i(o,v); +} + +PADnoteUI::PADnoteUI(PADnoteParameters *parameters,Master *master_) { + pars=parameters; +master=master_; +oscui=NULL; +resui=new ResonanceUI(pars->resonance); +make_window(); +} + +Fl_Double_Window* PADnoteUI::make_window() { + { padnotewindow = new Fl_Double_Window(535, 450, "PAD synth Parameters"); + padnotewindow->user_data((void*)(this)); + { Fl_Tabs* o = new Fl_Tabs(0, 0, 535, 395); + o->callback((Fl_Callback*)cb_); + { harmonicstructuregroup = new Fl_Group(0, 20, 535, 375, "Harmonic Structure"); + harmonicstructuregroup->box(FL_ENGRAVED_BOX); + { Fl_Group* o = bwprofilegroup = new Fl_Group(5, 30, 90, 260); + bwprofilegroup->box(FL_ENGRAVED_BOX); + { WidgetPDial* o = hpbasepar1 = new WidgetPDial(20, 75, 25, 25, "Width"); + hpbasepar1->box(FL_ROUND_UP_BOX); + hpbasepar1->color(FL_BACKGROUND_COLOR); + hpbasepar1->selection_color(FL_INACTIVE_COLOR); + hpbasepar1->labeltype(FL_NORMAL_LABEL); + hpbasepar1->labelfont(0); + hpbasepar1->labelsize(10); + hpbasepar1->labelcolor(FL_FOREGROUND_COLOR); + hpbasepar1->maximum(127); + hpbasepar1->step(1); + hpbasepar1->callback((Fl_Callback*)cb_hpbasepar1); + hpbasepar1->align(FL_ALIGN_TOP); + hpbasepar1->when(FL_WHEN_CHANGED); + o->value(pars->Php.base.par1); + } // WidgetPDial* hpbasepar1 + { Fl_Choice* o = hpbasetype = new Fl_Choice(15, 45, 75, 15, "Base Type"); + hpbasetype->down_box(FL_BORDER_BOX); + hpbasetype->labelsize(10); + hpbasetype->textsize(10); + hpbasetype->callback((Fl_Callback*)cb_hpbasetype); + hpbasetype->align(FL_ALIGN_TOP_LEFT); + hpbasetype->menu(menu_hpbasetype); + o->value(pars->Php.base.type); + } // Fl_Choice* hpbasetype + { WidgetPDial* o = hpfreqmult = new WidgetPDial(55, 75, 25, 25, "FreqMlt"); + hpfreqmult->box(FL_ROUND_UP_BOX); + hpfreqmult->color(FL_BACKGROUND_COLOR); + hpfreqmult->selection_color(FL_INACTIVE_COLOR); + hpfreqmult->labeltype(FL_NORMAL_LABEL); + hpfreqmult->labelfont(0); + hpfreqmult->labelsize(10); + hpfreqmult->labelcolor(FL_FOREGROUND_COLOR); + hpfreqmult->maximum(127); + hpfreqmult->step(1); + hpfreqmult->callback((Fl_Callback*)cb_hpfreqmult); + hpfreqmult->align(FL_ALIGN_TOP); + hpfreqmult->when(FL_WHEN_CHANGED); + o->value(pars->Php.freqmult); + } // WidgetPDial* hpfreqmult + { WidgetPDial* o = hpmpar1 = new WidgetPDial(15, 115, 20, 20, "Str"); + hpmpar1->box(FL_ROUND_UP_BOX); + hpmpar1->color(FL_BACKGROUND_COLOR); + hpmpar1->selection_color(FL_INACTIVE_COLOR); + hpmpar1->labeltype(FL_NORMAL_LABEL); + hpmpar1->labelfont(0); + hpmpar1->labelsize(10); + hpmpar1->labelcolor(FL_FOREGROUND_COLOR); + hpmpar1->maximum(127); + hpmpar1->step(1); + hpmpar1->callback((Fl_Callback*)cb_hpmpar1); + hpmpar1->align(FL_ALIGN_TOP); + hpmpar1->when(FL_WHEN_CHANGED); + o->value(pars->Php.modulator.par1); + } // WidgetPDial* hpmpar1 + { WidgetPDial* o = hpmfreq = new WidgetPDial(40, 115, 20, 20, "SFreq"); + hpmfreq->box(FL_ROUND_UP_BOX); + hpmfreq->color(FL_BACKGROUND_COLOR); + hpmfreq->selection_color(FL_INACTIVE_COLOR); + hpmfreq->labeltype(FL_NORMAL_LABEL); + hpmfreq->labelfont(0); + hpmfreq->labelsize(10); + hpmfreq->labelcolor(FL_FOREGROUND_COLOR); + hpmfreq->maximum(127); + hpmfreq->step(1); + hpmfreq->callback((Fl_Callback*)cb_hpmfreq); + hpmfreq->align(FL_ALIGN_TOP); + hpmfreq->when(FL_WHEN_CHANGED); + o->value(pars->Php.modulator.freq); + } // WidgetPDial* hpmfreq + { Fl_Group* o = new Fl_Group(10, 160, 80, 105); + o->box(FL_BORDER_BOX); + { Fl_Choice* o = hpamptype = new Fl_Choice(15, 175, 70, 15, "AmpMultiplier"); + hpamptype->down_box(FL_BORDER_BOX); + hpamptype->labelsize(10); + hpamptype->textsize(10); + hpamptype->callback((Fl_Callback*)cb_hpamptype); + hpamptype->align(FL_ALIGN_TOP_LEFT); + hpamptype->menu(menu_hpamptype); + o->value(pars->Php.amp.type); + } // Fl_Choice* hpamptype + { Fl_Choice* o = hpampmode = new Fl_Choice(15, 205, 70, 15, "AmpMode"); + hpampmode->down_box(FL_BORDER_BOX); + hpampmode->labelsize(10); + hpampmode->textsize(10); + hpampmode->callback((Fl_Callback*)cb_hpampmode); + hpampmode->align(FL_ALIGN_TOP_LEFT); + hpampmode->menu(menu_hpampmode); + o->value(pars->Php.amp.mode); + } // Fl_Choice* hpampmode + { WidgetPDial* o = hpamppar1 = new WidgetPDial(15, 235, 25, 25, "Par1"); + hpamppar1->box(FL_ROUND_UP_BOX); + hpamppar1->color(FL_BACKGROUND_COLOR); + hpamppar1->selection_color(FL_INACTIVE_COLOR); + hpamppar1->labeltype(FL_NORMAL_LABEL); + hpamppar1->labelfont(0); + hpamppar1->labelsize(10); + hpamppar1->labelcolor(FL_FOREGROUND_COLOR); + hpamppar1->maximum(127); + hpamppar1->step(1); + hpamppar1->callback((Fl_Callback*)cb_hpamppar1); + hpamppar1->align(FL_ALIGN_TOP); + hpamppar1->when(FL_WHEN_CHANGED); + o->value(pars->Php.amp.par1); + } // WidgetPDial* hpamppar1 + { WidgetPDial* o = hpamppar2 = new WidgetPDial(55, 235, 25, 25, "Par2"); + hpamppar2->box(FL_ROUND_UP_BOX); + hpamppar2->color(FL_BACKGROUND_COLOR); + hpamppar2->selection_color(FL_INACTIVE_COLOR); + hpamppar2->labeltype(FL_NORMAL_LABEL); + hpamppar2->labelfont(0); + hpamppar2->labelsize(10); + hpamppar2->labelcolor(FL_FOREGROUND_COLOR); + hpamppar2->maximum(127); + hpamppar2->step(1); + hpamppar2->callback((Fl_Callback*)cb_hpamppar2); + hpamppar2->align(FL_ALIGN_TOP); + hpamppar2->when(FL_WHEN_CHANGED); + o->value(pars->Php.amp.par2); + } // WidgetPDial* hpamppar2 + o->end(); + } // Fl_Group* o + { Fl_Check_Button* o = hpautoscale = new Fl_Check_Button(10, 270, 60, 15, "autoscale"); + hpautoscale->down_box(FL_DOWN_BOX); + hpautoscale->labelsize(10); + hpautoscale->callback((Fl_Callback*)cb_hpautoscale); + o->value(pars->Php.autoscale); + } // Fl_Check_Button* hpautoscale + { Fl_Choice* o = hponehalf = new Fl_Choice(10, 143, 80, 15); + hponehalf->down_box(FL_BORDER_BOX); + hponehalf->labelsize(10); + hponehalf->textsize(10); + hponehalf->callback((Fl_Callback*)cb_hponehalf); + hponehalf->align(FL_ALIGN_TOP_LEFT); + hponehalf->menu(menu_hponehalf); + o->value(pars->Php.onehalf); + } // Fl_Choice* hponehalf + { WidgetPDial* o = hpwidth = new WidgetPDial(65, 115, 20, 20, "Size"); + hpwidth->box(FL_ROUND_UP_BOX); + hpwidth->color(FL_BACKGROUND_COLOR); + hpwidth->selection_color(FL_INACTIVE_COLOR); + hpwidth->labeltype(FL_NORMAL_LABEL); + hpwidth->labelfont(0); + hpwidth->labelsize(10); + hpwidth->labelcolor(FL_FOREGROUND_COLOR); + hpwidth->maximum(127); + hpwidth->step(1); + hpwidth->callback((Fl_Callback*)cb_hpwidth); + hpwidth->align(FL_ALIGN_TOP); + hpwidth->when(FL_WHEN_CHANGED); + o->value(pars->Php.width); + } // WidgetPDial* hpwidth + if (pars->Pmode!=0) o->deactivate(); + bwprofilegroup->end(); + } // Fl_Group* bwprofilegroup + { Fl_Group* o = new Fl_Group(100, 155, 270, 135); + o->box(FL_THIN_DOWN_BOX); + o->color(FL_GRAY0); + o->selection_color((Fl_Color)71); + o->labelcolor((Fl_Color)179); + o->align(FL_ALIGN_BOTTOM_LEFT); + osc=new Oscilloscope(o->x(),o->y(),o->w(),o->h(),""); + osc->init(pars->oscilgen,master); + o->end(); + } // Fl_Group* o + { Fl_Button* o = new Fl_Button(375, 270, 60, 20, "Change"); + o->box(FL_THIN_UP_BOX); + o->labelfont(1); + o->labelsize(11); + o->callback((Fl_Callback*)cb_Change); + } // Fl_Button* o + { cbwidget = new Fl_Box(125, 135, 205, 20, "Harmonic Content"); + cbwidget->callback((Fl_Callback*)cb_cbwidget); + cbwidget->align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE); + } // Fl_Box* cbwidget + { Fl_Button* o = new Fl_Button(375, 225, 80, 20, "Resonance"); + o->box(FL_THIN_UP_BOX); + o->callback((Fl_Callback*)cb_Resonance); + } // Fl_Button* o + { WidgetPDial* o = bwdial = new WidgetPDial(15, 295, 35, 35, "BandWidth"); + bwdial->box(FL_ROUND_UP_BOX); + bwdial->color(FL_BACKGROUND_COLOR); + bwdial->selection_color(FL_INACTIVE_COLOR); + bwdial->labeltype(FL_NORMAL_LABEL); + bwdial->labelfont(0); + bwdial->labelsize(10); + bwdial->labelcolor(FL_FOREGROUND_COLOR); + bwdial->maximum(1000); + bwdial->step(1); + bwdial->callback((Fl_Callback*)cb_bwdial); + bwdial->align(FL_ALIGN_BOTTOM); + bwdial->when(FL_WHEN_CHANGED); + o->value(pars->Pbandwidth); + if (pars->Pmode!=0) o->deactivate(); + } // WidgetPDial* bwdial + { Fl_Value_Output* o = bwcents = new Fl_Value_Output(55, 305, 55, 15, "cents"); + bwcents->labelsize(10); + bwcents->maximum(10000); + bwcents->step(0.1); + bwcents->align(FL_ALIGN_BOTTOM_LEFT); + o->value(pars->setPbandwidth(pars->Pbandwidth)); + if (pars->Pmode!=0) o->deactivate(); + } // Fl_Value_Output* bwcents + { Fl_Group* o = new Fl_Group(315, 295, 215, 45); + o->box(FL_ENGRAVED_BOX); + { Fl_Choice* o = hrpostype = new Fl_Choice(325, 310, 80, 20, "OvertonesPosition"); + hrpostype->down_box(FL_BORDER_BOX); + hrpostype->labelsize(10); + hrpostype->textsize(11); + hrpostype->callback((Fl_Callback*)cb_hrpostype); + hrpostype->align(FL_ALIGN_TOP_LEFT); + hrpostype->menu(menu_hrpostype); + o->value(pars->Phrpos.type); + } // Fl_Choice* hrpostype + { WidgetPDial* o = hrpospar1 = new WidgetPDial(425, 310, 25, 25, "Par1"); + hrpospar1->box(FL_ROUND_UP_BOX); + hrpospar1->color(FL_BACKGROUND_COLOR); + hrpospar1->selection_color(FL_INACTIVE_COLOR); + hrpospar1->labeltype(FL_NORMAL_LABEL); + hrpospar1->labelfont(0); + hrpospar1->labelsize(10); + hrpospar1->labelcolor(FL_FOREGROUND_COLOR); + hrpospar1->maximum(255); + hrpospar1->step(1); + hrpospar1->callback((Fl_Callback*)cb_hrpospar1); + hrpospar1->align(FL_ALIGN_TOP); + hrpospar1->when(FL_WHEN_CHANGED); + o->value(pars->Phrpos.par1); + } // WidgetPDial* hrpospar1 + { WidgetPDial* o = hrpospar2 = new WidgetPDial(460, 310, 25, 25, "Par2"); + hrpospar2->box(FL_ROUND_UP_BOX); + hrpospar2->color(FL_BACKGROUND_COLOR); + hrpospar2->selection_color(FL_INACTIVE_COLOR); + hrpospar2->labeltype(FL_NORMAL_LABEL); + hrpospar2->labelfont(0); + hrpospar2->labelsize(10); + hrpospar2->labelcolor(FL_FOREGROUND_COLOR); + hrpospar2->maximum(255); + hrpospar2->step(1); + hrpospar2->callback((Fl_Callback*)cb_hrpospar2); + hrpospar2->align(FL_ALIGN_TOP); + hrpospar2->when(FL_WHEN_CHANGED); + o->value(pars->Phrpos.par2); + } // WidgetPDial* hrpospar2 + { WidgetPDial* o = hrpospar3 = new WidgetPDial(495, 310, 25, 25, "ForceH"); + hrpospar3->box(FL_ROUND_UP_BOX); + hrpospar3->color(FL_BACKGROUND_COLOR); + hrpospar3->selection_color(FL_INACTIVE_COLOR); + hrpospar3->labeltype(FL_NORMAL_LABEL); + hrpospar3->labelfont(0); + hrpospar3->labelsize(10); + hrpospar3->labelcolor(FL_FOREGROUND_COLOR); + hrpospar3->maximum(255); + hrpospar3->step(1); + hrpospar3->callback((Fl_Callback*)cb_hrpospar3); + hrpospar3->align(FL_ALIGN_TOP); + hrpospar3->when(FL_WHEN_CHANGED); + o->value(pars->Phrpos.par3); + } // WidgetPDial* hrpospar3 + o->end(); + } // Fl_Group* o + { Fl_Choice* o = bwscale = new Fl_Choice(120, 305, 80, 20, "Bandwidth Scale"); + bwscale->down_box(FL_BORDER_BOX); + bwscale->labelsize(10); + bwscale->textsize(11); + bwscale->callback((Fl_Callback*)cb_bwscale); + bwscale->align(FL_ALIGN_TOP_LEFT); + bwscale->menu(menu_bwscale); + o->value(pars->Pbwscale); + if (pars->Pmode!=0) o->deactivate(); + } // Fl_Choice* bwscale + { Fl_Group* o = overtonepos = new Fl_Group(5, 345, 525, 45); + overtonepos->box(FL_FLAT_BOX); + overtonepos->color(FL_LIGHT3); + overtonepos->selection_color((Fl_Color)218); + overtonepos->labelcolor(FL_GREEN); + PADnoteOvertonePosition *opui=new PADnoteOvertonePosition(o->x(),o->y(),o->w(),o->h(),""); + opui->init(pars,master); + overtonepos->end(); + } // Fl_Group* overtonepos + { Fl_Choice* o = qsamplesize = new Fl_Choice(375, 190, 115, 20, "Sample Size"); + qsamplesize->down_box(FL_BORDER_BOX); + qsamplesize->labelsize(10); + qsamplesize->textsize(11); + qsamplesize->callback((Fl_Callback*)cb_qsamplesize); + qsamplesize->align(FL_ALIGN_TOP_LEFT); + qsamplesize->menu(menu_qsamplesize); + o->value(pars->Pquality.samplesize); + } // Fl_Choice* qsamplesize + { Fl_Choice* o = qsmpoct = new Fl_Choice(430, 155, 45, 20, "smp/oct"); + qsmpoct->down_box(FL_BORDER_BOX); + qsmpoct->labelsize(11); + qsmpoct->textsize(11); + qsmpoct->callback((Fl_Callback*)cb_qsmpoct); + qsmpoct->align(FL_ALIGN_TOP_LEFT); + qsmpoct->menu(menu_qsmpoct); + o->value(pars->Pquality.smpoct); + } // Fl_Choice* qsmpoct + { Fl_Choice* o = qoct = new Fl_Choice(480, 155, 45, 20, "no.oct"); + qoct->down_box(FL_BORDER_BOX); + qoct->labelsize(11); + qoct->textsize(11); + qoct->callback((Fl_Callback*)cb_qoct); + qoct->align(FL_ALIGN_TOP_LEFT); + qoct->menu(menu_qoct); + o->value(pars->Pquality.oct); + } // Fl_Choice* qoct + { Fl_Choice* o = qbasenote = new Fl_Choice(375, 155, 50, 20, "base"); + qbasenote->down_box(FL_BORDER_BOX); + qbasenote->labelsize(11); + qbasenote->textsize(11); + qbasenote->callback((Fl_Callback*)cb_qbasenote); + qbasenote->align(FL_ALIGN_TOP_LEFT); + qbasenote->menu(menu_qbasenote); + o->value(pars->Pquality.basenote); + } // Fl_Choice* qbasenote + { Fl_Group* o = hprofile = new Fl_Group(100, 45, 430, 90); + hprofile->box(FL_FLAT_BOX); + hprofile->color(FL_LIGHT3); + hprofile->selection_color((Fl_Color)218); + hprofile->labelcolor(FL_GREEN); + PADnoteHarmonicProfile *hpui=new PADnoteHarmonicProfile(o->x(),o->y(),o->w(),o->h(),""); + hpui->init(pars,master); + if (pars->Pmode!=0) { o->deactivate(); o->color(48);}; + hprofile->end(); + } // Fl_Group* hprofile + { new Fl_Box(160, 25, 315, 20, "Profile of One Harmonic (Frequency Distribution)"); + } // Fl_Box* o + { Fl_Choice* o = spectrummode = new Fl_Choice(220, 305, 90, 20, "Spectrum Mode"); + spectrummode->down_box(FL_BORDER_BOX); + spectrummode->labelfont(1); + spectrummode->labelsize(10); + spectrummode->textsize(11); + spectrummode->callback((Fl_Callback*)cb_spectrummode); + spectrummode->align(FL_ALIGN_TOP_LEFT); + spectrummode->menu(menu_spectrummode); + o->value(pars->Pmode); + } // Fl_Choice* spectrummode + harmonicstructuregroup->end(); + } // Fl_Group* harmonicstructuregroup + { Fl_Group* o = new Fl_Group(0, 20, 535, 375, "Envelopes&LFOs"); + o->box(FL_ENGRAVED_BOX); + o->hide(); + { Fl_Group* o = new Fl_Group(5, 275, 525, 115, "FREQUENCY"); + o->box(FL_THIN_UP_BOX); + o->labeltype(FL_EMBOSSED_LABEL); + o->labelfont(1); + o->labelsize(13); + o->align(FL_ALIGN_TOP|FL_ALIGN_INSIDE); + { EnvelopeUI* o = freqenv = new EnvelopeUI(10, 315, 205, 70, "PADSynth - Frequency Envelope"); + freqenv->box(FL_FLAT_BOX); + freqenv->color((Fl_Color)51); + freqenv->selection_color(FL_BACKGROUND_COLOR); + freqenv->labeltype(FL_NORMAL_LABEL); + freqenv->labelfont(0); + freqenv->labelsize(14); + freqenv->labelcolor(FL_FOREGROUND_COLOR); + freqenv->align(FL_ALIGN_WRAP|FL_ALIGN_INSIDE); + freqenv->when(FL_WHEN_RELEASE); + o->init(pars->FreqEnvelope); + freqenv->end(); + } // EnvelopeUI* freqenv + { Fl_Counter* o = octave = new Fl_Counter(470, 295, 45, 15, "Octave"); + octave->tooltip("Octave"); + octave->type(1); + octave->labelsize(10); + octave->minimum(-8); + octave->maximum(7); + octave->step(1); + octave->textfont(1); + octave->textsize(11); + octave->callback((Fl_Callback*)cb_octave); + octave->align(FL_ALIGN_TOP); + int k=pars->PCoarseDetune/1024; + if (k>=8) k-=16; + o->value(k); + } // Fl_Counter* octave + { Fl_Counter* o = coarsedet = new Fl_Counter(455, 365, 60, 20, "Coarse det."); + coarsedet->tooltip("Coarse Detune"); + coarsedet->labelsize(10); + coarsedet->minimum(-64); + coarsedet->maximum(63); + coarsedet->step(1); + coarsedet->textfont(1); + coarsedet->textsize(11); + coarsedet->callback((Fl_Callback*)cb_coarsedet); + coarsedet->align(FL_ALIGN_TOP_LEFT); + int k=pars->PCoarseDetune%1024; + if (k>=512) k-=1024; + o->value(k); + o->lstep(10); + } // Fl_Counter* coarsedet + { LFOUI* o = freqlfo = new LFOUI(215, 315, 230, 70, "Frequency LFO "); + freqlfo->box(FL_FLAT_BOX); + freqlfo->color(FL_DARK1); + freqlfo->selection_color(FL_BACKGROUND_COLOR); + freqlfo->labeltype(FL_NORMAL_LABEL); + freqlfo->labelfont(0); + freqlfo->labelsize(14); + freqlfo->labelcolor(FL_FOREGROUND_COLOR); + freqlfo->align(FL_ALIGN_WRAP|FL_ALIGN_INSIDE); + freqlfo->when(FL_WHEN_RELEASE); + o->init(pars->FreqLfo); + freqlfo->end(); + } // LFOUI* freqlfo + { Fl_Slider* o = detune = new Fl_Slider(60, 295, 295, 15); + detune->tooltip("Fine Detune (cents)"); + detune->type(5); + detune->box(FL_FLAT_BOX); + detune->minimum(-8192); + detune->maximum(8191); + detune->step(1); + detune->callback((Fl_Callback*)cb_detune); + o->value(pars->PDetune-8192); + } // Fl_Slider* detune + { Fl_Value_Output* o = detunevalueoutput = new Fl_Value_Output(12, 295, 45, 15, "Detune"); + detunevalueoutput->labelsize(10); + detunevalueoutput->minimum(-5000); + detunevalueoutput->maximum(5000); + detunevalueoutput->step(0.01); + detunevalueoutput->textfont(1); + detunevalueoutput->textsize(10); + detunevalueoutput->callback((Fl_Callback*)cb_detunevalueoutput); + detunevalueoutput->align(FL_ALIGN_TOP_LEFT); + o->value(getdetune(pars->PDetuneType,0,pars->PDetune)); + } // Fl_Value_Output* detunevalueoutput + { Fl_Choice* o = detunetype = new Fl_Choice(450, 335, 75, 15, "Detune Type"); + detunetype->down_box(FL_BORDER_BOX); + detunetype->labelsize(10); + detunetype->textfont(1); + detunetype->textsize(10); + detunetype->callback((Fl_Callback*)cb_detunetype); + detunetype->align(FL_ALIGN_TOP_LEFT); + o->add("L35cents");o->add("L10cents");o->add("E100cents");o->add("E1200cents"); + o->value(pars->PDetuneType-1); + } // Fl_Choice* detunetype + { Fl_Check_Button* o = hz440 = new Fl_Check_Button(365, 295, 50, 15, "440Hz"); + hz440->tooltip("set the base frequency to 440Hz"); + hz440->down_box(FL_DOWN_BOX); + hz440->labelfont(1); + hz440->labelsize(10); + hz440->callback((Fl_Callback*)cb_hz440); + o->value(pars->Pfixedfreq); + } // Fl_Check_Button* hz440 + { WidgetPDial* o = fixedfreqetdial = new WidgetPDial(420, 295, 15, 15, "Eq.T."); + fixedfreqetdial->tooltip("How the frequency varies acording to the keyboard (leftmost for fixed frequen\ +cy)"); + fixedfreqetdial->box(FL_ROUND_UP_BOX); + fixedfreqetdial->color(FL_BACKGROUND_COLOR); + fixedfreqetdial->selection_color(FL_INACTIVE_COLOR); + fixedfreqetdial->labeltype(FL_NORMAL_LABEL); + fixedfreqetdial->labelfont(0); + fixedfreqetdial->labelsize(10); + fixedfreqetdial->labelcolor(FL_FOREGROUND_COLOR); + fixedfreqetdial->maximum(127); + fixedfreqetdial->step(1); + fixedfreqetdial->callback((Fl_Callback*)cb_fixedfreqetdial); + fixedfreqetdial->align(FL_ALIGN_RIGHT); + fixedfreqetdial->when(FL_WHEN_CHANGED); + o->value(pars->PfixedfreqET); + if (pars->Pfixedfreq==0) o->deactivate(); + } // WidgetPDial* fixedfreqetdial + o->end(); + } // Fl_Group* o + { Fl_Group* o = new Fl_Group(5, 25, 240, 250, "AMPLITUDE"); + o->box(FL_THIN_UP_FRAME); + o->labeltype(FL_EMBOSSED_LABEL); + o->labelfont(1); + o->labelsize(13); + o->align(FL_ALIGN_TOP|FL_ALIGN_INSIDE); + { Fl_Value_Slider* o = volume = new Fl_Value_Slider(10, 50, 160, 15, "Vol"); + volume->tooltip("Volume"); + volume->type(5); + volume->box(FL_FLAT_BOX); + volume->labelsize(11); + volume->maximum(127); + volume->step(1); + volume->callback((Fl_Callback*)cb_volume); + volume->align(FL_ALIGN_RIGHT); + o->value(pars->PVolume); + } // Fl_Value_Slider* volume + { Fl_Value_Slider* o = vsns = new Fl_Value_Slider(10, 70, 160, 15, "V.Sns"); + vsns->tooltip("Velocity Sensing Function (rightmost to disable)"); + vsns->type(5); + vsns->box(FL_FLAT_BOX); + vsns->labelsize(11); + vsns->maximum(127); + vsns->step(1); + vsns->callback((Fl_Callback*)cb_vsns); + vsns->align(FL_ALIGN_RIGHT); + o->value(pars->PAmpVelocityScaleFunction); + } // Fl_Value_Slider* vsns + { WidgetPDial* o = pan = new WidgetPDial(210, 45, 30, 30, "Pan"); + pan->tooltip("Panning (leftmost is Random)"); + pan->box(FL_ROUND_UP_BOX); + pan->color(FL_BACKGROUND_COLOR); + pan->selection_color(FL_INACTIVE_COLOR); + pan->labeltype(FL_NORMAL_LABEL); + pan->labelfont(0); + pan->labelsize(10); + pan->labelcolor(FL_FOREGROUND_COLOR); + pan->maximum(127); + pan->step(1); + pan->callback((Fl_Callback*)cb_pan); + pan->align(FL_ALIGN_BOTTOM); + pan->when(FL_WHEN_CHANGED); + o->value(pars->PPanning); + } // WidgetPDial* pan + { WidgetPDial* o = pstr = new WidgetPDial(125, 247, 25, 25, "P.Str."); + pstr->tooltip("Punch Strength"); + pstr->box(FL_ROUND_UP_BOX); + pstr->color(FL_BACKGROUND_COLOR); + pstr->selection_color(FL_INACTIVE_COLOR); + pstr->labeltype(FL_NORMAL_LABEL); + pstr->labelfont(0); + pstr->labelsize(10); + pstr->labelcolor(FL_FOREGROUND_COLOR); + pstr->maximum(127); + pstr->step(1); + pstr->callback((Fl_Callback*)cb_pstr); + pstr->align(FL_ALIGN_TOP); + pstr->when(FL_WHEN_CHANGED); + o->value(pars->PPunchStrength); + } // WidgetPDial* pstr + { WidgetPDial* o = pt = new WidgetPDial(155, 247, 25, 25, "P.t."); + pt->tooltip("Punch Time (duration)"); + pt->box(FL_ROUND_UP_BOX); + pt->color(FL_BACKGROUND_COLOR); + pt->selection_color(FL_INACTIVE_COLOR); + pt->labeltype(FL_NORMAL_LABEL); + pt->labelfont(0); + pt->labelsize(10); + pt->labelcolor(FL_FOREGROUND_COLOR); + pt->maximum(127); + pt->step(1); + pt->callback((Fl_Callback*)cb_pt); + pt->align(FL_ALIGN_TOP); + pt->when(FL_WHEN_CHANGED); + o->value(pars->PPunchTime); + } // WidgetPDial* pt + { WidgetPDial* o = pstc = new WidgetPDial(185, 247, 25, 25, "P.Stc."); + pstc->tooltip("Punch Stretch"); + pstc->box(FL_ROUND_UP_BOX); + pstc->color(FL_BACKGROUND_COLOR); + pstc->selection_color(FL_INACTIVE_COLOR); + pstc->labeltype(FL_NORMAL_LABEL); + pstc->labelfont(0); + pstc->labelsize(10); + pstc->labelcolor(FL_FOREGROUND_COLOR); + pstc->maximum(127); + pstc->step(1); + pstc->callback((Fl_Callback*)cb_pstc); + pstc->align(FL_ALIGN_TOP); + pstc->when(FL_WHEN_CHANGED); + o->value(pars->PPunchStretch); + } // WidgetPDial* pstc + { WidgetPDial* o = pvel = new WidgetPDial(215, 247, 25, 25, "P.Vel."); + pvel->tooltip("Punch Velocity Sensing"); + pvel->box(FL_ROUND_UP_BOX); + pvel->color(FL_BACKGROUND_COLOR); + pvel->selection_color(FL_INACTIVE_COLOR); + pvel->labeltype(FL_NORMAL_LABEL); + pvel->labelfont(0); + pvel->labelsize(10); + pvel->labelcolor(FL_FOREGROUND_COLOR); + pvel->maximum(127); + pvel->step(1); + pvel->callback((Fl_Callback*)cb_pvel); + pvel->align(FL_ALIGN_TOP); + pvel->when(FL_WHEN_CHANGED); + o->value(pars->PPunchVelocitySensing); + } // WidgetPDial* pvel + { EnvelopeUI* o = ampenv = new EnvelopeUI(10, 95, 205, 70, "PADSynth - Amplitude Envelope"); + ampenv->box(FL_FLAT_BOX); + ampenv->color((Fl_Color)51); + ampenv->selection_color(FL_BACKGROUND_COLOR); + ampenv->labeltype(FL_NORMAL_LABEL); + ampenv->labelfont(0); + ampenv->labelsize(14); + ampenv->labelcolor(FL_FOREGROUND_COLOR); + ampenv->align(FL_ALIGN_WRAP|FL_ALIGN_INSIDE); + ampenv->when(FL_WHEN_RELEASE); + o->init(pars->AmpEnvelope); + ampenv->end(); + } // EnvelopeUI* ampenv + { LFOUI* o = amplfo = new LFOUI(10, 165, 230, 70, "Amplitude LFO "); + amplfo->box(FL_FLAT_BOX); + amplfo->color(FL_DARK1); + amplfo->selection_color(FL_BACKGROUND_COLOR); + amplfo->labeltype(FL_NORMAL_LABEL); + amplfo->labelfont(0); + amplfo->labelsize(14); + amplfo->labelcolor(FL_FOREGROUND_COLOR); + amplfo->align(FL_ALIGN_WRAP|FL_ALIGN_INSIDE); + amplfo->when(FL_WHEN_RELEASE); + o->init(pars->AmpLfo); + amplfo->end(); + } // LFOUI* amplfo + { Fl_Check_Button* o = stereo = new Fl_Check_Button(15, 245, 70, 25, "Stereo"); + stereo->down_box(FL_DOWN_BOX); + stereo->callback((Fl_Callback*)cb_stereo); + o->value(pars->PStereo); + } // Fl_Check_Button* stereo + o->end(); + } // Fl_Group* o + { Fl_Group* o = new Fl_Group(245, 25, 285, 250, "FILTER"); + o->box(FL_THIN_UP_BOX); + o->labeltype(FL_EMBOSSED_LABEL); + o->labelfont(1); + o->labelsize(13); + o->align(FL_ALIGN_TOP|FL_ALIGN_INSIDE); + { EnvelopeUI* o = filterenv = new EnvelopeUI(250, 130, 275, 70, "PADSynth - Filter Envelope"); + filterenv->box(FL_FLAT_BOX); + filterenv->color((Fl_Color)51); + filterenv->selection_color(FL_BACKGROUND_COLOR); + filterenv->labeltype(FL_NORMAL_LABEL); + filterenv->labelfont(0); + filterenv->labelsize(14); + filterenv->labelcolor(FL_FOREGROUND_COLOR); + filterenv->align(FL_ALIGN_WRAP|FL_ALIGN_INSIDE); + filterenv->when(FL_WHEN_RELEASE); + o->init(pars->FilterEnvelope); + filterenv->end(); + } // EnvelopeUI* filterenv + { LFOUI* o = filterlfo = new LFOUI(250, 200, 230, 70, "Filter LFO "); + filterlfo->box(FL_FLAT_BOX); + filterlfo->color(FL_DARK1); + filterlfo->selection_color(FL_BACKGROUND_COLOR); + filterlfo->labeltype(FL_NORMAL_LABEL); + filterlfo->labelfont(0); + filterlfo->labelsize(14); + filterlfo->labelcolor(FL_FOREGROUND_COLOR); + filterlfo->align(FL_ALIGN_WRAP|FL_ALIGN_INSIDE); + filterlfo->when(FL_WHEN_RELEASE); + o->init(pars->FilterLfo); + filterlfo->end(); + } // LFOUI* filterlfo + { FilterUI* o = filterui = new FilterUI(250, 55, 275, 75, "PADsynth - Filter"); + filterui->box(FL_FLAT_BOX); + filterui->color(FL_LIGHT1); + filterui->selection_color(FL_BACKGROUND_COLOR); + filterui->labeltype(FL_NORMAL_LABEL); + filterui->labelfont(0); + filterui->labelsize(14); + filterui->labelcolor(FL_FOREGROUND_COLOR); + filterui->align(FL_ALIGN_WRAP|FL_ALIGN_INSIDE); + filterui->when(FL_WHEN_RELEASE); + o->init(pars->GlobalFilter,&pars->PFilterVelocityScale,&pars->PFilterVelocityScaleFunction); + filterui->end(); + } // FilterUI* filterui + o->end(); + } // Fl_Group* o + o->end(); + } // Fl_Group* o + o->end(); + } // Fl_Tabs* o + { Fl_Button* o = applybutton = new Fl_Button(45, 405, 185, 40, "Apply Changes"); + applybutton->box(FL_THIN_UP_BOX); + applybutton->labelfont(1); + applybutton->labelsize(16); + applybutton->callback((Fl_Callback*)cb_applybutton); + o->color(FL_RED); + } // Fl_Button* applybutton + { Fl_Button* o = new Fl_Button(320, 405, 175, 40, "Close"); + o->box(FL_THIN_UP_BOX); + o->labelsize(17); + o->callback((Fl_Callback*)cb_Close); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(240, 430, 25, 15, "C"); + o->box(FL_THIN_UP_BOX); + o->color((Fl_Color)179); + o->labelfont(1); + o->labelsize(11); + o->labelcolor(FL_BACKGROUND2_COLOR); + o->callback((Fl_Callback*)cb_C); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(270, 430, 25, 15, "P"); + o->box(FL_THIN_UP_BOX); + o->color((Fl_Color)179); + o->labelfont(1); + o->labelsize(11); + o->labelcolor(FL_BACKGROUND2_COLOR); + o->callback((Fl_Callback*)cb_P); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(240, 405, 55, 15, "export"); + o->tooltip("export samples as wav file"); + o->box(FL_THIN_UP_BOX); + o->color(FL_WHITE); + o->labelsize(11); + o->callback((Fl_Callback*)cb_export); + o->align(FL_ALIGN_WRAP); + } // Fl_Button* o + padnotewindow->end(); + } // Fl_Double_Window* padnotewindow + return padnotewindow; +} + +void PADnoteUI::refresh() { + volume->value(pars->PVolume); +vsns->value(pars->PAmpVelocityScaleFunction); +pan->value(pars->PPanning); + +stereo->value(pars->PStereo); + + +pstr->value(pars->PPunchStrength); +pt->value(pars->PPunchTime); +pstc->value(pars->PPunchStretch); +pvel->value(pars->PPunchVelocitySensing); + +detunevalueoutput->value(getdetune(pars->PDetuneType,0,pars->PDetune)); +detune->value(pars->PDetune-8192); + +int k=pars->PCoarseDetune/1024;if (k>=8) k-=16; +octave->value(k); + +detunetype->value(pars->PDetuneType-1); +k=pars->PCoarseDetune%1024;if (k>=512) k-=1024; +coarsedet->value(k); + +hz440->value(pars->Pfixedfreq); +fixedfreqetdial->value(pars->PfixedfreqET); + +amplfo->refresh(); +freqlfo->refresh(); +filterlfo->refresh(); + +ampenv->refresh(); +freqenv->refresh(); +filterenv->refresh(); +filterui->refresh(); + + +/* harmonic structure parametrs */ + +resui->refresh(); +if (oscui!=NULL) oscui->refresh(); + +hpbasetype->value(pars->Php.base.type); +hpbasepar1->value(pars->Php.base.par1); +hpfreqmult->value(pars->Php.freqmult); + +hpmpar1->value(pars->Php.modulator.par1); +hpmfreq->value(pars->Php.modulator.freq); +hpwidth->value(pars->Php.width); + +hponehalf->value(pars->Php.onehalf); +hpamptype->value(pars->Php.amp.type); +hpampmode->value(pars->Php.amp.mode); +hpamppar1->value(pars->Php.amp.par1); +hpamppar2->value(pars->Php.amp.par2); +hpautoscale->value(pars->Php.autoscale); + +bwdial->value(pars->Pbandwidth); +if (pars->Pmode==0){ + bwprofilegroup->activate(); + bwdial->activate(); + bwcents->activate(); + hprofile->activate(); + hprofile->color(54); + bwscale->activate(); +} else { + bwprofilegroup->deactivate(); + bwdial->deactivate(); + bwcents->deactivate(); + hprofile->deactivate(); + hprofile->color(48); + bwscale->activate(); +}; + +spectrummode->value(pars->Pmode); + +qbasenote->value(pars->Pquality.basenote); +qsmpoct->value(pars->Pquality.smpoct); +qoct->value(pars->Pquality.oct); +qsamplesize->value(pars->Pquality.samplesize); + +hrpostype->value(pars->Phrpos.type); +hrpospar1->value(pars->Phrpos.par1); +hrpospar2->value(pars->Phrpos.par2); +hrpospar3->value(pars->Phrpos.par3); + +hprofile->redraw(); +overtonepos->redraw(); + +osc->redraw(); +pars->applyparameters(true); +applybutton->color(FL_GRAY); +applybutton->parent()->redraw(); +} + +PADnoteUI::~PADnoteUI() { + delete(oscui); +delete(resui); + +padnotewindow->hide(); +delete(padnotewindow); +} diff --git a/plugins/zynaddsubfx/src/UI/PADnoteUI.fl b/plugins/zynaddsubfx/src/UI/PADnoteUI.fl new file mode 100644 index 000000000..74441c199 --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/PADnoteUI.fl @@ -0,0 +1,1101 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0107 +header_name {.h} +code_name {.cc} +decl {\#include "../Params/PADnoteParameters.h"} {public +} + +decl {\#include "../Misc/Util.h"} {public +} + +decl {\#include "../Misc/Master.h"} {public +} + +decl {\#include "ResonanceUI.h"} {public +} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include } {} + +decl {\#include } {} + +decl {\#include } {} + +decl {\#include } {} + +decl {\#include "WidgetPDial.h"} {public +} + +decl {\#include "EnvelopeUI.h"} {public +} + +decl {\#include "LFOUI.h"} {public +} + +decl {\#include "FilterUI.h"} {public +} + +decl {\#include "OscilGenUI.h"} {public +} + +decl {\#include "PresetsUI.h"} {public +} + +class PADnoteHarmonicProfile {: {public Fl_Box} +} { + Function {PADnoteHarmonicProfile(int x,int y, int w, int h, const char *label=0):Fl_Box(x,y,w,h,label)} {} { + code {pars=NULL;} {} + } + Function {init(PADnoteParameters *pars,Master *master_)} {} { + code {master=master_; +this->pars=pars;} {} + } + Function {draw()} {} { + code {int ox=x(),oy=y(),lx=w(),ly=h(); +if (!visible()) return; +REALTYPE smps[lx]; + +REALTYPE realbw=pars->getprofile(smps,lx); +bool active=active_r(); + +//draw the equivalent bandwidth +if (active) fl_color(220,220,220); + else fl_color(160,165,165); +fl_line_style(0); +int rbw=(int)(realbw*(lx-1.0)/2.0); +for (int i=lx/2-rbw;i<(lx/2+rbw);i++) fl_line(ox+i,oy,ox+i,oy+ly-1); + +fl_line_style(0); +if (active) fl_color(200,200,200); + else fl_color(160,160,160); +for (int i=1;i<10;i++){ + int kx=(int)(lx/10.0*i); + fl_line(ox+kx,oy,ox+kx,oy+ly-1); +}; +for (int i=1;i<5;i++){ + int ky=(int)(ly/5.0*i); + fl_line(ox,oy+ly-ky,ox+lx,oy+ly-ky-1); +}; + + +fl_color(120,120,120); +fl_line_style(FL_DOT); +fl_line(ox+lx/2,oy,ox+lx/2,oy+ly); + +//draw the graph +fl_line_style(0); +int old=0; +for (int i=0;i0) fl_line(ox+i-1,oy+ly-2-old,ox+i,oy+ly-2-val); + old=val; +}; + + +fl_line_style(FL_DASH); +if (active) fl_color(0,100,220); + else fl_color(150,160,170); +fl_line(ox+lx/2-rbw,oy,ox+lx/2-rbw,oy+ly-1); +fl_line(ox+lx/2+rbw,oy,ox+lx/2+rbw,oy+ly-1); + +fl_line_style(0);} {} + } + decl {Master *master;} {} + decl {PADnoteParameters *pars;} {public + } +} + +class PADnoteOvertonePosition {: {public Fl_Box} +} { + Function {PADnoteOvertonePosition(int x,int y, int w, int h, const char *label=0):Fl_Box(x,y,w,h,label)} {} { + code {pars=NULL;} {} + } + Function {init(PADnoteParameters *pars,Master *master_)} {} { + code {master=master_; +this->pars=pars;} {} + } + Function {draw()} {} { + code {if (!visible()) return; +const int maxdb=60; + +int ox=x(),oy=y(),lx=w(),ly=h(); +const int maxharmonic=64; + + +for (int i=1;imutex); +pars->oscilgen->getspectrum(n,spc,0); +pthread_mutex_unlock(&master->mutex); + + +//normalize +REALTYPE max=0; +for (int i=0;igetNhr(i); + int kx=(int)(lx/(REALTYPE)maxharmonic*nhr); + if ((kx<0)||(kx>lx)) continue; + + spectrum[kx]=spc[i-1]/max+1e-9; + +}; + +fl_color(180,0,0); +fl_line_style(0); + +if (pars->Pmode==2){ + int old=0; + for (int i=1;i1e-10)||(i==(lx-1))){ + int delta=i-old; + REALTYPE val1=spectrum[old]; + REALTYPE val2=spectrum[i]; + + REALTYPE idelta=1.0/delta; + for (int j=0;jdB2rap(-maxdb)) x=rap2dB(x)/maxdb+1; + else continue; + int yy=(int)(x*ly); + fl_line(ox+i,oy+ly-1-yy,ox+i,oy+ly-1); + +};} {} + } + decl {Master *master;} {} + decl {PADnoteParameters *pars;} {public + } +} + +class PADnoteUI {open : {public PresetsUI_} +} { + Function {PADnoteUI(PADnoteParameters *parameters,Master *master_)} {open + } { + code {pars=parameters; +master=master_; +oscui=NULL; +resui=new ResonanceUI(pars->resonance); +make_window();} {} + } + Function {make_window()} {open + } { + Fl_Window padnotewindow { + label {PAD synth Parameters} open + xywh {281 302 535 450} type Double visible + } { + Fl_Tabs {} { + callback {if (o->value()!=harmonicstructuregroup) applybutton->hide(); + else applybutton->show();} + xywh {0 0 535 395} + } { + Fl_Group harmonicstructuregroup { + label {Harmonic Structure} + xywh {0 20 535 375} box ENGRAVED_BOX + } { + Fl_Group bwprofilegroup { + xywh {5 30 90 260} box ENGRAVED_BOX + code0 {if (pars->Pmode!=0) o->deactivate();} + } { + Fl_Dial hpbasepar1 { + label Width + callback {pars->Php.base.par1=(int) o->value(); +hprofile->redraw(); +cbwidget->do_callback();} + xywh {20 75 25 25} box ROUND_UP_BOX labelsize 10 align 1 maximum 127 step 1 + code0 {o->value(pars->Php.base.par1);} + class WidgetPDial + } + Fl_Choice hpbasetype { + label {Base Type} + callback {pars->Php.base.type=o->value(); +hprofile->redraw(); +cbwidget->do_callback();} + xywh {15 45 75 15} down_box BORDER_BOX labelsize 10 align 5 textsize 10 + code0 {o->value(pars->Php.base.type);} + } { + MenuItem {} { + label Gauss + xywh {15 15 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Square + xywh {25 25 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label DoubleExp + xywh {35 35 100 20} labelfont 1 labelsize 10 + } + } + Fl_Dial hpfreqmult { + label FreqMlt + callback {pars->Php.freqmult=(int) o->value(); +hprofile->redraw(); +cbwidget->do_callback();} + xywh {55 75 25 25} box ROUND_UP_BOX labelsize 10 align 1 maximum 127 step 1 + code0 {o->value(pars->Php.freqmult);} + class WidgetPDial + } + Fl_Dial hpmpar1 { + label Str + callback {pars->Php.modulator.par1=(int) o->value(); +hprofile->redraw(); +cbwidget->do_callback();} + xywh {15 115 20 20} box ROUND_UP_BOX labelsize 10 align 1 maximum 127 step 1 + code0 {o->value(pars->Php.modulator.par1);} + class WidgetPDial + } + Fl_Dial hpmfreq { + label SFreq + callback {pars->Php.modulator.freq=(int) o->value(); +hprofile->redraw(); +cbwidget->do_callback();} + xywh {40 115 20 20} box ROUND_UP_BOX labelsize 10 align 1 maximum 127 step 1 + code0 {o->value(pars->Php.modulator.freq);} + class WidgetPDial + } + Fl_Group {} { + xywh {10 160 80 105} box BORDER_BOX + } { + Fl_Choice hpamptype { + label AmpMultiplier + callback {pars->Php.amp.type=o->value(); +hprofile->redraw(); +cbwidget->do_callback();} + xywh {15 175 70 15} down_box BORDER_BOX labelsize 10 align 5 textsize 10 + code0 {o->value(pars->Php.amp.type);} + } { + MenuItem {} { + label OFF + xywh {45 45 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Gauss + xywh {55 55 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Sine + xywh {65 65 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Flat + xywh {75 75 100 20} labelfont 1 labelsize 10 + } + } + Fl_Choice hpampmode { + label AmpMode + callback {pars->Php.amp.mode=o->value(); +hprofile->redraw(); +cbwidget->do_callback();} + xywh {15 205 70 15} down_box BORDER_BOX labelsize 10 align 5 textsize 10 + code0 {o->value(pars->Php.amp.mode);} + } { + MenuItem {} { + label Sum + xywh {60 60 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Mult + xywh {70 70 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Div1 + xywh {80 80 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Div2 + xywh {90 90 100 20} labelfont 1 labelsize 10 + } + } + Fl_Dial hpamppar1 { + label Par1 + callback {pars->Php.amp.par1=(int) o->value(); +hprofile->redraw(); +cbwidget->do_callback();} + xywh {15 235 25 25} box ROUND_UP_BOX labelsize 10 align 1 maximum 127 step 1 + code0 {o->value(pars->Php.amp.par1);} + class WidgetPDial + } + Fl_Dial hpamppar2 { + label Par2 + callback {pars->Php.amp.par2=(int) o->value(); +hprofile->redraw(); +cbwidget->do_callback();} + xywh {55 235 25 25} box ROUND_UP_BOX labelsize 10 align 1 maximum 127 step 1 + code0 {o->value(pars->Php.amp.par2);} + class WidgetPDial + } + } + Fl_Check_Button hpautoscale { + label autoscale + callback {pars->Php.autoscale=(int) o->value(); +hprofile->redraw(); +cbwidget->do_callback();} + xywh {10 270 60 15} down_box DOWN_BOX labelsize 10 + code0 {o->value(pars->Php.autoscale);} + } + Fl_Choice hponehalf { + callback {pars->Php.onehalf=o->value(); +hprofile->redraw(); +cbwidget->do_callback();} + xywh {10 143 80 15} down_box BORDER_BOX labelsize 10 align 5 textsize 10 + code0 {o->value(pars->Php.onehalf);} + } { + MenuItem {} { + label Full + xywh {25 25 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label {Upper Half} + xywh {45 45 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label {Lower Half} + xywh {35 35 100 20} labelfont 1 labelsize 10 + } + } + Fl_Dial hpwidth { + label Size + callback {pars->Php.width=(int) o->value(); +hprofile->redraw(); +cbwidget->do_callback();} + xywh {65 115 20 20} box ROUND_UP_BOX labelsize 10 align 1 maximum 127 step 1 + code0 {o->value(pars->Php.width);} + class WidgetPDial + } + } + Fl_Group {} { + xywh {100 155 270 135} box THIN_DOWN_BOX color 32 selection_color 71 labelcolor 179 align 6 + code0 {osc=new Oscilloscope(o->x(),o->y(),o->w(),o->h(),"");} + code1 {osc->init(pars->oscilgen,master);} + } {} + Fl_Button {} { + label Change + callback {if (oscui!=NULL) delete (oscui); +oscui=new OscilEditor(pars->oscilgen,osc,cbwidget,applybutton,master);} + xywh {375 270 60 20} box THIN_UP_BOX labelfont 1 labelsize 11 + } + Fl_Box cbwidget { + label {Harmonic Content} + callback {overtonepos->redraw(); +applybutton->color(FL_RED); +applybutton->redraw();} + xywh {125 135 205 20} align 16 + } + Fl_Button {} { + label Resonance + callback {resui->resonancewindow->redraw(); +resui->resonancewindow->show(); +resui->setcbwidget(cbwidget,applybutton);} + xywh {375 225 80 20} box THIN_UP_BOX + } + Fl_Dial bwdial { + label BandWidth + callback {bwcents->value(pars->setPbandwidth((int) o->value())); +cbwidget->do_callback();} + xywh {15 295 35 35} box ROUND_UP_BOX labelsize 10 maximum 1000 step 1 + code0 {o->value(pars->Pbandwidth);} + code1 {if (pars->Pmode!=0) o->deactivate();} + class WidgetPDial + } + Fl_Value_Output bwcents { + label cents + xywh {55 305 55 15} labelsize 10 align 6 maximum 10000 step 0.1 + code0 {o->value(pars->setPbandwidth(pars->Pbandwidth));} + code1 {if (pars->Pmode!=0) o->deactivate();} + } + Fl_Group {} { + xywh {315 295 215 45} box ENGRAVED_BOX + } { + Fl_Choice hrpostype { + label OvertonesPosition + callback {pars->Phrpos.type=o->value(); +overtonepos->redraw(); +cbwidget->do_callback();} + xywh {325 310 80 20} down_box BORDER_BOX labelsize 10 align 5 textsize 11 + code0 {o->value(pars->Phrpos.type);} + } { + MenuItem {} { + label Harmonic + xywh {70 70 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label ShiftU + xywh {80 80 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label ShiftL + xywh {90 90 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label PowerU + xywh {90 90 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label PowerL + xywh {100 100 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label Sine + xywh {110 110 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label Power + xywh {120 120 100 20} labelfont 1 labelsize 11 + } + } + Fl_Dial hrpospar1 { + label Par1 + callback {pars->Phrpos.par1=(int) o->value(); +overtonepos->redraw(); +cbwidget->do_callback();} + xywh {425 310 25 25} box ROUND_UP_BOX labelsize 10 align 1 maximum 255 step 1 + code0 {o->value(pars->Phrpos.par1);} + class WidgetPDial + } + Fl_Dial hrpospar2 { + label Par2 + callback {pars->Phrpos.par2=(int) o->value(); +overtonepos->redraw(); +cbwidget->do_callback();} + xywh {460 310 25 25} box ROUND_UP_BOX labelsize 10 align 1 maximum 255 step 1 + code0 {o->value(pars->Phrpos.par2);} + class WidgetPDial + } + Fl_Dial hrpospar3 { + label ForceH + callback {pars->Phrpos.par3=(int) o->value(); +overtonepos->redraw(); +cbwidget->do_callback();} + xywh {495 310 25 25} box ROUND_UP_BOX labelsize 10 align 1 maximum 255 step 1 + code0 {o->value(pars->Phrpos.par3);} + class WidgetPDial + } + } + Fl_Choice bwscale { + label {Bandwidth Scale} + callback {pars->Pbwscale=(int) o->value(); +cbwidget->do_callback();} + xywh {120 305 80 20} down_box BORDER_BOX labelsize 10 align 5 textsize 11 + code0 {o->value(pars->Pbwscale);} + code1 {if (pars->Pmode!=0) o->deactivate();} + } { + MenuItem {} { + label Normal + xywh {95 95 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label EqualHz + xywh {105 105 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label Quater + xywh {115 115 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label Half + xywh {125 125 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label {75%} + xywh {135 135 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label {150%} + xywh {145 145 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label Double + xywh {145 145 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label {Inv.Half} + xywh {155 155 100 20} labelfont 1 labelsize 11 + } + } + Fl_Group overtonepos { + xywh {5 345 525 45} box FLAT_BOX color 54 selection_color 218 labelcolor 63 + code0 {PADnoteOvertonePosition *opui=new PADnoteOvertonePosition(o->x(),o->y(),o->w(),o->h(),"");} + code1 {opui->init(pars,master);} + } {} + Fl_Choice qsamplesize { + label {Sample Size} + callback {pars->Pquality.samplesize=(int) o->value(); +cbwidget->do_callback();} + xywh {375 190 115 20} down_box BORDER_BOX labelsize 10 align 5 textsize 11 + code0 {o->value(pars->Pquality.samplesize);} + } { + MenuItem {} { + label {16k (Tiny)} + xywh {155 155 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label 32k + xywh {165 165 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label {64k (Small)} + xywh {175 175 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label 128k + xywh {185 185 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label {256k (Normal)} + xywh {205 205 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label 512k + xywh {200 200 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label {1M (Big)} + xywh {205 205 100 20} labelfont 1 labelsize 11 + } + } + Fl_Choice qsmpoct { + label {smp/oct} + callback {pars->Pquality.smpoct=(int) o->value(); +cbwidget->do_callback();} + xywh {430 155 45 20} down_box BORDER_BOX labelsize 11 align 5 textsize 11 + code0 {o->value(pars->Pquality.smpoct);} + } { + MenuItem {} { + label {0.5} + xywh {10 10 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label 1 + xywh {0 0 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label 2 + xywh {10 10 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label 3 + xywh {20 20 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label 4 + xywh {30 30 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label 6 + xywh {40 40 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label 12 + xywh {50 50 100 20} labelfont 1 labelsize 11 + } + } + Fl_Choice qoct { + label {no.oct} + callback {pars->Pquality.oct=(int) o->value(); +cbwidget->do_callback();} + xywh {480 155 45 20} down_box BORDER_BOX labelsize 11 align 5 textsize 11 + code0 {o->value(pars->Pquality.oct);} + } { + MenuItem {} { + label 1 + xywh {10 10 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label 2 + xywh {20 20 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label 3 + xywh {30 30 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label 4 + xywh {40 40 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label 5 + xywh {50 50 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label 6 + xywh {60 60 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label 7 + xywh {70 70 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label 8 + xywh {80 80 100 20} labelfont 1 labelsize 11 + } + } + Fl_Choice qbasenote { + label base + callback {pars->Pquality.basenote=(int) o->value(); +cbwidget->do_callback();} + xywh {375 155 50 20} down_box BORDER_BOX labelsize 11 align 5 textsize 11 + code0 {o->value(pars->Pquality.basenote);} + } { + MenuItem {} { + label {C-2} + xywh {10 10 100 20} labelfont 1 + } + MenuItem {} { + label {G-2} + xywh {20 20 100 20} labelfont 1 + } + MenuItem {} { + label {C-3} + xywh {20 20 100 20} labelfont 1 + } + MenuItem {} { + label {G-3} + xywh {30 30 100 20} labelfont 1 + } + MenuItem {} { + label {C-4} + xywh {30 30 100 20} labelfont 1 + } + MenuItem {} { + label {G-4} + xywh {40 40 100 20} labelfont 1 + } + MenuItem {} { + label {C-5} + xywh {40 40 100 20} labelfont 1 + } + MenuItem {} { + label {G-5} + xywh {50 50 100 20} labelfont 1 + } + MenuItem {} { + label {G-6} + xywh {60 60 100 20} labelfont 1 + } + } + Fl_Group hprofile { + xywh {100 45 430 90} box FLAT_BOX color 54 selection_color 218 labelcolor 63 + code0 {PADnoteHarmonicProfile *hpui=new PADnoteHarmonicProfile(o->x(),o->y(),o->w(),o->h(),"");} + code1 {hpui->init(pars,master);} + code2 {if (pars->Pmode!=0) { o->deactivate(); o->color(48);};} + } {} + Fl_Box {} { + label {Profile of One Harmonic (Frequency Distribution)} + xywh {160 25 315 20} + } + Fl_Choice spectrummode { + label {Spectrum Mode} + callback {pars->Pmode=(int) o->value(); + +if (pars->Pmode==0){ + bwprofilegroup->activate(); + bwdial->activate(); + bwcents->activate(); + hprofile->activate(); + hprofile->color(54); + bwscale->activate(); +} else { + bwprofilegroup->deactivate(); + bwdial->deactivate(); + bwcents->deactivate(); + hprofile->deactivate(); + hprofile->color(48); + bwscale->deactivate(); +}; + +cbwidget->do_callback();} + xywh {220 305 90 20} down_box BORDER_BOX labelfont 1 labelsize 10 align 5 textsize 11 + code0 {o->value(pars->Pmode);} + } { + MenuItem {} { + label Bandwidth + xywh {105 105 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label Discrete + xywh {125 125 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label Continous + xywh {115 115 100 20} labelfont 1 labelsize 11 + } + } + } + Fl_Group {} { + label {Envelopes&LFOs} + xywh {0 20 535 375} box ENGRAVED_BOX hide + } { + Fl_Group {} { + label FREQUENCY + xywh {5 275 525 115} box THIN_UP_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 13 align 17 + } { + Fl_Group freqenv { + label {PADSynth - Frequency Envelope} open + xywh {10 315 205 70} box FLAT_BOX color 51 align 144 + code0 {o->init(pars->FreqEnvelope);} + class EnvelopeUI + } {} + Fl_Counter octave { + label Octave + callback {int k=(int) o->value(); +if (k<0) k+=16; +pars->PCoarseDetune = k*1024+ + pars->PCoarseDetune%1024;} + tooltip Octave xywh {470 295 45 15} type Simple labelsize 10 align 1 minimum -8 maximum 7 step 1 textfont 1 textsize 11 + code0 {int k=pars->PCoarseDetune/1024;} + code1 {if (k>=8) k-=16;} + code2 {o->value(k);} + } + Fl_Counter coarsedet { + label {Coarse det.} + callback {int k=(int) o->value(); +if (k<0) k+=1024; +pars->PCoarseDetune = k+ + (pars->PCoarseDetune/1024)*1024;} + tooltip {Coarse Detune} xywh {455 365 60 20} labelsize 10 align 5 minimum -64 maximum 63 step 1 textfont 1 textsize 11 + code0 {int k=pars->PCoarseDetune%1024;} + code1 {if (k>=512) k-=1024;} + code2 {o->value(k);} + code3 {o->lstep(10);} + } + Fl_Group freqlfo { + label {Frequency LFO } open + xywh {215 315 230 70} box FLAT_BOX color 47 align 144 + code0 {o->init(pars->FreqLfo);} + class LFOUI + } {} + Fl_Slider detune { + callback {pars->PDetune=(int)o->value()+8192; +detunevalueoutput->do_callback();} + tooltip {Fine Detune (cents)} xywh {60 295 295 15} type {Horz Knob} box FLAT_BOX minimum -8192 maximum 8191 step 1 + code0 {o->value(pars->PDetune-8192);} + } + Fl_Value_Output detunevalueoutput { + label Detune + callback {o->value(getdetune(pars->PDetuneType,0,pars->PDetune));} + xywh {12 295 45 15} labelsize 10 align 5 minimum -5000 maximum 5000 step 0.01 textfont 1 textsize 10 + code0 {o->value(getdetune(pars->PDetuneType,0,pars->PDetune));} + } + Fl_Choice detunetype { + label {Detune Type} + callback {pars->PDetuneType=(int) o->value()+1; +detunevalueoutput->do_callback();} open + xywh {450 335 75 15} down_box BORDER_BOX labelsize 10 align 5 textfont 1 textsize 10 + code0 {o->add("L35cents");o->add("L10cents");o->add("E100cents");o->add("E1200cents");} + code1 {o->value(pars->PDetuneType-1);} + } {} + Fl_Check_Button hz440 { + label 440Hz + callback {int x=(int) o->value(); +pars->Pfixedfreq=x; +if (x==0) fixedfreqetdial->deactivate(); + else fixedfreqetdial->activate();} + tooltip {set the base frequency to 440Hz} xywh {365 295 50 15} down_box DOWN_BOX labelfont 1 labelsize 10 + code0 {o->value(pars->Pfixedfreq);} + } + Fl_Dial fixedfreqetdial { + label {Eq.T.} + callback {pars->PfixedfreqET=(int) o->value();} + tooltip {How the frequency varies acording to the keyboard (leftmost for fixed frequency)} xywh {420 295 15 15} box ROUND_UP_BOX labelsize 10 align 8 maximum 127 step 1 + code0 {o->value(pars->PfixedfreqET);} + code1 {if (pars->Pfixedfreq==0) o->deactivate();} + class WidgetPDial + } + } + Fl_Group {} { + label AMPLITUDE + xywh {5 25 240 250} box THIN_UP_FRAME labeltype EMBOSSED_LABEL labelfont 1 labelsize 13 align 17 + } { + Fl_Value_Slider volume { + label Vol + callback {pars->PVolume=(int)o->value();} + tooltip Volume xywh {10 50 160 15} type {Horz Knob} box FLAT_BOX labelsize 11 align 8 maximum 127 step 1 + code0 {o->value(pars->PVolume);} + } + Fl_Value_Slider vsns { + label {V.Sns} + callback {pars->PAmpVelocityScaleFunction=(int) o->value();} + tooltip {Velocity Sensing Function (rightmost to disable)} xywh {10 70 160 15} type {Horz Knob} box FLAT_BOX labelsize 11 align 8 maximum 127 step 1 + code0 {o->value(pars->PAmpVelocityScaleFunction);} + } + Fl_Dial pan { + label Pan + callback {pars->PPanning=(int) o->value();} + tooltip {Panning (leftmost is Random)} xywh {210 45 30 30} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + code0 {o->value(pars->PPanning);} + class WidgetPDial + } + Fl_Dial pstr { + label {P.Str.} + callback {pars->PPunchStrength=(int) o->value();} + tooltip {Punch Strength} xywh {125 247 25 25} box ROUND_UP_BOX labelsize 10 align 1 maximum 127 step 1 + code0 {o->value(pars->PPunchStrength);} + class WidgetPDial + } + Fl_Dial pt { + label {P.t.} + callback {pars->PPunchTime=(int) o->value();} + tooltip {Punch Time (duration)} xywh {155 247 25 25} box ROUND_UP_BOX labelsize 10 align 1 maximum 127 step 1 + code0 {o->value(pars->PPunchTime);} + class WidgetPDial + } + Fl_Dial pstc { + label {P.Stc.} + callback {pars->PPunchStretch=(int) o->value();} + tooltip {Punch Stretch} xywh {185 247 25 25} box ROUND_UP_BOX labelsize 10 align 1 maximum 127 step 1 + code0 {o->value(pars->PPunchStretch);} + class WidgetPDial + } + Fl_Dial pvel { + label {P.Vel.} + callback {pars->PPunchVelocitySensing=(int) o->value();} + tooltip {Punch Velocity Sensing} xywh {215 247 25 25} box ROUND_UP_BOX labelsize 10 align 1 maximum 127 step 1 + code0 {o->value(pars->PPunchVelocitySensing);} + class WidgetPDial + } + Fl_Group ampenv { + label {PADSynth - Amplitude Envelope} open + xywh {10 95 205 70} box FLAT_BOX color 51 align 144 + code0 {o->init(pars->AmpEnvelope);} + class EnvelopeUI + } {} + Fl_Group amplfo { + label {Amplitude LFO } open + xywh {10 165 230 70} box FLAT_BOX color 47 align 144 + code0 {o->init(pars->AmpLfo);} + class LFOUI + } {} + Fl_Check_Button stereo { + label Stereo + callback {pars->PStereo=(int) o->value(); +hprofile->redraw();} + xywh {15 245 70 25} down_box DOWN_BOX + code0 {o->value(pars->PStereo);} + } + } + Fl_Group {} { + label FILTER + xywh {245 25 285 250} box THIN_UP_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 13 align 17 + } { + Fl_Group filterenv { + label {PADSynth - Filter Envelope} open + xywh {250 130 275 70} box FLAT_BOX color 51 align 144 + code0 {o->init(pars->FilterEnvelope);} + class EnvelopeUI + } {} + Fl_Group filterlfo { + label {Filter LFO } open + xywh {250 200 230 70} box FLAT_BOX color 47 align 144 + code0 {o->init(pars->FilterLfo);} + class LFOUI + } {} + Fl_Group filterui { + label {PADsynth - Filter} open + xywh {250 55 275 75} box FLAT_BOX color 50 align 144 + code0 {o->init(pars->GlobalFilter,&pars->PFilterVelocityScale,&pars->PFilterVelocityScaleFunction);} + class FilterUI + } {} + } + } + } + Fl_Button applybutton { + label {Apply Changes} + callback {pars->applyparameters(true); +o->color(FL_GRAY); +if (oscui!=NULL) { + oscui->applybutton->color(FL_GRAY); + oscui->applybutton->redraw(); +}; +if (resui!=NULL) { + resui->applybutton->color(FL_GRAY); + resui->applybutton->redraw(); +};} + xywh {45 405 185 40} box THIN_UP_BOX labelfont 1 labelsize 16 + code0 {o->color(FL_RED);} + } + Fl_Button {} { + label Close + callback {padnotewindow->hide();} + xywh {320 405 175 40} box THIN_UP_BOX labelsize 17 + } + Fl_Button {} { + label C + callback {presetsui->copy(pars);} + xywh {240 430 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 11 labelcolor 7 + } + Fl_Button {} { + label P + callback {presetsui->paste(pars,this);} + xywh {270 430 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 11 labelcolor 7 + } + Fl_Button {} { + label export + callback {char *filename; +filename=fl_file_chooser("Export samples:","(*.wav)",NULL,0); +if (filename==NULL) return; +fl_filename_setext(filename,""); + + + +pars->export2wav(filename);} selected + tooltip {export samples as wav file} xywh {240 405 55 15} box THIN_UP_BOX color 255 labelsize 11 align 128 + } + } + } + Function {refresh()} {} { + code {volume->value(pars->PVolume); +vsns->value(pars->PAmpVelocityScaleFunction); +pan->value(pars->PPanning); + +stereo->value(pars->PStereo); + + +pstr->value(pars->PPunchStrength); +pt->value(pars->PPunchTime); +pstc->value(pars->PPunchStretch); +pvel->value(pars->PPunchVelocitySensing); + +detunevalueoutput->value(getdetune(pars->PDetuneType,0,pars->PDetune)); +detune->value(pars->PDetune-8192); + +int k=pars->PCoarseDetune/1024;if (k>=8) k-=16; +octave->value(k); + +detunetype->value(pars->PDetuneType-1); +k=pars->PCoarseDetune%1024;if (k>=512) k-=1024; +coarsedet->value(k); + +hz440->value(pars->Pfixedfreq); +fixedfreqetdial->value(pars->PfixedfreqET); + +amplfo->refresh(); +freqlfo->refresh(); +filterlfo->refresh(); + +ampenv->refresh(); +freqenv->refresh(); +filterenv->refresh(); +filterui->refresh(); + + +/* harmonic structure parametrs */ + +resui->refresh(); +if (oscui!=NULL) oscui->refresh(); + +hpbasetype->value(pars->Php.base.type); +hpbasepar1->value(pars->Php.base.par1); +hpfreqmult->value(pars->Php.freqmult); + +hpmpar1->value(pars->Php.modulator.par1); +hpmfreq->value(pars->Php.modulator.freq); +hpwidth->value(pars->Php.width); + +hponehalf->value(pars->Php.onehalf); +hpamptype->value(pars->Php.amp.type); +hpampmode->value(pars->Php.amp.mode); +hpamppar1->value(pars->Php.amp.par1); +hpamppar2->value(pars->Php.amp.par2); +hpautoscale->value(pars->Php.autoscale); + +bwdial->value(pars->Pbandwidth); +if (pars->Pmode==0){ + bwprofilegroup->activate(); + bwdial->activate(); + bwcents->activate(); + hprofile->activate(); + hprofile->color(54); + bwscale->activate(); +} else { + bwprofilegroup->deactivate(); + bwdial->deactivate(); + bwcents->deactivate(); + hprofile->deactivate(); + hprofile->color(48); + bwscale->activate(); +}; + +spectrummode->value(pars->Pmode); + +qbasenote->value(pars->Pquality.basenote); +qsmpoct->value(pars->Pquality.smpoct); +qoct->value(pars->Pquality.oct); +qsamplesize->value(pars->Pquality.samplesize); + +hrpostype->value(pars->Phrpos.type); +hrpospar1->value(pars->Phrpos.par1); +hrpospar2->value(pars->Phrpos.par2); +hrpospar3->value(pars->Phrpos.par3); + +hprofile->redraw(); +overtonepos->redraw(); + +osc->redraw(); +pars->applyparameters(true); +applybutton->color(FL_GRAY); +applybutton->parent()->redraw();} {} + } + Function {~PADnoteUI()} {} { + code {delete(oscui); +delete(resui); + +padnotewindow->hide(); +delete(padnotewindow);} {} + } + decl {PADnoteParameters *pars;} {public + } + decl {Master *master;} {public + } + decl {OscilEditor *oscui;} {public + } + decl {Oscilloscope *osc;} {public + } + decl {ResonanceUI *resui;} {public + } +} diff --git a/plugins/zynaddsubfx/src/UI/PADnoteUI.h b/plugins/zynaddsubfx/src/UI/PADnoteUI.h new file mode 100644 index 000000000..79fd94b00 --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/PADnoteUI.h @@ -0,0 +1,305 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0109 + +#ifndef PADnoteUI_h +#define PADnoteUI_h +#include +#include "../Params/PADnoteParameters.h" +#include "../Misc/Util.h" +#include "../Misc/Master.h" +#include "ResonanceUI.h" +#include +#include +#include +#include "WidgetPDial.h" +#include "EnvelopeUI.h" +#include "LFOUI.h" +#include "FilterUI.h" +#include "OscilGenUI.h" +#include "PresetsUI.h" + +class PADnoteHarmonicProfile : public Fl_Box { +public: + PADnoteHarmonicProfile(int x,int y, int w, int h, const char *label=0); + void init(PADnoteParameters *pars,Master *master_); + void draw(); +private: + Master *master; +public: + PADnoteParameters *pars; +}; + +class PADnoteOvertonePosition : public Fl_Box { +public: + PADnoteOvertonePosition(int x,int y, int w, int h, const char *label=0); + void init(PADnoteParameters *pars,Master *master_); + void draw(); +private: + Master *master; +public: + PADnoteParameters *pars; +}; +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class PADnoteUI : public PresetsUI_ { +public: + PADnoteUI(PADnoteParameters *parameters,Master *master_); + Fl_Double_Window* make_window(); + Fl_Double_Window *padnotewindow; +private: + void cb__i(Fl_Tabs*, void*); + static void cb_(Fl_Tabs*, void*); +public: + Fl_Group *harmonicstructuregroup; + Fl_Group *bwprofilegroup; + WidgetPDial *hpbasepar1; +private: + void cb_hpbasepar1_i(WidgetPDial*, void*); + static void cb_hpbasepar1(WidgetPDial*, void*); +public: + Fl_Choice *hpbasetype; +private: + void cb_hpbasetype_i(Fl_Choice*, void*); + static void cb_hpbasetype(Fl_Choice*, void*); + static Fl_Menu_Item menu_hpbasetype[]; +public: + WidgetPDial *hpfreqmult; +private: + void cb_hpfreqmult_i(WidgetPDial*, void*); + static void cb_hpfreqmult(WidgetPDial*, void*); +public: + WidgetPDial *hpmpar1; +private: + void cb_hpmpar1_i(WidgetPDial*, void*); + static void cb_hpmpar1(WidgetPDial*, void*); +public: + WidgetPDial *hpmfreq; +private: + void cb_hpmfreq_i(WidgetPDial*, void*); + static void cb_hpmfreq(WidgetPDial*, void*); +public: + Fl_Choice *hpamptype; +private: + void cb_hpamptype_i(Fl_Choice*, void*); + static void cb_hpamptype(Fl_Choice*, void*); + static Fl_Menu_Item menu_hpamptype[]; +public: + Fl_Choice *hpampmode; +private: + void cb_hpampmode_i(Fl_Choice*, void*); + static void cb_hpampmode(Fl_Choice*, void*); + static Fl_Menu_Item menu_hpampmode[]; +public: + WidgetPDial *hpamppar1; +private: + void cb_hpamppar1_i(WidgetPDial*, void*); + static void cb_hpamppar1(WidgetPDial*, void*); +public: + WidgetPDial *hpamppar2; +private: + void cb_hpamppar2_i(WidgetPDial*, void*); + static void cb_hpamppar2(WidgetPDial*, void*); +public: + Fl_Check_Button *hpautoscale; +private: + void cb_hpautoscale_i(Fl_Check_Button*, void*); + static void cb_hpautoscale(Fl_Check_Button*, void*); +public: + Fl_Choice *hponehalf; +private: + void cb_hponehalf_i(Fl_Choice*, void*); + static void cb_hponehalf(Fl_Choice*, void*); + static Fl_Menu_Item menu_hponehalf[]; +public: + WidgetPDial *hpwidth; +private: + void cb_hpwidth_i(WidgetPDial*, void*); + static void cb_hpwidth(WidgetPDial*, void*); + void cb_Change_i(Fl_Button*, void*); + static void cb_Change(Fl_Button*, void*); +public: + Fl_Box *cbwidget; +private: + void cb_cbwidget_i(Fl_Box*, void*); + static void cb_cbwidget(Fl_Box*, void*); + void cb_Resonance_i(Fl_Button*, void*); + static void cb_Resonance(Fl_Button*, void*); +public: + WidgetPDial *bwdial; +private: + void cb_bwdial_i(WidgetPDial*, void*); + static void cb_bwdial(WidgetPDial*, void*); +public: + Fl_Value_Output *bwcents; + Fl_Choice *hrpostype; +private: + void cb_hrpostype_i(Fl_Choice*, void*); + static void cb_hrpostype(Fl_Choice*, void*); + static Fl_Menu_Item menu_hrpostype[]; +public: + WidgetPDial *hrpospar1; +private: + void cb_hrpospar1_i(WidgetPDial*, void*); + static void cb_hrpospar1(WidgetPDial*, void*); +public: + WidgetPDial *hrpospar2; +private: + void cb_hrpospar2_i(WidgetPDial*, void*); + static void cb_hrpospar2(WidgetPDial*, void*); +public: + WidgetPDial *hrpospar3; +private: + void cb_hrpospar3_i(WidgetPDial*, void*); + static void cb_hrpospar3(WidgetPDial*, void*); +public: + Fl_Choice *bwscale; +private: + void cb_bwscale_i(Fl_Choice*, void*); + static void cb_bwscale(Fl_Choice*, void*); + static Fl_Menu_Item menu_bwscale[]; +public: + Fl_Group *overtonepos; + Fl_Choice *qsamplesize; +private: + void cb_qsamplesize_i(Fl_Choice*, void*); + static void cb_qsamplesize(Fl_Choice*, void*); + static Fl_Menu_Item menu_qsamplesize[]; +public: + Fl_Choice *qsmpoct; +private: + void cb_qsmpoct_i(Fl_Choice*, void*); + static void cb_qsmpoct(Fl_Choice*, void*); + static Fl_Menu_Item menu_qsmpoct[]; +public: + Fl_Choice *qoct; +private: + void cb_qoct_i(Fl_Choice*, void*); + static void cb_qoct(Fl_Choice*, void*); + static Fl_Menu_Item menu_qoct[]; +public: + Fl_Choice *qbasenote; +private: + void cb_qbasenote_i(Fl_Choice*, void*); + static void cb_qbasenote(Fl_Choice*, void*); + static Fl_Menu_Item menu_qbasenote[]; +public: + Fl_Group *hprofile; + Fl_Choice *spectrummode; +private: + void cb_spectrummode_i(Fl_Choice*, void*); + static void cb_spectrummode(Fl_Choice*, void*); + static Fl_Menu_Item menu_spectrummode[]; +public: + EnvelopeUI *freqenv; + Fl_Counter *octave; +private: + void cb_octave_i(Fl_Counter*, void*); + static void cb_octave(Fl_Counter*, void*); +public: + Fl_Counter *coarsedet; +private: + void cb_coarsedet_i(Fl_Counter*, void*); + static void cb_coarsedet(Fl_Counter*, void*); +public: + LFOUI *freqlfo; + Fl_Slider *detune; +private: + void cb_detune_i(Fl_Slider*, void*); + static void cb_detune(Fl_Slider*, void*); +public: + Fl_Value_Output *detunevalueoutput; +private: + void cb_detunevalueoutput_i(Fl_Value_Output*, void*); + static void cb_detunevalueoutput(Fl_Value_Output*, void*); +public: + Fl_Choice *detunetype; +private: + void cb_detunetype_i(Fl_Choice*, void*); + static void cb_detunetype(Fl_Choice*, void*); +public: + Fl_Check_Button *hz440; +private: + void cb_hz440_i(Fl_Check_Button*, void*); + static void cb_hz440(Fl_Check_Button*, void*); +public: + WidgetPDial *fixedfreqetdial; +private: + void cb_fixedfreqetdial_i(WidgetPDial*, void*); + static void cb_fixedfreqetdial(WidgetPDial*, void*); +public: + Fl_Value_Slider *volume; +private: + void cb_volume_i(Fl_Value_Slider*, void*); + static void cb_volume(Fl_Value_Slider*, void*); +public: + Fl_Value_Slider *vsns; +private: + void cb_vsns_i(Fl_Value_Slider*, void*); + static void cb_vsns(Fl_Value_Slider*, void*); +public: + WidgetPDial *pan; +private: + void cb_pan_i(WidgetPDial*, void*); + static void cb_pan(WidgetPDial*, void*); +public: + WidgetPDial *pstr; +private: + void cb_pstr_i(WidgetPDial*, void*); + static void cb_pstr(WidgetPDial*, void*); +public: + WidgetPDial *pt; +private: + void cb_pt_i(WidgetPDial*, void*); + static void cb_pt(WidgetPDial*, void*); +public: + WidgetPDial *pstc; +private: + void cb_pstc_i(WidgetPDial*, void*); + static void cb_pstc(WidgetPDial*, void*); +public: + WidgetPDial *pvel; +private: + void cb_pvel_i(WidgetPDial*, void*); + static void cb_pvel(WidgetPDial*, void*); +public: + EnvelopeUI *ampenv; + LFOUI *amplfo; + Fl_Check_Button *stereo; +private: + void cb_stereo_i(Fl_Check_Button*, void*); + static void cb_stereo(Fl_Check_Button*, void*); +public: + EnvelopeUI *filterenv; + LFOUI *filterlfo; + FilterUI *filterui; + Fl_Button *applybutton; +private: + void cb_applybutton_i(Fl_Button*, void*); + static void cb_applybutton(Fl_Button*, void*); + void cb_Close_i(Fl_Button*, void*); + static void cb_Close(Fl_Button*, void*); + void cb_C_i(Fl_Button*, void*); + static void cb_C(Fl_Button*, void*); + void cb_P_i(Fl_Button*, void*); + static void cb_P(Fl_Button*, void*); + void cb_export_i(Fl_Button*, void*); + static void cb_export(Fl_Button*, void*); +public: + void refresh(); + ~PADnoteUI(); + PADnoteParameters *pars; + Master *master; + OscilEditor *oscui; + Oscilloscope *osc; + ResonanceUI *resui; +}; +#endif diff --git a/plugins/zynaddsubfx/src/UI/PartUI.cc b/plugins/zynaddsubfx/src/UI/PartUI.cc new file mode 100644 index 000000000..8c370ba41 --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/PartUI.cc @@ -0,0 +1,1815 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0109 + +#include "PartUI.h" +//Copyright (c) 2002-2005 Nasca Octavian Paul +//License: GNU GPL version 2 or later + +void PartSysEffSend::cb_01_i(WidgetPDial* o, void*) { + master->setPsysefxvol(npart,neff,(int) o->value()); +} +void PartSysEffSend::cb_01(WidgetPDial* o, void* v) { + ((PartSysEffSend*)(o->parent()->user_data()))->cb_01_i(o,v); +} + +Fl_Group* PartSysEffSend::make_window() { + { syseffsend = new Fl_Group(0, 0, 90, 35); + syseffsend->box(FL_FLAT_BOX); + syseffsend->color(FL_BACKGROUND_COLOR); + syseffsend->selection_color(FL_BACKGROUND_COLOR); + syseffsend->labeltype(FL_NO_LABEL); + syseffsend->labelfont(0); + syseffsend->labelsize(14); + syseffsend->labelcolor(FL_FOREGROUND_COLOR); + syseffsend->user_data((void*)(this)); + syseffsend->align(FL_ALIGN_TOP); + syseffsend->when(FL_WHEN_RELEASE); + { WidgetPDial* o = new WidgetPDial(0, 0, 25, 25, "01"); + o->box(FL_ROUND_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_INACTIVE_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(1); + o->labelsize(10); + o->labelcolor(FL_FOREGROUND_COLOR); + o->maximum(127); + o->step(1); + o->callback((Fl_Callback*)cb_01); + o->align(130); + o->when(FL_WHEN_CHANGED); + o->size(25,25); + o->value(master->Psysefxvol[neff][npart]); + char tmp[10];snprintf(tmp,10,"%d",neff+1);o->label(strdup(tmp)); + } // WidgetPDial* o + syseffsend->end(); + } // Fl_Group* syseffsend + return syseffsend; +} + +PartSysEffSend::PartSysEffSend(int x,int y, int w, int h, const char *label):Fl_Group(x,y,w,h,label) { + master=NULL; +neff=0; +npart=0; +} + +void PartSysEffSend::init(Master *master_,int npart_,int neff_) { + npart=npart_; +neff=neff_; +master=master_; +make_window(); +syseffsend->show(); +end(); +} + +PartSysEffSend::~PartSysEffSend() { + syseffsend->hide(); +//delete(syseffsend); +} + +void PartUI_::showparameters(int kititem,int engine) { +} + +void PartKitItem::cb_minkcounter_i(Fl_Counter* o, void*) { + part->kit[n].Pminkey=(int)o->value(); +} +void PartKitItem::cb_minkcounter(Fl_Counter* o, void* v) { + ((PartKitItem*)(o->parent()->parent()->user_data()))->cb_minkcounter_i(o,v); +} + +void PartKitItem::cb_m_i(Fl_Button*, void*) { + if (part->lastnote>=0) minkcounter->value(part->lastnote); +minkcounter->do_callback(); +maxkcounter->do_callback(); +} +void PartKitItem::cb_m(Fl_Button* o, void* v) { + ((PartKitItem*)(o->parent()->parent()->user_data()))->cb_m_i(o,v); +} + +void PartKitItem::cb_M_i(Fl_Button*, void*) { + if (part->lastnote>=0) maxkcounter->value(part->lastnote); +maxkcounter->do_callback(); +minkcounter->do_callback(); +} +void PartKitItem::cb_M(Fl_Button* o, void* v) { + ((PartKitItem*)(o->parent()->parent()->user_data()))->cb_M_i(o,v); +} + +void PartKitItem::cb_R_i(Fl_Button*, void*) { + minkcounter->value(0); +minkcounter->do_callback(); +maxkcounter->value(127); +maxkcounter->do_callback(); +} +void PartKitItem::cb_R(Fl_Button* o, void* v) { + ((PartKitItem*)(o->parent()->parent()->user_data()))->cb_R_i(o,v); +} + +void PartKitItem::cb_adeditbutton_i(Fl_Button*, void*) { + partui->showparameters(n,0); +} +void PartKitItem::cb_adeditbutton(Fl_Button* o, void* v) { + ((PartKitItem*)(o->parent()->parent()->user_data()))->cb_adeditbutton_i(o,v); +} + +void PartKitItem::cb_subeditbutton_i(Fl_Button*, void*) { + partui->showparameters(n,1); +} +void PartKitItem::cb_subeditbutton(Fl_Button* o, void* v) { + ((PartKitItem*)(o->parent()->parent()->user_data()))->cb_subeditbutton_i(o,v); +} + +void PartKitItem::cb_mutedcheck_i(Fl_Check_Button* o, void*) { + part->kit[n].Pmuted=(int)o->value(); +} +void PartKitItem::cb_mutedcheck(Fl_Check_Button* o, void* v) { + ((PartKitItem*)(o->parent()->parent()->user_data()))->cb_mutedcheck_i(o,v); +} + +void PartKitItem::cb_maxkcounter_i(Fl_Counter* o, void*) { + part->kit[n].Pmaxkey=(int)o->value(); +} +void PartKitItem::cb_maxkcounter(Fl_Counter* o, void* v) { + ((PartKitItem*)(o->parent()->parent()->user_data()))->cb_maxkcounter_i(o,v); +} + +void PartKitItem::cb_labelbutton_i(Fl_Button*, void*) { + const char *tmp=fl_input("Kit item name:",(const char *)part->kit[n].Pname); +if (tmp!=NULL) snprintf((char *)part->kit[n].Pname,PART_MAX_NAME_LEN,"%s",tmp); +} +void PartKitItem::cb_labelbutton(Fl_Button* o, void* v) { + ((PartKitItem*)(o->parent()->parent()->user_data()))->cb_labelbutton_i(o,v); +} + +void PartKitItem::cb_adcheck_i(Fl_Check_Button* o, void*) { + part->kit[n].Padenabled=(int)o->value(); +if (part->kit[n].Padenabled!=0) adeditbutton->activate(); + else adeditbutton->deactivate(); +} +void PartKitItem::cb_adcheck(Fl_Check_Button* o, void* v) { + ((PartKitItem*)(o->parent()->parent()->user_data()))->cb_adcheck_i(o,v); +} + +void PartKitItem::cb_subcheck_i(Fl_Check_Button* o, void*) { + part->kit[n].Psubenabled=(int)o->value(); +if (part->kit[n].Psubenabled!=0) subeditbutton->activate(); + else subeditbutton->deactivate(); +} +void PartKitItem::cb_subcheck(Fl_Check_Button* o, void* v) { + ((PartKitItem*)(o->parent()->parent()->user_data()))->cb_subcheck_i(o,v); +} + +void PartKitItem::cb_sendtoeffect_i(Fl_Choice* o, void*) { + if (o->value()!=0) part->kit[n].Psendtoparteffect=(int)o->value()-1; + else part->kit[n].Psendtoparteffect=127; +} +void PartKitItem::cb_sendtoeffect(Fl_Choice* o, void* v) { + ((PartKitItem*)(o->parent()->parent()->user_data()))->cb_sendtoeffect_i(o,v); +} + +void PartKitItem::cb_padeditbutton_i(Fl_Button*, void*) { + partui->showparameters(n,2); +} +void PartKitItem::cb_padeditbutton(Fl_Button* o, void* v) { + ((PartKitItem*)(o->parent()->parent()->user_data()))->cb_padeditbutton_i(o,v); +} + +void PartKitItem::cb_padcheck_i(Fl_Check_Button* o, void*) { + part->kit[n].Ppadenabled=(int)o->value(); +if (part->kit[n].Ppadenabled!=0) padeditbutton->activate(); + else padeditbutton->deactivate(); +} +void PartKitItem::cb_padcheck(Fl_Check_Button* o, void* v) { + ((PartKitItem*)(o->parent()->parent()->user_data()))->cb_padcheck_i(o,v); +} + +void PartKitItem::cb_enabledcheck_i(Fl_Check_Button* o, void*) { + int answer=1; +if (o->value()==0) answer=fl_choice("Delete the item?","No","Yes",NULL); +if (answer!=0){ +pthread_mutex_lock(&master->mutex); + part->setkititemstatus(n,(int) o->value()); +pthread_mutex_unlock(&master->mutex); + +if (o->value()==0) partkititemgroup->deactivate(); +else partkititemgroup->activate(); +o->redraw(); +partui->showparameters(n,-1);//use to delete the ui, if it is not to item 0 +} else o->value(1); +} +void PartKitItem::cb_enabledcheck(Fl_Check_Button* o, void* v) { + ((PartKitItem*)(o->parent()->user_data()))->cb_enabledcheck_i(o,v); +} + +Fl_Group* PartKitItem::make_window() { + { partkititem = new Fl_Group(0, 0, 670, 30); + partkititem->box(FL_FLAT_BOX); + partkititem->color(FL_BACKGROUND_COLOR); + partkititem->selection_color(FL_BACKGROUND_COLOR); + partkititem->labeltype(FL_NO_LABEL); + partkititem->labelfont(0); + partkititem->labelsize(14); + partkititem->labelcolor(FL_FOREGROUND_COLOR); + partkititem->user_data((void*)(this)); + partkititem->align(FL_ALIGN_TOP); + partkititem->when(FL_WHEN_RELEASE); + { Fl_Group* o = partkititemgroup = new Fl_Group(55, 0, 605, 20); + partkititemgroup->box(FL_FLAT_BOX); + { Fl_Counter* o = minkcounter = new Fl_Counter(225, 0, 55, 15); + minkcounter->type(1); + minkcounter->minimum(0); + minkcounter->maximum(128); + minkcounter->step(1); + minkcounter->callback((Fl_Callback*)cb_minkcounter); + o->value(part->kit[n].Pminkey); + } // Fl_Counter* minkcounter + { Fl_Button* o = new Fl_Button(285, 3, 15, 12, "m"); + o->tooltip("set the minimum key to the last pressed key"); + o->box(FL_THIN_UP_BOX); + o->labelsize(10); + o->callback((Fl_Callback*)cb_m); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(315, 3, 15, 12, "M"); + o->tooltip("set the maximum key to the last pressed key"); + o->box(FL_THIN_UP_BOX); + o->labelsize(10); + o->callback((Fl_Callback*)cb_M); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(300, 3, 15, 12, "R"); + o->tooltip("reset the minimum key to 0 and maximum key to 127"); + o->box(FL_THIN_UP_BOX); + o->labelfont(1); + o->labelsize(10); + o->callback((Fl_Callback*)cb_R); + } // Fl_Button* o + { Fl_Button* o = adeditbutton = new Fl_Button(420, 0, 40, 15, "edit"); + adeditbutton->box(FL_THIN_UP_BOX); + adeditbutton->labelsize(11); + adeditbutton->callback((Fl_Callback*)cb_adeditbutton); + if (part->kit[n].Padenabled==0) o->deactivate(); + if (n==0) o->hide(); + } // Fl_Button* adeditbutton + { Fl_Button* o = subeditbutton = new Fl_Button(490, 0, 40, 15, "edit"); + subeditbutton->box(FL_THIN_UP_BOX); + subeditbutton->labelsize(11); + subeditbutton->callback((Fl_Callback*)cb_subeditbutton); + if (part->kit[n].Psubenabled==0) o->deactivate(); + if (n==0) o->hide(); + } // Fl_Button* subeditbutton + { Fl_Check_Button* o = mutedcheck = new Fl_Check_Button(60, 0, 20, 15); + mutedcheck->down_box(FL_DOWN_BOX); + mutedcheck->labelfont(1); + mutedcheck->labelsize(11); + mutedcheck->callback((Fl_Callback*)cb_mutedcheck); + mutedcheck->align(FL_ALIGN_LEFT); + o->value(part->kit[n].Pmuted); + } // Fl_Check_Button* mutedcheck + { Fl_Counter* o = maxkcounter = new Fl_Counter(335, 0, 55, 15); + maxkcounter->type(1); + maxkcounter->minimum(0); + maxkcounter->maximum(128); + maxkcounter->step(1); + maxkcounter->callback((Fl_Callback*)cb_maxkcounter); + o->value(part->kit[n].Pmaxkey); + } // Fl_Counter* maxkcounter + { Fl_Button* o = labelbutton = new Fl_Button(90, 0, 130, 15, "Bass Drum"); + labelbutton->box(FL_THIN_DOWN_BOX); + labelbutton->down_box(FL_FLAT_BOX); + labelbutton->labelfont(1); + labelbutton->labelsize(10); + labelbutton->callback((Fl_Callback*)cb_labelbutton); + labelbutton->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE); + o->label((char *)part->kit[n].Pname); + } // Fl_Button* labelbutton + { Fl_Check_Button* o = adcheck = new Fl_Check_Button(400, 0, 20, 15); + adcheck->down_box(FL_DOWN_BOX); + adcheck->labelfont(1); + adcheck->labelsize(11); + adcheck->callback((Fl_Callback*)cb_adcheck); + adcheck->align(FL_ALIGN_LEFT); + o->value(part->kit[n].Padenabled); + if (n==0) o->hide(); + } // Fl_Check_Button* adcheck + { Fl_Check_Button* o = subcheck = new Fl_Check_Button(470, 0, 20, 15); + subcheck->down_box(FL_DOWN_BOX); + subcheck->labelfont(1); + subcheck->labelsize(11); + subcheck->callback((Fl_Callback*)cb_subcheck); + subcheck->align(FL_ALIGN_LEFT); + o->value(part->kit[n].Psubenabled); + if (n==0) o->hide(); + } // Fl_Check_Button* subcheck + { Fl_Choice* o = sendtoeffect = new Fl_Choice(615, 0, 45, 15); + sendtoeffect->down_box(FL_BORDER_BOX); + sendtoeffect->labelsize(10); + sendtoeffect->textfont(1); + sendtoeffect->textsize(10); + sendtoeffect->callback((Fl_Callback*)cb_sendtoeffect); + sendtoeffect->align(FL_ALIGN_TOP_LEFT); + o->add("OFF");char nrstr[10]; for(int i=0;iadd(nrstr);}; + o->value(part->kit[n].Psendtoparteffect+1);if (part->kit[n].Psendtoparteffect==127) o->value(0); + } // Fl_Choice* sendtoeffect + { Fl_Button* o = padeditbutton = new Fl_Button(560, 0, 40, 15, "edit"); + padeditbutton->box(FL_THIN_UP_BOX); + padeditbutton->labelsize(11); + padeditbutton->callback((Fl_Callback*)cb_padeditbutton); + if (part->kit[n].Ppadenabled==0) o->deactivate(); + if (n==0) o->hide(); + } // Fl_Button* padeditbutton + { Fl_Check_Button* o = padcheck = new Fl_Check_Button(540, 0, 20, 15); + padcheck->down_box(FL_DOWN_BOX); + padcheck->labelfont(1); + padcheck->labelsize(11); + padcheck->callback((Fl_Callback*)cb_padcheck); + padcheck->align(FL_ALIGN_LEFT); + o->value(part->kit[n].Ppadenabled); + if (n==0) o->hide(); + } // Fl_Check_Button* padcheck + if (part->kit[n].Penabled==0) o->deactivate(); + partkititemgroup->end(); + } // Fl_Group* partkititemgroup + { Fl_Check_Button* o = enabledcheck = new Fl_Check_Button(30, 0, 20, 15, "01"); + enabledcheck->down_box(FL_DOWN_BOX); + enabledcheck->labeltype(FL_EMBOSSED_LABEL); + enabledcheck->labelfont(1); + enabledcheck->labelsize(13); + enabledcheck->callback((Fl_Callback*)cb_enabledcheck); + enabledcheck->align(FL_ALIGN_LEFT); + snprintf(label,10,"%d",n+1);o->label(strdup(label)); + o->value(part->kit[n].Penabled); + if (n==0) o->deactivate(); + } // Fl_Check_Button* enabledcheck + partkititem->end(); + } // Fl_Group* partkititem + return partkititem; +} + +PartKitItem::PartKitItem(int x,int y, int w, int h, const char *label):Fl_Group(x,y,w,h,label) { + n=0; +part=NULL; +} + +void PartKitItem::refresh() { + enabledcheck->value(part->kit[n].Penabled); +if (part->kit[n].Penabled==0) partkititemgroup->deactivate(); +else partkititemgroup->activate(); + +mutedcheck->value(part->kit[n].Pmuted); +labelbutton->label((char *)part->kit[n].Pname); +minkcounter->value(part->kit[n].Pminkey); +maxkcounter->value(part->kit[n].Pmaxkey); +adcheck->value(part->kit[n].Padenabled); +adcheck->do_callback(); +subcheck->value(part->kit[n].Psubenabled); +subcheck->do_callback(); + +sendtoeffect->value(part->kit[n].Psendtoparteffect+1); +if (part->kit[n].Psendtoparteffect==127) sendtoeffect->value(0); + +this->redraw(); +} + +void PartKitItem::init(Part *part_,int n_,Master *master_,PartUI_ *partui_) { + part=part_; +n=n_; +partui=partui_; +master=master_; +make_window(); +//partkititem->show(); +end(); +} + +PartKitItem::~PartKitItem() { + partkititem->hide(); +//delete(partkititem); +} + +void PartUI::cb_Pan_i(WidgetPDial* o, void*) { + part->setPpanning((int) o->value()); +} +void PartUI::cb_Pan(WidgetPDial* o, void* v) { + ((PartUI*)(o->parent()->parent()->user_data()))->cb_Pan_i(o,v); +} + +void PartUI::cb_KeyShift_i(Fl_Counter* o, void*) { + part->Pkeyshift=(int) o->value()+64; +} +void PartUI::cb_KeyShift(Fl_Counter* o, void* v) { + ((PartUI*)(o->parent()->parent()->user_data()))->cb_KeyShift_i(o,v); +} + +void PartUI::cb_Grand_i(Fl_Button*, void*) { + int event=Fl::event_button(); +if (event==FL_RIGHT_MOUSE){ + const char *tmp=fl_input("Instrument name:",(const char *)part->Pname); + if (tmp!=NULL) snprintf((char *)part->Pname,PART_MAX_NAME_LEN,"%s",tmp); +} else { + if (event==FL_LEFT_MOUSE) bankui->show(); + else instrumenteditwindow->show(); +}; +} +void PartUI::cb_Grand(Fl_Button* o, void* v) { + ((PartUI*)(o->parent()->parent()->user_data()))->cb_Grand_i(o,v); +} + +void PartUI::cb_NoteOn_i(Fl_Check_Button* o, void*) { + part->Pnoteon=(int) o->value(); +} +void PartUI::cb_NoteOn(Fl_Check_Button* o, void* v) { + ((PartUI*)(o->parent()->parent()->user_data()))->cb_NoteOn_i(o,v); +} + +void PartUI::cb_minkcounter1_i(Fl_Counter* o, void*) { + part->Pminkey=(int) o->value(); +if (part->Pminkey>part->Pmaxkey) o->textcolor(FL_RED); + else o->textcolor(FL_BLACK); +} +void PartUI::cb_minkcounter1(Fl_Counter* o, void* v) { + ((PartUI*)(o->parent()->parent()->user_data()))->cb_minkcounter1_i(o,v); +} + +void PartUI::cb_maxkcounter1_i(Fl_Counter* o, void*) { + part->Pmaxkey=(int) o->value(); + +if (part->Pminkey>part->Pmaxkey) o->textcolor(FL_RED); + else o->textcolor(FL_BLACK); +} +void PartUI::cb_maxkcounter1(Fl_Counter* o, void* v) { + ((PartUI*)(o->parent()->parent()->user_data()))->cb_maxkcounter1_i(o,v); +} + +void PartUI::cb_Volume_i(WidgetPDial* o, void*) { + part->setPvolume((int) o->value()); +} +void PartUI::cb_Volume(WidgetPDial* o, void* v) { + ((PartUI*)(o->parent()->parent()->user_data()))->cb_Volume_i(o,v); +} + +void PartUI::cb_Vel_i(WidgetPDial* o, void*) { + part->Pveloffs=(int) o->value(); +} +void PartUI::cb_Vel(WidgetPDial* o, void* v) { + ((PartUI*)(o->parent()->parent()->user_data()))->cb_Vel_i(o,v); +} + +void PartUI::cb_Vel1_i(WidgetPDial* o, void*) { + part->Pvelsns=(int) o->value(); +} +void PartUI::cb_Vel1(WidgetPDial* o, void* v) { + ((PartUI*)(o->parent()->parent()->user_data()))->cb_Vel1_i(o,v); +} + +void PartUI::cb_Controllers_i(Fl_Button*, void*) { + ctlwindow->show(); +} +void PartUI::cb_Controllers(Fl_Button* o, void* v) { + ((PartUI*)(o->parent()->parent()->user_data()))->cb_Controllers_i(o,v); +} + +void PartUI::cb_Portamento_i(Fl_Check_Button* o, void*) { + part->ctl.portamento.portamento=(int) o->value(); +} +void PartUI::cb_Portamento(Fl_Check_Button* o, void* v) { + ((PartUI*)(o->parent()->parent()->user_data()))->cb_Portamento_i(o,v); +} + +void PartUI::cb_Edit_i(Fl_Button*, void*) { + instrumenteditwindow->show(); +} +void PartUI::cb_Edit(Fl_Button* o, void* v) { + ((PartUI*)(o->parent()->parent()->user_data()))->cb_Edit_i(o,v); +} + +void PartUI::cb_m1_i(Fl_Button*, void*) { + if (part->lastnote>=0) minkcounter->value(part->lastnote); +minkcounter->do_callback(); +maxkcounter->do_callback(); +} +void PartUI::cb_m1(Fl_Button* o, void* v) { + ((PartUI*)(o->parent()->parent()->user_data()))->cb_m1_i(o,v); +} + +void PartUI::cb_M1_i(Fl_Button*, void*) { + if (part->lastnote>=0) maxkcounter->value(part->lastnote); +maxkcounter->do_callback(); +minkcounter->do_callback(); +} +void PartUI::cb_M1(Fl_Button* o, void* v) { + ((PartUI*)(o->parent()->parent()->user_data()))->cb_M1_i(o,v); +} + +void PartUI::cb_R1_i(Fl_Button*, void*) { + minkcounter->value(0); +minkcounter->do_callback(); +maxkcounter->value(127); +maxkcounter->do_callback(); +} +void PartUI::cb_R1(Fl_Button* o, void* v) { + ((PartUI*)(o->parent()->parent()->user_data()))->cb_R1_i(o,v); +} + +void PartUI::cb_MIDI_i(Fl_Choice* o, void*) { + part->Prcvchn=(int) o->value(); +} +void PartUI::cb_MIDI(Fl_Choice* o, void* v) { + ((PartUI*)(o->parent()->parent()->user_data()))->cb_MIDI_i(o,v); +} + +void PartUI::cb_keylimitlist_i(Fl_Choice* o, void*) { + int val=0; +val=atoi(o->text()); +part->setkeylimit(val); +} +void PartUI::cb_keylimitlist(Fl_Choice* o, void* v) { + ((PartUI*)(o->parent()->parent()->user_data()))->cb_keylimitlist_i(o,v); +} + +void PartUI::cb_Mode_i(Fl_Choice* o, void*) { + if ((int) o->value()==0){ /* Poly (implies no legato) */ + part->Ppolymode=1; + part->Plegatomode=0; +} else { + if ((int) o->value()==1){ /* Mono (implies no legato) */ + part->Ppolymode=0; + part->Plegatomode=0; + } else { + if ((int) o->value()==2){ /* Legato (implies mono) */ + part->Ppolymode=0; + part->Plegatomode=1; + }; + }; +}; +} +void PartUI::cb_Mode(Fl_Choice* o, void* v) { + ((PartUI*)(o->parent()->parent()->user_data()))->cb_Mode_i(o,v); +} + +void PartUI::cb_Enabled_i(Fl_Check_Button* o, void*) { + pthread_mutex_lock(&master->mutex); +master->partonoff(npart,(int) o->value()); +pthread_mutex_unlock(&master->mutex); +if (part->Penabled==0) partgroupui->deactivate(); + else partgroupui->activate(); +} +void PartUI::cb_Enabled(Fl_Check_Button* o, void* v) { + ((PartUI*)(o->parent()->user_data()))->cb_Enabled_i(o,v); +} + +void PartUI::cb_Expr_i(Fl_Check_Button* o, void*) { + part->ctl.expression.receive=(int) o->value(); +} +void PartUI::cb_Expr(Fl_Check_Button* o, void* v) { + ((PartUI*)(o->parent()->user_data()))->cb_Expr_i(o,v); +} + +void PartUI::cb_PanDpth_i(WidgetPDial* o, void*) { + part->ctl.panning.depth=(int) o->value(); +} +void PartUI::cb_PanDpth(WidgetPDial* o, void* v) { + ((PartUI*)(o->parent()->user_data()))->cb_PanDpth_i(o,v); +} + +void PartUI::cb_FltCut_i(WidgetPDial* o, void*) { + part->ctl.filtercutoff.depth=(int) o->value(); +} +void PartUI::cb_FltCut(WidgetPDial* o, void* v) { + ((PartUI*)(o->parent()->user_data()))->cb_FltCut_i(o,v); +} + +void PartUI::cb_FltQ_i(WidgetPDial* o, void*) { + part->ctl.filterq.depth=(int) o->value(); +} +void PartUI::cb_FltQ(WidgetPDial* o, void* v) { + ((PartUI*)(o->parent()->user_data()))->cb_FltQ_i(o,v); +} + +void PartUI::cb_BwDpth_i(WidgetPDial* o, void*) { + part->ctl.bandwidth.depth=(int) o->value(); +} +void PartUI::cb_BwDpth(WidgetPDial* o, void* v) { + ((PartUI*)(o->parent()->user_data()))->cb_BwDpth_i(o,v); +} + +void PartUI::cb_ModWh_i(WidgetPDial* o, void*) { + part->ctl.modwheel.depth=(int) o->value(); +} +void PartUI::cb_ModWh(WidgetPDial* o, void* v) { + ((PartUI*)(o->parent()->user_data()))->cb_ModWh_i(o,v); +} + +void PartUI::cb_PWheelB_i(Fl_Counter* o, void*) { + part->ctl.pitchwheel.bendrange=(int) o->value(); +} +void PartUI::cb_PWheelB(Fl_Counter* o, void* v) { + ((PartUI*)(o->parent()->user_data()))->cb_PWheelB_i(o,v); +} + +void PartUI::cb_FMamp_i(Fl_Check_Button* o, void*) { + part->ctl.fmamp.receive=(int) o->value(); +} +void PartUI::cb_FMamp(Fl_Check_Button* o, void* v) { + ((PartUI*)(o->parent()->user_data()))->cb_FMamp_i(o,v); +} + +void PartUI::cb_Vol_i(Fl_Check_Button* o, void*) { + part->ctl.volume.receive=(int) o->value(); +} +void PartUI::cb_Vol(Fl_Check_Button* o, void* v) { + ((PartUI*)(o->parent()->user_data()))->cb_Vol_i(o,v); +} + +void PartUI::cb_Sustain_i(Fl_Check_Button* o, void*) { + part->ctl.sustain.receive=(int) o->value(); +if (part->ctl.sustain.receive==0) { + part->RelaseSustainedKeys(); + part->ctl.setsustain(0); +}; +} +void PartUI::cb_Sustain(Fl_Check_Button* o, void* v) { + ((PartUI*)(o->parent()->user_data()))->cb_Sustain_i(o,v); +} + +void PartUI::cb_Close_i(Fl_Button*, void*) { + ctlwindow->hide(); +} +void PartUI::cb_Close(Fl_Button* o, void* v) { + ((PartUI*)(o->parent()->user_data()))->cb_Close_i(o,v); +} + +void PartUI::cb_Reset_i(Fl_Button*, void*) { + part->SetController(C_resetallcontrollers,0); +} +void PartUI::cb_Reset(Fl_Button* o, void* v) { + ((PartUI*)(o->parent()->user_data()))->cb_Reset_i(o,v); +} + +void PartUI::cb_Rcv_i(Fl_Check_Button* o, void*) { + part->ctl.portamento.receive=(int) o->value(); +} +void PartUI::cb_Rcv(Fl_Check_Button* o, void* v) { + ((PartUI*)(o->parent()->parent()->user_data()))->cb_Rcv_i(o,v); +} + +void PartUI::cb_time_i(WidgetPDial* o, void*) { + part->ctl.portamento.time=(int) o->value(); +} +void PartUI::cb_time(WidgetPDial* o, void* v) { + ((PartUI*)(o->parent()->parent()->user_data()))->cb_time_i(o,v); +} + +void PartUI::cb_thresh_i(Fl_Counter* o, void*) { + part->ctl.portamento.pitchthresh=(int) o->value(); +} +void PartUI::cb_thresh(Fl_Counter* o, void* v) { + ((PartUI*)(o->parent()->parent()->user_data()))->cb_thresh_i(o,v); +} + +void PartUI::cb_th_i(Fl_Check_Button* o, void*) { + part->ctl.portamento.pitchthreshtype=(int) o->value(); +} +void PartUI::cb_th(Fl_Check_Button* o, void* v) { + ((PartUI*)(o->parent()->parent()->user_data()))->cb_th_i(o,v); +} + +void PartUI::cb_t_i(WidgetPDial* o, void*) { + int x=(int) o->value(); + +part->ctl.portamento.updowntimestretch=x; +} +void PartUI::cb_t(WidgetPDial* o, void* v) { + ((PartUI*)(o->parent()->parent()->user_data()))->cb_t_i(o,v); +} + +void PartUI::cb_BWdpth_i(WidgetPDial* o, void*) { + part->ctl.resonancebandwidth.depth=(int) o->value(); +} +void PartUI::cb_BWdpth(WidgetPDial* o, void* v) { + ((PartUI*)(o->parent()->parent()->user_data()))->cb_BWdpth_i(o,v); +} + +void PartUI::cb_CFdpth_i(WidgetPDial* o, void*) { + part->ctl.resonancecenter.depth=(int) o->value(); +} +void PartUI::cb_CFdpth(WidgetPDial* o, void* v) { + ((PartUI*)(o->parent()->parent()->user_data()))->cb_CFdpth_i(o,v); +} + +void PartUI::cb_Exp_i(Fl_Check_Button* o, void*) { + part->ctl.modwheel.exponential=(int) o->value(); +} +void PartUI::cb_Exp(Fl_Check_Button* o, void* v) { + ((PartUI*)(o->parent()->user_data()))->cb_Exp_i(o,v); +} + +void PartUI::cb_Exp1_i(Fl_Check_Button* o, void*) { + part->ctl.bandwidth.exponential=(int) o->value(); +} +void PartUI::cb_Exp1(Fl_Check_Button* o, void* v) { + ((PartUI*)(o->parent()->user_data()))->cb_Exp1_i(o,v); +} + +void PartUI::cb_inseffnocounter_i(Fl_Counter* o, void*) { + ninseff=(int) o->value()-1; +insefftype->value(part->partefx[ninseff]->geteffect()); +//insefftype->do_callback(); +inseffectui->refresh(part->partefx[ninseff]); +int x=part->Pefxroute[ninseff]; +if (x==127) x=1; +bypasseff->value(part->Pefxbypass[ninseff]); + +sendtochoice->value(x); +} +void PartUI::cb_inseffnocounter(Fl_Counter* o, void* v) { + ((PartUI*)(o->parent()->user_data()))->cb_inseffnocounter_i(o,v); +} + +void PartUI::cb_insefftype_i(Fl_Choice* o, void*) { + pthread_mutex_lock(part->mutex); +part->partefx[ninseff]->changeeffect((int) o->value()); +pthread_mutex_unlock(part->mutex); +inseffectui->refresh(part->partefx[ninseff]); +} +void PartUI::cb_insefftype(Fl_Choice* o, void* v) { + ((PartUI*)(o->parent()->user_data()))->cb_insefftype_i(o,v); +} + +Fl_Menu_Item PartUI::menu_insefftype[] = { + {"No Effect", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Reverb", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Echo", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Chorus", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Phaser", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"AlienWah", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Distortion", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"EQ", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"DynFilter", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void PartUI::cb_Close1_i(Fl_Button*, void*) { + partfx->hide(); +} +void PartUI::cb_Close1(Fl_Button* o, void* v) { + ((PartUI*)(o->parent()->user_data()))->cb_Close1_i(o,v); +} + +void PartUI::cb_sendtochoice_i(Fl_Choice* o, void*) { + int x=(int) o->value(); +part->Pefxroute[ninseff]=x; +if (x==2) part->partefx[ninseff]->setdryonly(true); + else part->partefx[ninseff]->setdryonly(false); +} +void PartUI::cb_sendtochoice(Fl_Choice* o, void* v) { + ((PartUI*)(o->parent()->user_data()))->cb_sendtochoice_i(o,v); +} + +Fl_Menu_Item PartUI::menu_sendtochoice[] = { + {"Next Effect", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Part Out", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"Dry Out", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void PartUI::cb_bypasseff_i(Fl_Check_Button* o, void*) { + part->Pefxbypass[ninseff]=(((int)o->value())!=0); +} +void PartUI::cb_bypasseff(Fl_Check_Button* o, void* v) { + ((PartUI*)(o->parent()->user_data()))->cb_bypasseff_i(o,v); +} + +void PartUI::cb_C_i(Fl_Button*, void*) { + presetsui->copy(part->partefx[ninseff]); +} +void PartUI::cb_C(Fl_Button* o, void* v) { + ((PartUI*)(o->parent()->user_data()))->cb_C_i(o,v); +} + +void PartUI::cb_P_i(Fl_Button*, void*) { + pthread_mutex_lock(&master->mutex); +presetsui->paste(part->partefx[ninseff],inseffectui); +pthread_mutex_unlock(&master->mutex); +} +void PartUI::cb_P(Fl_Button* o, void* v) { + ((PartUI*)(o->parent()->user_data()))->cb_P_i(o,v); +} + +void PartUI::cb_Close2_i(Fl_Button*, void*) { + instrumentkitlist->hide(); +} +void PartUI::cb_Close2(Fl_Button* o, void* v) { + ((PartUI*)(o->parent()->user_data()))->cb_Close2_i(o,v); +} + +void PartUI::cb_Mode1_i(Fl_Choice* o, void*) { + part->Pkitmode=(int) o->value(); +if (part->Pkitmode==0) { + kitlist->deactivate(); + } else { + kitlist->activate(); +}; +} +void PartUI::cb_Mode1(Fl_Choice* o, void* v) { + ((PartUI*)(o->parent()->user_data()))->cb_Mode1_i(o,v); +} + +Fl_Menu_Item PartUI::menu_Mode[] = { + {"OFF", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"MULTI", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"SINGLE", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void PartUI::cb_Drum_i(Fl_Check_Button* o, void*) { + part->Pdrummode=(int) o->value(); +} +void PartUI::cb_Drum(Fl_Check_Button* o, void* v) { + ((PartUI*)(o->parent()->user_data()))->cb_Drum_i(o,v); +} + +void PartUI::cb_padeditbutton1_i(Fl_Button*, void*) { + showparameters(0,2); +} +void PartUI::cb_padeditbutton1(Fl_Button* o, void* v) { + ((PartUI*)(o->parent()->parent()->parent()->user_data()))->cb_padeditbutton1_i(o,v); +} + +void PartUI::cb_padsynenabledcheck_i(Fl_Check_Button* o, void*) { + int x=(int) o->value(); +part->kit[0].Ppadenabled=x; +if (x==0) padeditbutton->deactivate(); + else padeditbutton->activate(); +} +void PartUI::cb_padsynenabledcheck(Fl_Check_Button* o, void* v) { + ((PartUI*)(o->parent()->parent()->parent()->user_data()))->cb_padsynenabledcheck_i(o,v); +} + +void PartUI::cb_adsynenabledcheck_i(Fl_Check_Button* o, void*) { + int x=(int) o->value(); +part->kit[0].Padenabled=x; +if (x==0) adeditbutton->deactivate(); + else adeditbutton->activate(); +} +void PartUI::cb_adsynenabledcheck(Fl_Check_Button* o, void* v) { + ((PartUI*)(o->parent()->parent()->parent()->user_data()))->cb_adsynenabledcheck_i(o,v); +} + +void PartUI::cb_adeditbutton1_i(Fl_Button*, void*) { + showparameters(0,0); +} +void PartUI::cb_adeditbutton1(Fl_Button* o, void* v) { + ((PartUI*)(o->parent()->parent()->parent()->user_data()))->cb_adeditbutton1_i(o,v); +} + +void PartUI::cb_subsynenabledcheck_i(Fl_Check_Button* o, void*) { + int x=(int) o->value(); +part->kit[0].Psubenabled=x; +if (x==0) subeditbutton->deactivate(); + else subeditbutton->activate(); +} +void PartUI::cb_subsynenabledcheck(Fl_Check_Button* o, void* v) { + ((PartUI*)(o->parent()->parent()->parent()->user_data()))->cb_subsynenabledcheck_i(o,v); +} + +void PartUI::cb_subeditbutton1_i(Fl_Button*, void*) { + showparameters(0,1); +} +void PartUI::cb_subeditbutton1(Fl_Button* o, void* v) { + ((PartUI*)(o->parent()->parent()->parent()->user_data()))->cb_subeditbutton1_i(o,v); +} + +void PartUI::cb_Kit_i(Fl_Button*, void*) { + instrumentkitlist->show(); +} +void PartUI::cb_Kit(Fl_Button* o, void* v) { + ((PartUI*)(o->parent()->parent()->user_data()))->cb_Kit_i(o,v); +} + +void PartUI::cb_Effects_i(Fl_Button*, void*) { + partfx->show(); +} +void PartUI::cb_Effects(Fl_Button* o, void* v) { + ((PartUI*)(o->parent()->parent()->user_data()))->cb_Effects_i(o,v); +} + +void PartUI::cb_Author_i(Fl_Input* o, void*) { + snprintf((char *)part->info.Pauthor,MAX_INFO_TEXT_SIZE,"%s",o->value()); +} +void PartUI::cb_Author(Fl_Input* o, void* v) { + ((PartUI*)(o->parent()->parent()->user_data()))->cb_Author_i(o,v); +} + +void PartUI::cb_Comments_i(Fl_Input* o, void*) { + snprintf((char *)part->info.Pcomments,MAX_INFO_TEXT_SIZE,"%s",o->value()); +} +void PartUI::cb_Comments(Fl_Input* o, void* v) { + ((PartUI*)(o->parent()->parent()->user_data()))->cb_Comments_i(o,v); +} + +void PartUI::cb_Type_i(Fl_Choice* o, void*) { + part->info.Ptype=o->value(); +} +void PartUI::cb_Type(Fl_Choice* o, void* v) { + ((PartUI*)(o->parent()->parent()->user_data()))->cb_Type_i(o,v); +} + +Fl_Menu_Item PartUI::menu_Type[] = { + {"--------------------------", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"Piano", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"Chromatic Percussion", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"Organ", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"Guitar", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"Bass", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"Solo Strings", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"Ensemble", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"Brass", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"Reed", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"Pipe", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"Synth Lead", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"Synth Pad", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"Synth Effects", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"Ethnic", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"Percussive", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"Sound Effects", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void PartUI::cb_Close3_i(Fl_Button*, void*) { + instrumenteditwindow->hide(); +} +void PartUI::cb_Close3(Fl_Button* o, void* v) { + ((PartUI*)(o->parent()->user_data()))->cb_Close3_i(o,v); +} + +Fl_Group* PartUI::make_window() { + { partgroup = new Fl_Group(0, 0, 385, 180); + partgroup->box(FL_FLAT_BOX); + partgroup->color(FL_BACKGROUND_COLOR); + partgroup->selection_color(FL_BACKGROUND_COLOR); + partgroup->labeltype(FL_NO_LABEL); + partgroup->labelfont(0); + partgroup->labelsize(14); + partgroup->labelcolor(FL_FOREGROUND_COLOR); + partgroup->user_data((void*)(this)); + partgroup->align(FL_ALIGN_TOP); + partgroup->when(FL_WHEN_RELEASE); + { Fl_Group* o = partgroupui = new Fl_Group(0, 0, 385, 180); + { WidgetPDial* o = new WidgetPDial(50, 40, 25, 25, "Pan"); + o->box(FL_ROUND_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_INACTIVE_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(11); + o->labelcolor(FL_FOREGROUND_COLOR); + o->maximum(127); + o->step(1); + o->callback((Fl_Callback*)cb_Pan); + o->align(FL_ALIGN_BOTTOM); + o->when(FL_WHEN_CHANGED); + o->value(part->Ppanning); + } // WidgetPDial* o + { Fl_Counter* o = new Fl_Counter(195, 45, 90, 20, "KeyShift"); + o->labelsize(11); + o->minimum(-64); + o->maximum(64); + o->step(1); + o->callback((Fl_Callback*)cb_KeyShift); + o->align(FL_ALIGN_TOP); + o->lstep(12); + o->value(part->Pkeyshift-64); + } // Fl_Counter* o + { Fl_Scroll* o = new Fl_Scroll(166, 91, 125, 60); + o->box(FL_ENGRAVED_FRAME); + o->labelfont(1); + o->labelsize(10); + o->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE); + { Fl_Pack* o = new Fl_Pack(171, 96, 115, 35); + o->type(1); + o->spacing(5); + for (int i=0;iinit(master,npart,i);} + o->end(); + } // Fl_Pack* o + o->end(); + } // Fl_Scroll* o + { Fl_Button* o = new Fl_Button(195, 5, 185, 20, "Grand Piano"); + o->tooltip("left mousebutton - to choose/save/.. from/to bank or right mousebutton to cha\ +nge the name or middle button to change the instrument information"); + o->box(FL_THIN_DOWN_BOX); + o->down_box(FL_FLAT_BOX); + o->labelfont(1); + o->labelsize(11); + o->callback((Fl_Callback*)cb_Grand); + o->align(68|FL_ALIGN_INSIDE); + o->label((char *)part->Pname); + } // Fl_Button* o + { Fl_Box* o = new Fl_Box(166, 81, 95, 10, "To Sys.Efx."); + o->labelfont(1); + o->labelsize(10); + } // Fl_Box* o + { Fl_Check_Button* o = new Fl_Check_Button(10, 155, 65, 20, "NoteOn"); + o->tooltip("set if the part receives NoteOn messages"); + o->down_box(FL_DOWN_BOX); + o->labelfont(1); + o->labelsize(11); + o->callback((Fl_Callback*)cb_NoteOn); + o->value(part->Pnoteon); + } // Fl_Check_Button* o + { Fl_Counter* o = minkcounter = new Fl_Counter(295, 125, 40, 15, "Min.k"); + minkcounter->tooltip("Minimum key (that the part receives NoteOn messages)"); + minkcounter->type(1); + minkcounter->labelfont(1); + minkcounter->labelsize(10); + minkcounter->minimum(0); + minkcounter->maximum(127); + minkcounter->step(1); + minkcounter->textsize(10); + minkcounter->callback((Fl_Callback*)cb_minkcounter1); + o->value(part->Pminkey); + } // Fl_Counter* minkcounter + { Fl_Counter* o = maxkcounter = new Fl_Counter(340, 125, 40, 15, "Max.k"); + maxkcounter->tooltip("Maximum key (that the part receives NoteOn messages)"); + maxkcounter->type(1); + maxkcounter->labelfont(1); + maxkcounter->labelsize(10); + maxkcounter->minimum(0); + maxkcounter->maximum(127); + maxkcounter->step(1); + maxkcounter->textsize(10); + maxkcounter->callback((Fl_Callback*)cb_maxkcounter1); + o->value(part->Pmaxkey); + } // Fl_Counter* maxkcounter + { WidgetPDial* o = new WidgetPDial(10, 35, 30, 30, "Volume"); + o->tooltip("Part Volume"); + o->box(FL_ROUND_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_INACTIVE_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(11); + o->labelcolor(FL_FOREGROUND_COLOR); + o->maximum(127); + o->step(1); + o->callback((Fl_Callback*)cb_Volume); + o->align(FL_ALIGN_BOTTOM); + o->when(FL_WHEN_CHANGED); + o->value(part->Pvolume); + } // WidgetPDial* o + { WidgetPDial* o = new WidgetPDial(135, 40, 25, 25, "Vel.Ofs."); + o->tooltip("Velocity Offset"); + o->box(FL_ROUND_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_INACTIVE_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(10); + o->labelcolor(FL_FOREGROUND_COLOR); + o->maximum(127); + o->step(1); + o->callback((Fl_Callback*)cb_Vel); + o->align(FL_ALIGN_BOTTOM); + o->when(FL_WHEN_CHANGED); + o->value(part->Pveloffs); + } // WidgetPDial* o + { WidgetPDial* o = new WidgetPDial(95, 40, 25, 25, "Vel.Sns."); + o->tooltip("Velocity Sensing Function"); + o->box(FL_ROUND_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_INACTIVE_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(10); + o->labelcolor(FL_FOREGROUND_COLOR); + o->maximum(127); + o->step(1); + o->callback((Fl_Callback*)cb_Vel1); + o->align(FL_ALIGN_BOTTOM); + o->when(FL_WHEN_CHANGED); + o->value(part->Pvelsns); + } // WidgetPDial* o + { Fl_Button* o = new Fl_Button(295, 90, 85, 30, "Controllers"); + o->box(FL_PLASTIC_UP_BOX); + o->labelfont(1); + o->labelsize(11); + o->callback((Fl_Callback*)cb_Controllers); + } // Fl_Button* o + { Fl_Check_Button* o = new Fl_Check_Button(95, 155, 88, 20, "Portamento"); + o->tooltip("Enable/Disable the portamento"); + o->down_box(FL_DOWN_BOX); + o->labelfont(1); + o->labelsize(11); + o->callback((Fl_Callback*)cb_Portamento); + o->value(part->ctl.portamento.portamento); + } // Fl_Check_Button* o + { Fl_Button* o = new Fl_Button(15, 90, 130, 30, "Edit instrument"); + o->box(FL_PLASTIC_UP_BOX); + o->color((Fl_Color)230); + o->labelfont(1); + o->labelsize(13); + o->callback((Fl_Callback*)cb_Edit); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(315, 155, 15, 12, "m"); + o->tooltip("set the minimum key to the last pressed key"); + o->box(FL_THIN_UP_BOX); + o->labelsize(10); + o->callback((Fl_Callback*)cb_m1); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(345, 155, 15, 12, "M"); + o->tooltip("set the maximum key to the last pressed key"); + o->box(FL_THIN_UP_BOX); + o->labelsize(10); + o->callback((Fl_Callback*)cb_M1); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(330, 155, 15, 12, "R"); + o->tooltip("reset the minimum key to 0 and maximum key to 127"); + o->box(FL_THIN_UP_BOX); + o->labelfont(1); + o->labelsize(10); + o->callback((Fl_Callback*)cb_R1); + } // Fl_Button* o + { Fl_Choice* o = new Fl_Choice(310, 45, 70, 20, "MIDI Chn.Rcv."); + o->tooltip("receive from Midi channel"); + o->down_box(FL_BORDER_BOX); + o->labelsize(10); + o->textfont(1); + o->textsize(10); + o->callback((Fl_Callback*)cb_MIDI); + o->align(FL_ALIGN_TOP_LEFT); + char nrstr[10]; for(int i=0;iadd(nrstr); else o->add("Drms10");}; + o->value(part->Prcvchn); + } // Fl_Choice* o + { keylimitlist = new Fl_Choice(215, 155, 50, 20, "KLmt"); + keylimitlist->tooltip("Key Limit"); + keylimitlist->down_box(FL_BORDER_BOX); + keylimitlist->labelsize(10); + keylimitlist->textfont(1); + keylimitlist->textsize(10); + keylimitlist->callback((Fl_Callback*)cb_keylimitlist); + keylimitlist->align(FL_ALIGN_RIGHT); + } // Fl_Choice* keylimitlist + { Fl_Choice* o = new Fl_Choice(80, 130, 64, 18, "Mode :"); + o->tooltip("Poly, Mono or Legato mode"); + o->down_box(FL_BORDER_BOX); + o->labelfont(1); + o->labelsize(11); + o->textfont(1); + o->textsize(10); + o->callback((Fl_Callback*)cb_Mode); + o->add("Poly"); o->add("Mono"); o->add("Legato"); + if (part->Ppolymode!=0) o->value(0); else o->value(1); + if (part->Ppolymode==0 && part->Plegatomode!=0) o->value(2); + } // Fl_Choice* o + if (part->Penabled==0) o->deactivate(); + partgroupui->end(); + } // Fl_Group* partgroupui + { Fl_Check_Button* o = new Fl_Check_Button(90, 5, 75, 20, "Enabled"); + o->down_box(FL_DOWN_BOX); + o->labelfont(1); + o->labelsize(11); + o->callback((Fl_Callback*)cb_Enabled); + o->value(part->Penabled); + } // Fl_Check_Button* o + partgroup->end(); + } // Fl_Group* partgroup + { ctlwindow = new Fl_Double_Window(460, 130, "Controllers"); + ctlwindow->user_data((void*)(this)); + { Fl_Check_Button* o = new Fl_Check_Button(155, 55, 45, 20, "Expr"); + o->tooltip("Expression enable"); + o->box(FL_THIN_UP_BOX); + o->down_box(FL_DOWN_BOX); + o->labelsize(10); + o->callback((Fl_Callback*)cb_Expr); + o->value(part->ctl.expression.receive); + } // Fl_Check_Button* o + { WidgetPDial* o = new WidgetPDial(10, 55, 30, 30, "PanDpth"); + o->tooltip("Panning Depth"); + o->box(FL_OVAL_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_INACTIVE_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(10); + o->labelcolor(FL_FOREGROUND_COLOR); + o->maximum(127); + o->step(1); + o->callback((Fl_Callback*)cb_PanDpth); + o->align(FL_ALIGN_BOTTOM); + o->when(FL_WHEN_CHANGED); + o->value(part->ctl.panning.depth); + } // WidgetPDial* o + { WidgetPDial* o = new WidgetPDial(90, 55, 30, 30, "FltCut"); + o->tooltip("Filter Cutoff depth"); + o->box(FL_OVAL_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_INACTIVE_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(10); + o->labelcolor(FL_FOREGROUND_COLOR); + o->maximum(127); + o->step(1); + o->callback((Fl_Callback*)cb_FltCut); + o->align(FL_ALIGN_BOTTOM); + o->when(FL_WHEN_CHANGED); + o->value(part->ctl.filtercutoff.depth); + } // WidgetPDial* o + { WidgetPDial* o = new WidgetPDial(50, 55, 30, 30, "FltQ"); + o->tooltip("Filter Q depth"); + o->box(FL_OVAL_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_INACTIVE_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(10); + o->labelcolor(FL_FOREGROUND_COLOR); + o->maximum(127); + o->step(1); + o->callback((Fl_Callback*)cb_FltQ); + o->align(FL_ALIGN_BOTTOM); + o->when(FL_WHEN_CHANGED); + o->value(part->ctl.filterq.depth); + } // WidgetPDial* o + { WidgetPDial* o = new WidgetPDial(125, 10, 30, 30, "BwDpth"); + o->tooltip("BandWidth depth"); + o->box(FL_OVAL_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_INACTIVE_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(10); + o->labelcolor(FL_FOREGROUND_COLOR); + o->maximum(127); + o->step(1); + o->callback((Fl_Callback*)cb_BwDpth); + o->align(FL_ALIGN_BOTTOM); + o->when(FL_WHEN_CHANGED); + o->value(part->ctl.bandwidth.depth); + } // WidgetPDial* o + { WidgetPDial* o = new WidgetPDial(50, 10, 30, 30, "ModWh"); + o->tooltip("Modulation Wheel depth"); + o->box(FL_OVAL_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_INACTIVE_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(10); + o->labelcolor(FL_FOREGROUND_COLOR); + o->maximum(127); + o->step(1); + o->callback((Fl_Callback*)cb_ModWh); + o->align(FL_ALIGN_BOTTOM); + o->when(FL_WHEN_CHANGED); + o->value(part->ctl.modwheel.depth); + } // WidgetPDial* o + { Fl_Counter* o = new Fl_Counter(165, 15, 110, 20, "PWheelB.Rng (cents)"); + o->tooltip("Pitch Wheel Bend Range (cents)"); + o->labelsize(10); + o->minimum(-6400); + o->maximum(6400); + o->step(1); + o->callback((Fl_Callback*)cb_PWheelB); + o->align(FL_ALIGN_TOP); + o->value(part->ctl.pitchwheel.bendrange); + o->lstep(100); + } // Fl_Counter* o + { Fl_Check_Button* o = new Fl_Check_Button(205, 55, 60, 20, "FMamp"); + o->tooltip("FM amplitude enable"); + o->box(FL_THIN_UP_BOX); + o->down_box(FL_DOWN_BOX); + o->labelsize(10); + o->callback((Fl_Callback*)cb_FMamp); + o->value(part->ctl.fmamp.receive); + } // Fl_Check_Button* o + { Fl_Check_Button* o = new Fl_Check_Button(155, 80, 45, 20, "Vol"); + o->tooltip("Volume enable"); + o->box(FL_THIN_UP_BOX); + o->down_box(FL_DOWN_BOX); + o->labelsize(10); + o->callback((Fl_Callback*)cb_Vol); + o->value(part->ctl.volume.receive); + } // Fl_Check_Button* o + { Fl_Check_Button* o = new Fl_Check_Button(205, 80, 60, 20, "Sustain"); + o->tooltip("Sustain pedal enable"); + o->box(FL_THIN_UP_BOX); + o->down_box(FL_DOWN_BOX); + o->labelsize(10); + o->callback((Fl_Callback*)cb_Sustain); + o->value(part->ctl.sustain.receive); + } // Fl_Check_Button* o + { Fl_Button* o = new Fl_Button(330, 105, 95, 20, "Close"); + o->box(FL_THIN_UP_BOX); + o->callback((Fl_Callback*)cb_Close); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(5, 105, 210, 20, "Reset all controllers"); + o->box(FL_THIN_UP_BOX); + o->callback((Fl_Callback*)cb_Reset); + } // Fl_Button* o + { Fl_Group* o = new Fl_Group(280, 15, 120, 85, "Portamento"); + o->box(FL_ENGRAVED_FRAME); + o->labelfont(1); + o->labelsize(10); + { Fl_Check_Button* o = new Fl_Check_Button(285, 20, 40, 20, "Rcv"); + o->tooltip("Receive Portamento Controllers"); + o->box(FL_THIN_UP_BOX); + o->down_box(FL_DOWN_BOX); + o->labelsize(10); + o->callback((Fl_Callback*)cb_Rcv); + o->value(part->ctl.portamento.receive); + } // Fl_Check_Button* o + { WidgetPDial* o = new WidgetPDial(285, 60, 25, 25, "time"); + o->tooltip("Portamento time"); + o->box(FL_OVAL_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_INACTIVE_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(10); + o->labelcolor(FL_FOREGROUND_COLOR); + o->maximum(127); + o->step(1); + o->callback((Fl_Callback*)cb_time); + o->align(FL_ALIGN_BOTTOM); + o->when(FL_WHEN_CHANGED); + o->value(part->ctl.portamento.time); + } // WidgetPDial* o + { Fl_Counter* o = new Fl_Counter(340, 20, 50, 20, "thresh"); + o->tooltip("Minimum or max. difference of the notes in order to do the portamento (x 100 \ +cents)"); + o->type(1); + o->labelsize(10); + o->minimum(0); + o->maximum(127); + o->step(1); + o->callback((Fl_Callback*)cb_thresh); + o->value(part->ctl.portamento.pitchthresh); + } // Fl_Counter* o + { Fl_Check_Button* o = new Fl_Check_Button(370, 70, 15, 15, "th.type"); + o->tooltip("Threshold type (min/max)"); + o->down_box(FL_DOWN_BOX); + o->labelsize(10); + o->callback((Fl_Callback*)cb_th); + o->align(FL_ALIGN_BOTTOM); + o->value(part->ctl.portamento.pitchthreshtype); + } // Fl_Check_Button* o + { Fl_Box* o = new Fl_Box(340, 50, 55, 15, "x100 cnt."); + o->labelsize(10); + o->align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE); + } // Fl_Box* o + { WidgetPDial* o = new WidgetPDial(315, 60, 25, 25, "t.dn/up"); + o->tooltip("Portamento time stretch (up/down)"); + o->box(FL_OVAL_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_INACTIVE_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(10); + o->labelcolor(FL_FOREGROUND_COLOR); + o->maximum(127); + o->step(1); + o->callback((Fl_Callback*)cb_t); + o->align(FL_ALIGN_BOTTOM); + o->when(FL_WHEN_CHANGED); + o->value(part->ctl.portamento.updowntimestretch); + } // WidgetPDial* o + o->end(); + } // Fl_Group* o + { Fl_Group* o = new Fl_Group(400, 15, 45, 85, "Resonance"); + o->box(FL_ENGRAVED_BOX); + o->labelfont(1); + o->labelsize(10); + { WidgetPDial* o = new WidgetPDial(410, 60, 25, 25, "BWdpth"); + o->tooltip("BandWidth controller depth"); + o->box(FL_OVAL_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_INACTIVE_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(10); + o->labelcolor(FL_FOREGROUND_COLOR); + o->maximum(127); + o->step(1); + o->callback((Fl_Callback*)cb_BWdpth); + o->align(FL_ALIGN_BOTTOM); + o->when(FL_WHEN_CHANGED); + o->value(part->ctl.resonancebandwidth.depth); + } // WidgetPDial* o + { WidgetPDial* o = new WidgetPDial(410, 20, 25, 25, "CFdpth"); + o->tooltip("Center Frequency controller Depth"); + o->box(FL_OVAL_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_INACTIVE_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(10); + o->labelcolor(FL_FOREGROUND_COLOR); + o->maximum(127); + o->step(1); + o->callback((Fl_Callback*)cb_CFdpth); + o->align(FL_ALIGN_BOTTOM); + o->when(FL_WHEN_CHANGED); + o->value(part->ctl.resonancecenter.depth); + } // WidgetPDial* o + o->end(); + } // Fl_Group* o + { Fl_Check_Button* o = new Fl_Check_Button(10, 15, 40, 25, "Exp MWh"); + o->tooltip("Exponential modulation wheel"); + o->down_box(FL_DOWN_BOX); + o->labelsize(10); + o->callback((Fl_Callback*)cb_Exp); + o->align(132|FL_ALIGN_INSIDE); + o->value(part->ctl.modwheel.exponential); + } // Fl_Check_Button* o + { Fl_Check_Button* o = new Fl_Check_Button(85, 15, 35, 25, "Exp BW"); + o->tooltip("Exponential BandWidth Controller"); + o->down_box(FL_DOWN_BOX); + o->labelsize(10); + o->callback((Fl_Callback*)cb_Exp1); + o->align(132|FL_ALIGN_INSIDE); + o->value(part->ctl.bandwidth.exponential); + } // Fl_Check_Button* o + ctlwindow->end(); + } // Fl_Double_Window* ctlwindow + { partfx = new Fl_Double_Window(390, 145, "Part\'s Insert Effects"); + partfx->user_data((void*)(this)); + { Fl_Counter* o = inseffnocounter = new Fl_Counter(5, 110, 80, 20, "FX No."); + inseffnocounter->type(1); + inseffnocounter->labelfont(1); + inseffnocounter->minimum(1); + inseffnocounter->maximum(127); + inseffnocounter->step(1); + inseffnocounter->textfont(1); + inseffnocounter->callback((Fl_Callback*)cb_inseffnocounter); + inseffnocounter->align(FL_ALIGN_BOTTOM_LEFT); + o->bounds(1,NUM_PART_EFX); + o->value(ninseff+1); + } // Fl_Counter* inseffnocounter + { Fl_Choice* o = insefftype = new Fl_Choice(155, 110, 70, 15, "EffType"); + insefftype->down_box(FL_BORDER_BOX); + insefftype->labelsize(10); + insefftype->callback((Fl_Callback*)cb_insefftype); + insefftype->align(FL_ALIGN_BOTTOM_LEFT); + insefftype->menu(menu_insefftype); + o->value(part->partefx[ninseff]->geteffect()); + } // Fl_Choice* insefftype + { inseffectuigroup = new Fl_Group(5, 5, 380, 100); + inseffectuigroup->box(FL_FLAT_BOX); + inseffectuigroup->color((Fl_Color)48); + { EffUI* o = inseffectui = new EffUI(5, 5, 380, 95); + inseffectui->box(FL_NO_BOX); + inseffectui->color(FL_BACKGROUND_COLOR); + inseffectui->selection_color(FL_BACKGROUND_COLOR); + inseffectui->labeltype(FL_NORMAL_LABEL); + inseffectui->labelfont(0); + inseffectui->labelsize(14); + inseffectui->labelcolor(FL_FOREGROUND_COLOR); + inseffectui->align(FL_ALIGN_TOP); + inseffectui->when(FL_WHEN_RELEASE); + o->init(part->partefx[ninseff]); + inseffectui->end(); + } // EffUI* inseffectui + inseffectuigroup->end(); + } // Fl_Group* inseffectuigroup + { Fl_Button* o = new Fl_Button(325, 115, 60, 20, "Close"); + o->box(FL_THIN_UP_BOX); + o->callback((Fl_Callback*)cb_Close1); + } // Fl_Button* o + { Fl_Choice* o = sendtochoice = new Fl_Choice(235, 110, 80, 15, "Send To."); + sendtochoice->down_box(FL_BORDER_BOX); + sendtochoice->labelsize(10); + sendtochoice->callback((Fl_Callback*)cb_sendtochoice); + sendtochoice->align(FL_ALIGN_BOTTOM_LEFT); + sendtochoice->menu(menu_sendtochoice); + int x=part->Pefxroute[ninseff]; if (x==127) x=1; + o->value(x); + } // Fl_Choice* sendtochoice + { Fl_Check_Button* o = bypasseff = new Fl_Check_Button(90, 110, 60, 15, "bypass"); + bypasseff->tooltip("if the effect is not used (is bypassed)"); + bypasseff->down_box(FL_DOWN_BOX); + bypasseff->labelsize(11); + bypasseff->callback((Fl_Callback*)cb_bypasseff); + int x=part->Pefxbypass[ninseff];o->value(x); + } // Fl_Check_Button* bypasseff + { Fl_Button* o = new Fl_Button(90, 127, 25, 15, "C"); + o->box(FL_THIN_UP_BOX); + o->color((Fl_Color)179); + o->labelfont(1); + o->labelsize(11); + o->labelcolor(FL_BACKGROUND2_COLOR); + o->callback((Fl_Callback*)cb_C); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(120, 127, 25, 15, "P"); + o->box(FL_THIN_UP_BOX); + o->color((Fl_Color)179); + o->labelfont(1); + o->labelsize(11); + o->labelcolor(FL_BACKGROUND2_COLOR); + o->callback((Fl_Callback*)cb_P); + } // Fl_Button* o + partfx->end(); + } // Fl_Double_Window* partfx + { instrumentkitlist = new Fl_Double_Window(670, 370, "Instrument Kit"); + instrumentkitlist->user_data((void*)(this)); + { Fl_Button* o = new Fl_Button(375, 350, 160, 20, "Close Window"); + o->box(FL_THIN_UP_BOX); + o->callback((Fl_Callback*)cb_Close2); + } // Fl_Button* o + { Fl_Scroll* o = kitlist = new Fl_Scroll(0, 15, 670, 330); + kitlist->type(2); + kitlist->box(FL_THIN_UP_BOX); + { Fl_Pack* o = new Fl_Pack(0, 20, 670, 320); + for (int i=0;iinit(part,i,master,this);} + o->end(); + } // Fl_Pack* o + if (part->Pkitmode==0) o->deactivate(); + kitlist->end(); + } // Fl_Scroll* kitlist + { Fl_Box* o = new Fl_Box(5, 0, 25, 15, "No."); + o->labelfont(1); + o->labelsize(11); + o->align(FL_ALIGN_BOTTOM|FL_ALIGN_INSIDE); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(55, 0, 25, 15, "M."); + o->labelfont(1); + o->labelsize(11); + o->align(FL_ALIGN_BOTTOM|FL_ALIGN_INSIDE); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(235, 0, 40, 15, "Min.k"); + o->labelfont(1); + o->labelsize(11); + o->align(FL_ALIGN_BOTTOM|FL_ALIGN_INSIDE); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(345, 0, 40, 15, "Max.k"); + o->labelfont(1); + o->labelsize(11); + o->align(FL_ALIGN_BOTTOM|FL_ALIGN_INSIDE); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(405, 0, 50, 15, "ADsynth"); + o->labelfont(1); + o->labelsize(11); + o->align(FL_ALIGN_BOTTOM|FL_ALIGN_INSIDE); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(470, 0, 60, 15, "SUBsynth"); + o->labelfont(1); + o->labelsize(11); + o->align(FL_ALIGN_BOTTOM|FL_ALIGN_INSIDE); + } // Fl_Box* o + { Fl_Choice* o = new Fl_Choice(35, 350, 70, 15, "Mode"); + o->down_box(FL_BORDER_BOX); + o->labelsize(11); + o->textfont(1); + o->textsize(11); + o->callback((Fl_Callback*)cb_Mode1); + o->menu(menu_Mode); + o->value(part->Pkitmode); + } // Fl_Choice* o + { Fl_Check_Button* o = new Fl_Check_Button(285, 350, 70, 15, "Drum mode"); + o->down_box(FL_DOWN_BOX); + o->labelsize(10); + o->callback((Fl_Callback*)cb_Drum); + o->value(part->Pdrummode); + } // Fl_Check_Button* o + { Fl_Box* o = new Fl_Box(620, 0, 30, 15, "FX.r."); + o->labelfont(1); + o->labelsize(11); + o->align(FL_ALIGN_BOTTOM|FL_ALIGN_INSIDE); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(540, 0, 60, 15, "PADsynth"); + o->labelfont(1); + o->labelsize(11); + o->align(FL_ALIGN_BOTTOM|FL_ALIGN_INSIDE); + } // Fl_Box* o + instrumentkitlist->end(); + } // Fl_Double_Window* instrumentkitlist + { instrumenteditwindow = new Fl_Double_Window(395, 360, "Instrument Edit"); + instrumenteditwindow->user_data((void*)(this)); + { Fl_Group* o = new Fl_Group(0, 220, 395, 110); + o->box(FL_ENGRAVED_FRAME); + { Fl_Group* o = new Fl_Group(205, 245, 100, 80, "PADsynth"); + o->box(FL_ENGRAVED_FRAME); + o->labelfont(1); + { Fl_Button* o = padeditbutton = new Fl_Button(215, 280, 80, 35, "Edit"); + padeditbutton->box(FL_PLASTIC_UP_BOX); + padeditbutton->color((Fl_Color)222); + padeditbutton->selection_color((Fl_Color)220); + padeditbutton->labelfont(1); + padeditbutton->labelsize(13); + padeditbutton->callback((Fl_Callback*)cb_padeditbutton1); + padeditbutton->align(FL_ALIGN_WRAP); + if (part->kit[0].Ppadenabled==0) o->deactivate(); + } // Fl_Button* padeditbutton + { Fl_Check_Button* o = padsynenabledcheck = new Fl_Check_Button(215, 255, 80, 20, "Enabled"); + padsynenabledcheck->tooltip("enable/disable PADsynth"); + padsynenabledcheck->box(FL_PLASTIC_UP_BOX); + padsynenabledcheck->down_box(FL_DOWN_BOX); + padsynenabledcheck->color((Fl_Color)222); + padsynenabledcheck->selection_color((Fl_Color)218); + padsynenabledcheck->labelfont(1); + padsynenabledcheck->labelsize(11); + padsynenabledcheck->callback((Fl_Callback*)cb_padsynenabledcheck); + o->value(part->kit[0].Ppadenabled); + } // Fl_Check_Button* padsynenabledcheck + o->end(); + } // Fl_Group* o + { Fl_Group* o = new Fl_Group(5, 245, 100, 80, "ADDsynth"); + o->box(FL_ENGRAVED_FRAME); + o->labelfont(1); + { Fl_Check_Button* o = adsynenabledcheck = new Fl_Check_Button(15, 255, 80, 20, "Enabled"); + adsynenabledcheck->tooltip("enable/disable ADsynth"); + adsynenabledcheck->box(FL_PLASTIC_UP_BOX); + adsynenabledcheck->down_box(FL_DOWN_BOX); + adsynenabledcheck->color((Fl_Color)222); + adsynenabledcheck->selection_color((Fl_Color)218); + adsynenabledcheck->labelfont(1); + adsynenabledcheck->labelsize(11); + adsynenabledcheck->callback((Fl_Callback*)cb_adsynenabledcheck); + o->value(part->kit[0].Padenabled); + } // Fl_Check_Button* adsynenabledcheck + { Fl_Button* o = adeditbutton = new Fl_Button(15, 281, 80, 34, "Edit"); + adeditbutton->box(FL_PLASTIC_UP_BOX); + adeditbutton->color((Fl_Color)222); + adeditbutton->selection_color((Fl_Color)220); + adeditbutton->labelfont(1); + adeditbutton->labelsize(13); + adeditbutton->callback((Fl_Callback*)cb_adeditbutton1); + adeditbutton->align(FL_ALIGN_WRAP); + if (part->kit[0].Padenabled==0) o->deactivate(); + } // Fl_Button* adeditbutton + o->end(); + } // Fl_Group* o + { Fl_Group* o = new Fl_Group(105, 245, 100, 80, "SUBsynth"); + o->box(FL_ENGRAVED_FRAME); + o->labelfont(1); + { Fl_Check_Button* o = subsynenabledcheck = new Fl_Check_Button(115, 255, 80, 20, "Enabled"); + subsynenabledcheck->tooltip("enable/disable SUBsynth"); + subsynenabledcheck->box(FL_PLASTIC_UP_BOX); + subsynenabledcheck->down_box(FL_DOWN_BOX); + subsynenabledcheck->color((Fl_Color)222); + subsynenabledcheck->selection_color((Fl_Color)218); + subsynenabledcheck->labelfont(1); + subsynenabledcheck->labelsize(11); + subsynenabledcheck->callback((Fl_Callback*)cb_subsynenabledcheck); + o->value(part->kit[0].Psubenabled); + } // Fl_Check_Button* subsynenabledcheck + { Fl_Button* o = subeditbutton = new Fl_Button(115, 280, 80, 35, "Edit"); + subeditbutton->box(FL_PLASTIC_UP_BOX); + subeditbutton->color((Fl_Color)222); + subeditbutton->selection_color((Fl_Color)220); + subeditbutton->labelfont(1); + subeditbutton->labelsize(13); + subeditbutton->callback((Fl_Callback*)cb_subeditbutton1); + subeditbutton->align(FL_ALIGN_WRAP); + if (part->kit[0].Psubenabled==0) o->deactivate(); + } // Fl_Button* subeditbutton + o->end(); + } // Fl_Group* o + { Fl_Button* o = new Fl_Button(310, 245, 80, 35, "Kit Edit"); + o->box(FL_PLASTIC_UP_BOX); + o->color((Fl_Color)238); + o->selection_color((Fl_Color)220); + o->labelfont(1); + o->callback((Fl_Callback*)cb_Kit); + o->align(FL_ALIGN_WRAP); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(310, 290, 80, 35, "Effects"); + o->box(FL_PLASTIC_UP_BOX); + o->color((Fl_Color)230); + o->labelfont(1); + o->labelsize(13); + o->callback((Fl_Callback*)cb_Effects); + } // Fl_Button* o + o->end(); + } // Fl_Group* o + { Fl_Group* o = new Fl_Group(0, 5, 395, 215); + o->box(FL_ENGRAVED_FRAME); + { Fl_Input* o = new Fl_Input(5, 60, 385, 50, "Author and Copyright"); + o->type(4); + o->color((Fl_Color)26); + o->labelsize(10); + o->callback((Fl_Callback*)cb_Author); + o->align(FL_ALIGN_TOP_LEFT); + o->maximum_size(MAX_INFO_TEXT_SIZE); + o->value((char *) &part->info.Pauthor); + } // Fl_Input* o + { Fl_Input* o = new Fl_Input(5, 125, 385, 90, "Comments"); + o->type(4); + o->color((Fl_Color)26); + o->labelsize(11); + o->callback((Fl_Callback*)cb_Comments); + o->align(FL_ALIGN_TOP_LEFT); + o->maximum_size(MAX_INFO_TEXT_SIZE); + o->value((char *) &part->info.Pcomments); + } // Fl_Input* o + { Fl_Choice* o = new Fl_Choice(5, 25, 155, 20, "Type:"); + o->down_box(FL_BORDER_BOX); + o->labelfont(1); + o->labelsize(11); + o->textsize(10); + o->callback((Fl_Callback*)cb_Type); + o->align(FL_ALIGN_TOP_LEFT); + o->menu(menu_Type); + o->value(part->info.Ptype); + } // Fl_Choice* o + o->end(); + } // Fl_Group* o + { Fl_Button* o = new Fl_Button(150, 335, 95, 25, "Close"); + o->box(FL_THIN_UP_BOX); + o->callback((Fl_Callback*)cb_Close3); + } // Fl_Button* o + instrumenteditwindow->end(); + } // Fl_Double_Window* instrumenteditwindow + return instrumenteditwindow; +} + +PartUI::PartUI(int x,int y, int w, int h, const char *label):Fl_Group(x,y,w,h,label) { + part=NULL; +adnoteui=NULL; +subnoteui=NULL; +padnoteui=NULL; +lastkititem=-1; +} + +void PartUI::init(Part *part_,Master *master_,int npart_,BankUI *bankui_) { + bankui=bankui_; +part=part_; +npart=npart_; +master=master_; +ninseff=0; + +make_window(); +partgroup->position(this->parent()->x()+2,this->parent()->y()+2); +partgroup->show(); +end(); + + +//if (config.ui.showinstrumentinfo!=0) instrumenteditwindow->show(); + +int klimits[]={1,2,3,4,5,6,7,8,9,10,15,20,30,50,100,0}; + +keylimitlist->add("OFF"); +int k=0; +int val=-1; +char tmp[10]; +while (klimits[k]!=0){ + sprintf(tmp,"%d",klimits[k]); + keylimitlist->add(tmp); + if ((val==-1)){ + if (klimits[k]>part->Pkeylimit) val=k; + }; + k++; +}; + +if (val==-1) val=k; +keylimitlist->value(val); +} + +void PartUI::showparameters(int kititem,int engine) { + if (engine==-1){//this is used if I want to clear the engine from the part + if (kititem==lastkititem) kititem=-1; + else kititem=lastkititem; +}; + +if (kititem!=lastkititem){ + if (adnoteui!=NULL) delete (adnoteui); + if (subnoteui!=NULL) delete (subnoteui); + if (padnoteui!=NULL) delete (padnoteui); + adnoteui=NULL;subnoteui=NULL;padnoteui=NULL; + lastkititem=kititem; + + if (kititem>=NUM_KIT_ITEMS) return;//bad kit item + if (kititem<0) return; + + if (part->kit[kititem].adpars!=NULL) + adnoteui=new ADnoteUI(part->kit[kititem].adpars,master); + + if (part->kit[kititem].subpars!=NULL) + subnoteui=new SUBnoteUI(part->kit[kititem].subpars); + + if (part->kit[kititem].padpars!=NULL) + padnoteui=new PADnoteUI(part->kit[kititem].padpars,master); + +}; + + + +if ((engine==0)&&(adnoteui!=NULL)) adnoteui->ADnoteGlobalParameters->show(); +if ((engine==1)&&(subnoteui!=NULL)) subnoteui->SUBparameters->show(); +if ((engine==2)&&(adnoteui!=NULL)) padnoteui->padnotewindow->show(); +} + +PartUI::~PartUI() { + if (adnoteui!=NULL) delete (adnoteui); +if (subnoteui!=NULL) delete (subnoteui); +if (padnoteui!=NULL) delete (padnoteui); + +partgroup->hide(); +//delete(partgroup); + +ctlwindow->hide(); +delete(ctlwindow); + +partfx->hide(); +delete(partfx); + +instrumentkitlist->hide(); +delete(instrumentkitlist); + +instrumenteditwindow->hide(); +delete(instrumenteditwindow); +} diff --git a/plugins/zynaddsubfx/src/UI/PartUI.fl b/plugins/zynaddsubfx/src/UI/PartUI.fl new file mode 100644 index 000000000..3a7288514 --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/PartUI.fl @@ -0,0 +1,1101 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0107 +header_name {.h} +code_name {.cc} +decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} + +decl {//License: GNU GPL version 2 or later} {} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include "WidgetPDial.h"} {public +} + +decl {\#include "EffUI.h"} {public +} + +decl {\#include "BankUI.h"} {public +} + +decl {\#include "ADnoteUI.h"} {public +} + +decl {\#include "SUBnoteUI.h"} {public +} + +decl {\#include "PADnoteUI.h"} {public +} + +decl {\#include "../Misc/Config.h"} {public +} + +decl {\#include "../Misc/Master.h"} {public +} + +decl {\#include "../Misc/Part.h"} {public +} + +class PartSysEffSend {open : {public Fl_Group} +} { + Function {make_window()} {open private + } { + Fl_Window syseffsend { + private xywh {584 83 90 35} type Double hide + class Fl_Group + } { + Fl_Dial {} { + label 01 + callback {master->setPsysefxvol(npart,neff,(int) o->value());} selected + xywh {0 0 25 25} box ROUND_UP_BOX labelfont 1 labelsize 10 align 130 maximum 127 step 1 + code0 {o->size(25,25);} + code1 {o->value(master->Psysefxvol[neff][npart]);} + code2 {char tmp[10];snprintf(tmp,10,"%d",neff+1);o->label(strdup(tmp));} + class WidgetPDial + } + } + } + Function {PartSysEffSend(int x,int y, int w, int h, const char *label=0):Fl_Group(x,y,w,h,label)} {} { + code {master=NULL; +neff=0; +npart=0;} {} + } + Function {init(Master *master_,int npart_,int neff_)} {} { + code {npart=npart_; +neff=neff_; +master=master_; +make_window(); +syseffsend->show(); +end();} {} + } + Function {~PartSysEffSend()} {} { + code {syseffsend->hide(); +//delete(syseffsend);} {} + } + decl {Master *master;} {} + decl {int neff;} {} + decl {int npart;} {} +} + +class PartUI_ {} { + Function {showparameters(int kititem,int engine)} {return_type virtual + } {} +} + +class PartKitItem {: {public Fl_Group} +} { + Function {make_window()} {private + } { + Fl_Window partkititem { + private xywh {113 271 670 30} type Double hide + class Fl_Group + } { + Fl_Group partkititemgroup { + private xywh {55 0 605 20} box FLAT_BOX + code0 {if (part->kit[n].Penabled==0) o->deactivate();} + } { + Fl_Counter minkcounter { + callback {part->kit[n].Pminkey=(int)o->value();} + xywh {225 0 55 15} type Simple minimum 0 maximum 128 step 1 + code0 {o->value(part->kit[n].Pminkey);} + } + Fl_Button {} { + label m + callback {if (part->lastnote>=0) minkcounter->value(part->lastnote); +minkcounter->do_callback(); +maxkcounter->do_callback();} + tooltip {set the minimum key to the last pressed key} xywh {285 3 15 12} box THIN_UP_BOX labelsize 10 + } + Fl_Button {} { + label M + callback {if (part->lastnote>=0) maxkcounter->value(part->lastnote); +maxkcounter->do_callback(); +minkcounter->do_callback();} + tooltip {set the maximum key to the last pressed key} xywh {315 3 15 12} box THIN_UP_BOX labelsize 10 + } + Fl_Button {} { + label R + callback {minkcounter->value(0); +minkcounter->do_callback(); +maxkcounter->value(127); +maxkcounter->do_callback();} + tooltip {reset the minimum key to 0 and maximum key to 127} xywh {300 3 15 12} box THIN_UP_BOX labelfont 1 labelsize 10 + } + Fl_Button adeditbutton { + label edit + callback {partui->showparameters(n,0);} + xywh {420 0 40 15} box THIN_UP_BOX labelsize 11 + code0 {if (part->kit[n].Padenabled==0) o->deactivate();} + code1 {if (n==0) o->hide();} + } + Fl_Button subeditbutton { + label edit + callback {partui->showparameters(n,1);} + xywh {490 0 40 15} box THIN_UP_BOX labelsize 11 + code0 {if (part->kit[n].Psubenabled==0) o->deactivate();} + code1 {if (n==0) o->hide();} + } + Fl_Check_Button mutedcheck { + callback {part->kit[n].Pmuted=(int)o->value();} + private xywh {60 0 20 15} down_box DOWN_BOX labelfont 1 labelsize 11 align 4 + code0 {o->value(part->kit[n].Pmuted);} + } + Fl_Counter maxkcounter { + callback {part->kit[n].Pmaxkey=(int)o->value();} + xywh {335 0 55 15} type Simple minimum 0 maximum 128 step 1 + code0 {o->value(part->kit[n].Pmaxkey);} + } + Fl_Button labelbutton { + label {Bass Drum} + callback {const char *tmp=fl_input("Kit item name:",(const char *)part->kit[n].Pname); +if (tmp!=NULL) snprintf((char *)part->kit[n].Pname,PART_MAX_NAME_LEN,"%s",tmp);} + xywh {90 0 130 15} box THIN_DOWN_BOX down_box FLAT_BOX labelfont 1 labelsize 10 align 20 + code0 {o->label((char *)part->kit[n].Pname);} + } + Fl_Check_Button adcheck { + callback {part->kit[n].Padenabled=(int)o->value(); +if (part->kit[n].Padenabled!=0) adeditbutton->activate(); + else adeditbutton->deactivate();} + private xywh {400 0 20 15} down_box DOWN_BOX labelfont 1 labelsize 11 align 4 + code0 {o->value(part->kit[n].Padenabled);} + code1 {if (n==0) o->hide();} + } + Fl_Check_Button subcheck { + callback {part->kit[n].Psubenabled=(int)o->value(); +if (part->kit[n].Psubenabled!=0) subeditbutton->activate(); + else subeditbutton->deactivate();} + private xywh {470 0 20 15} down_box DOWN_BOX labelfont 1 labelsize 11 align 4 + code0 {o->value(part->kit[n].Psubenabled);} + code1 {if (n==0) o->hide();} + } + Fl_Choice sendtoeffect { + callback {if (o->value()!=0) part->kit[n].Psendtoparteffect=(int)o->value()-1; + else part->kit[n].Psendtoparteffect=127;} open + xywh {615 0 45 15} down_box BORDER_BOX labelsize 10 align 5 textfont 1 textsize 10 + code0 {o->add("OFF");char nrstr[10]; for(int i=0;iadd(nrstr);};} + code1 {o->value(part->kit[n].Psendtoparteffect+1);if (part->kit[n].Psendtoparteffect==127) o->value(0);} + } {} + Fl_Button padeditbutton { + label edit + callback {partui->showparameters(n,2);} + xywh {560 0 40 15} box THIN_UP_BOX labelsize 11 + code0 {if (part->kit[n].Ppadenabled==0) o->deactivate();} + code1 {if (n==0) o->hide();} + } + Fl_Check_Button padcheck { + callback {part->kit[n].Ppadenabled=(int)o->value(); +if (part->kit[n].Ppadenabled!=0) padeditbutton->activate(); + else padeditbutton->deactivate();} + private xywh {540 0 20 15} down_box DOWN_BOX labelfont 1 labelsize 11 align 4 + code0 {o->value(part->kit[n].Ppadenabled);} + code1 {if (n==0) o->hide();} + } + } + Fl_Check_Button enabledcheck { + label 01 + callback {int answer=1; +if (o->value()==0) answer=fl_choice("Delete the item?","No","Yes",NULL); +if (answer!=0){ +pthread_mutex_lock(&master->mutex); + part->setkititemstatus(n,(int) o->value()); +pthread_mutex_unlock(&master->mutex); + +if (o->value()==0) partkititemgroup->deactivate(); +else partkititemgroup->activate(); +o->redraw(); +partui->showparameters(n,-1);//use to delete the ui, if it is not to item 0 +} else o->value(1);} + private xywh {30 0 20 15} down_box DOWN_BOX labeltype EMBOSSED_LABEL labelfont 1 labelsize 13 align 4 + code0 {snprintf(label,10,"%d",n+1);o->label(strdup(label));} + code1 {o->value(part->kit[n].Penabled);} + code2 {if (n==0) o->deactivate();} + } + } + } + Function {PartKitItem(int x,int y, int w, int h, const char *label=0):Fl_Group(x,y,w,h,label)} {} { + code {n=0; +part=NULL;} {} + } + Function {refresh()} {} { + code {enabledcheck->value(part->kit[n].Penabled); +if (part->kit[n].Penabled==0) partkititemgroup->deactivate(); +else partkititemgroup->activate(); + +mutedcheck->value(part->kit[n].Pmuted); +labelbutton->label((char *)part->kit[n].Pname); +minkcounter->value(part->kit[n].Pminkey); +maxkcounter->value(part->kit[n].Pmaxkey); +adcheck->value(part->kit[n].Padenabled); +adcheck->do_callback(); +subcheck->value(part->kit[n].Psubenabled); +subcheck->do_callback(); + +sendtoeffect->value(part->kit[n].Psendtoparteffect+1); +if (part->kit[n].Psendtoparteffect==127) sendtoeffect->value(0); + +this->redraw();} { + callback {int answer=1; +if (o->value()==0) answer=fl_choice("Delete the item?","No","Yes",NULL); +if (answer!=0){ +pthread_mutex_lock(&master->mutex); + part->setkititemstatus(n,(int) o->value()); +pthread_mutex_unlock(&master->mutex); + +if (o->value()==0) partkititemgroup->deactivate(); +else partkititemgroup->activate(); +o->redraw(); +partui->showparameters(n,-1);//use to delete the ui, if it is not to item 0 +} else o->value(1);} + } + } + Function {init(Part *part_,int n_,Master *master_,PartUI_ *partui_)} {} { + code {part=part_; +n=n_; +partui=partui_; +master=master_; +make_window(); +//partkititem->show(); +end();} {} + } + Function {~PartKitItem()} {} { + code {partkititem->hide(); +//delete(partkititem);} {} + } + decl {Part *part;} {} + decl {int n;} {} + decl {Master *master;} {} + decl {char label[10];} {} + decl {PartUI_ *partui;} {} +} + +class PartUI {open : {public Fl_Group,PartUI_} +} { + Function {make_window()} {open private + } { + Fl_Window partgroup { + private xywh {424 178 385 180} type Double hide + class Fl_Group + } { + Fl_Group partgroupui { + xywh {0 0 385 180} + code0 {if (part->Penabled==0) o->deactivate();} + } { + Fl_Dial {} { + label Pan + callback {part->setPpanning((int) o->value());} + xywh {50 40 25 25} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + code0 {o->value(part->Ppanning);} + class WidgetPDial + } + Fl_Counter {} { + label KeyShift + callback {part->Pkeyshift=(int) o->value()+64;} + xywh {195 45 90 20} labelsize 11 align 1 minimum -64 maximum 64 step 1 + code0 {o->lstep(12);} + code1 {o->value(part->Pkeyshift-64);} + } + Fl_Scroll {} {open + xywh {166 91 125 60} box ENGRAVED_FRAME labelfont 1 labelsize 10 align 21 + } { + Fl_Pack {} {open + xywh {171 96 115 35} type HORIZONTAL + code0 {o->spacing(5);} + code1 {for (int i=0;iinit(master,npart,i);}} + } {} + } + Fl_Button {} { + label {Grand Piano} + callback {int event=Fl::event_button(); +if (event==FL_RIGHT_MOUSE){ + const char *tmp=fl_input("Instrument name:",(const char *)part->Pname); + if (tmp!=NULL) snprintf((char *)part->Pname,PART_MAX_NAME_LEN,"%s",tmp); +} else { + if (event==FL_LEFT_MOUSE) bankui->show(); + else instrumenteditwindow->show(); +};} + tooltip {left mousebutton - to choose/save/.. from/to bank or right mousebutton to change the name or middle button to change the instrument information} xywh {195 5 185 20} box THIN_DOWN_BOX down_box FLAT_BOX labelfont 1 labelsize 11 align 84 + code0 {o->label((char *)part->Pname);} + } + Fl_Box {} { + label {To Sys.Efx.} + xywh {166 81 95 10} labelfont 1 labelsize 10 + } + Fl_Check_Button {} { + label NoteOn + callback {part->Pnoteon=(int) o->value();} + tooltip {set if the part receives NoteOn messages} xywh {10 155 65 20} down_box DOWN_BOX labelfont 1 labelsize 11 + code0 {o->value(part->Pnoteon);} + } + Fl_Counter minkcounter { + label {Min.k} + callback {part->Pminkey=(int) o->value(); +if (part->Pminkey>part->Pmaxkey) o->textcolor(FL_RED); + else o->textcolor(FL_BLACK);} + tooltip {Minimum key (that the part receives NoteOn messages)} xywh {295 125 40 15} type Simple labelfont 1 labelsize 10 minimum 0 maximum 127 step 1 textsize 10 + code0 {o->value(part->Pminkey);} + } + Fl_Counter maxkcounter { + label {Max.k} + callback {part->Pmaxkey=(int) o->value(); + +if (part->Pminkey>part->Pmaxkey) o->textcolor(FL_RED); + else o->textcolor(FL_BLACK);} + tooltip {Maximum key (that the part receives NoteOn messages)} xywh {340 125 40 15} type Simple labelfont 1 labelsize 10 minimum 0 maximum 127 step 1 textsize 10 + code0 {o->value(part->Pmaxkey);} + } + Fl_Dial {} { + label Volume + callback {part->setPvolume((int) o->value());} + tooltip {Part Volume} xywh {10 35 30 30} box ROUND_UP_BOX labelsize 11 maximum 127 step 1 + code0 {o->value(part->Pvolume);} + class WidgetPDial + } + Fl_Dial {} { + label {Vel.Ofs.} + callback {part->Pveloffs=(int) o->value();} + tooltip {Velocity Offset} xywh {135 40 25 25} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + code0 {o->value(part->Pveloffs);} + class WidgetPDial + } + Fl_Dial {} { + label {Vel.Sns.} + callback {part->Pvelsns=(int) o->value();} + tooltip {Velocity Sensing Function} xywh {95 40 25 25} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + code0 {o->value(part->Pvelsns);} + class WidgetPDial + } + Fl_Button {} { + label Controllers + callback {ctlwindow->show();} + xywh {295 90 85 30} box PLASTIC_UP_BOX labelfont 1 labelsize 11 + } + Fl_Check_Button {} { + label Portamento + callback {part->ctl.portamento.portamento=(int) o->value();} + tooltip {Enable/Disable the portamento} xywh {95 155 88 20} down_box DOWN_BOX labelfont 1 labelsize 11 + code0 {o->value(part->ctl.portamento.portamento);} + } + Fl_Button {} { + label {Edit instrument} + callback {instrumenteditwindow->show();} + xywh {15 90 130 30} box PLASTIC_UP_BOX color 230 labelfont 1 labelsize 13 + } + Fl_Button {} { + label m + callback {if (part->lastnote>=0) minkcounter->value(part->lastnote); +minkcounter->do_callback(); +maxkcounter->do_callback();} + tooltip {set the minimum key to the last pressed key} xywh {315 155 15 12} box THIN_UP_BOX labelsize 10 + } + Fl_Button {} { + label M + callback {if (part->lastnote>=0) maxkcounter->value(part->lastnote); +maxkcounter->do_callback(); +minkcounter->do_callback();} + tooltip {set the maximum key to the last pressed key} xywh {345 155 15 12} box THIN_UP_BOX labelsize 10 + } + Fl_Button {} { + label R + callback {minkcounter->value(0); +minkcounter->do_callback(); +maxkcounter->value(127); +maxkcounter->do_callback();} + tooltip {reset the minimum key to 0 and maximum key to 127} xywh {330 155 15 12} box THIN_UP_BOX labelfont 1 labelsize 10 + } + Fl_Choice {} { + label {MIDI Chn.Rcv.} + callback {part->Prcvchn=(int) o->value();} open + tooltip {receive from Midi channel} xywh {310 45 70 20} down_box BORDER_BOX labelsize 10 align 5 textfont 1 textsize 10 + code0 {char nrstr[10]; for(int i=0;iadd(nrstr); else o->add("Drms10");};} + code1 {o->value(part->Prcvchn);} + } {} + Fl_Choice keylimitlist { + label KLmt + callback {int val=0; +val=atoi(o->text()); +part->setkeylimit(val);} open + tooltip {Key Limit} xywh {215 155 50 20} down_box BORDER_BOX labelsize 10 align 8 textfont 1 textsize 10 + } {} + Fl_Choice {} { + label {Mode :} + callback {if ((int) o->value()==0){ /* Poly (implies no legato) */ + part->Ppolymode=1; + part->Plegatomode=0; +} else { + if ((int) o->value()==1){ /* Mono (implies no legato) */ + part->Ppolymode=0; + part->Plegatomode=0; + } else { + if ((int) o->value()==2){ /* Legato (implies mono) */ + part->Ppolymode=0; + part->Plegatomode=1; + }; + }; +};} open + tooltip {Poly, Mono or Legato mode} xywh {80 130 64 18} down_box BORDER_BOX labelfont 1 labelsize 11 textfont 1 textsize 10 + code0 {o->add("Poly"); o->add("Mono"); o->add("Legato");} + code1 {if (part->Ppolymode!=0) o->value(0); else o->value(1);} + code2 {if (part->Ppolymode==0 && part->Plegatomode!=0) o->value(2);} + } {} + } + Fl_Check_Button {} { + label Enabled + callback {pthread_mutex_lock(&master->mutex); +master->partonoff(npart,(int) o->value()); +pthread_mutex_unlock(&master->mutex); +if (part->Penabled==0) partgroupui->deactivate(); + else partgroupui->activate();} + xywh {90 5 75 20} down_box DOWN_BOX labelfont 1 labelsize 11 + code0 {o->value(part->Penabled);} + } + } + Fl_Window ctlwindow { + label Controllers + private xywh {198 472 460 130} type Double hide + } { + Fl_Check_Button {} { + label Expr + callback {part->ctl.expression.receive=(int) o->value();} + tooltip {Expression enable} xywh {155 55 45 20} box THIN_UP_BOX down_box DOWN_BOX labelsize 10 + code0 {o->value(part->ctl.expression.receive);} + } + Fl_Dial {} { + label PanDpth + callback {part->ctl.panning.depth=(int) o->value();} + tooltip {Panning Depth} xywh {10 55 30 30} labelsize 10 maximum 127 step 1 + code0 {o->value(part->ctl.panning.depth);} + class WidgetPDial + } + Fl_Dial {} { + label FltCut + callback {part->ctl.filtercutoff.depth=(int) o->value();} + tooltip {Filter Cutoff depth} xywh {90 55 30 30} labelsize 10 maximum 127 step 1 + code0 {o->value(part->ctl.filtercutoff.depth);} + class WidgetPDial + } + Fl_Dial {} { + label FltQ + callback {part->ctl.filterq.depth=(int) o->value();} + tooltip {Filter Q depth} xywh {50 55 30 30} labelsize 10 maximum 127 step 1 + code0 {o->value(part->ctl.filterq.depth);} + class WidgetPDial + } + Fl_Dial {} { + label BwDpth + callback {part->ctl.bandwidth.depth=(int) o->value();} + tooltip {BandWidth depth} xywh {125 10 30 30} labelsize 10 maximum 127 step 1 + code0 {o->value(part->ctl.bandwidth.depth);} + class WidgetPDial + } + Fl_Dial {} { + label ModWh + callback {part->ctl.modwheel.depth=(int) o->value();} + tooltip {Modulation Wheel depth} xywh {50 10 30 30} labelsize 10 maximum 127 step 1 + code0 {o->value(part->ctl.modwheel.depth);} + class WidgetPDial + } + Fl_Counter {} { + label {PWheelB.Rng (cents)} + callback {part->ctl.pitchwheel.bendrange=(int) o->value();} + tooltip {Pitch Wheel Bend Range (cents)} xywh {165 15 110 20} labelsize 10 align 1 minimum -6400 maximum 6400 step 1 + code0 {o->value(part->ctl.pitchwheel.bendrange);} + code1 {o->lstep(100);} + } + Fl_Check_Button {} { + label FMamp + callback {part->ctl.fmamp.receive=(int) o->value();} + tooltip {FM amplitude enable} xywh {205 55 60 20} box THIN_UP_BOX down_box DOWN_BOX labelsize 10 + code0 {o->value(part->ctl.fmamp.receive);} + } + Fl_Check_Button {} { + label Vol + callback {part->ctl.volume.receive=(int) o->value();} + tooltip {Volume enable} xywh {155 80 45 20} box THIN_UP_BOX down_box DOWN_BOX labelsize 10 + code0 {o->value(part->ctl.volume.receive);} + } + Fl_Check_Button {} { + label Sustain + callback {part->ctl.sustain.receive=(int) o->value(); +if (part->ctl.sustain.receive==0) { + part->RelaseSustainedKeys(); + part->ctl.setsustain(0); +};} + tooltip {Sustain pedal enable} xywh {205 80 60 20} box THIN_UP_BOX down_box DOWN_BOX labelsize 10 + code0 {o->value(part->ctl.sustain.receive);} + } + Fl_Button {} { + label Close + callback {ctlwindow->hide();} + xywh {330 105 95 20} box THIN_UP_BOX + } + Fl_Button {} { + label {Reset all controllers} + callback {part->SetController(C_resetallcontrollers,0);} + xywh {5 105 210 20} box THIN_UP_BOX + } + Fl_Group {} { + label Portamento open + xywh {280 15 120 85} box ENGRAVED_FRAME labelfont 1 labelsize 10 + } { + Fl_Check_Button {} { + label Rcv + callback {part->ctl.portamento.receive=(int) o->value();} + tooltip {Receive Portamento Controllers} xywh {285 20 40 20} box THIN_UP_BOX down_box DOWN_BOX labelsize 10 + code0 {o->value(part->ctl.portamento.receive);} + } + Fl_Dial {} { + label time + callback {part->ctl.portamento.time=(int) o->value();} + tooltip {Portamento time} xywh {285 60 25 25} labelsize 10 maximum 127 step 1 + code0 {o->value(part->ctl.portamento.time);} + class WidgetPDial + } + Fl_Counter {} { + label thresh + callback {part->ctl.portamento.pitchthresh=(int) o->value();} + tooltip {Minimum or max. difference of the notes in order to do the portamento (x 100 cents)} xywh {340 20 50 20} type Simple labelsize 10 minimum 0 maximum 127 step 1 + code0 {o->value(part->ctl.portamento.pitchthresh);} + } + Fl_Check_Button {} { + label {th.type} + callback {part->ctl.portamento.pitchthreshtype=(int) o->value();} + tooltip {Threshold type (min/max)} xywh {370 70 15 15} down_box DOWN_BOX labelsize 10 align 2 + code0 {o->value(part->ctl.portamento.pitchthreshtype);} + } + Fl_Box {} { + label {x100 cnt.} + xywh {340 50 55 15} labelsize 10 align 16 + } + Fl_Dial {} { + label {t.dn/up} + callback {int x=(int) o->value(); + +part->ctl.portamento.updowntimestretch=x;} + tooltip {Portamento time stretch (up/down)} xywh {315 60 25 25} labelsize 10 maximum 127 step 1 + code0 {o->value(part->ctl.portamento.updowntimestretch);} + class WidgetPDial + } + } + Fl_Group {} { + label Resonance open + xywh {400 15 45 85} box ENGRAVED_BOX labelfont 1 labelsize 10 + } { + Fl_Dial {} { + label BWdpth + callback {part->ctl.resonancebandwidth.depth=(int) o->value();} + tooltip {BandWidth controller depth} xywh {410 60 25 25} labelsize 10 maximum 127 step 1 + code0 {o->value(part->ctl.resonancebandwidth.depth);} + class WidgetPDial + } + Fl_Dial {} { + label CFdpth + callback {part->ctl.resonancecenter.depth=(int) o->value();} + tooltip {Center Frequency controller Depth} xywh {410 20 25 25} labelsize 10 maximum 127 step 1 + code0 {o->value(part->ctl.resonancecenter.depth);} + class WidgetPDial + } + } + Fl_Check_Button {} { + label {Exp MWh} + callback {part->ctl.modwheel.exponential=(int) o->value();} + tooltip {Exponential modulation wheel} xywh {10 15 40 25} down_box DOWN_BOX labelsize 10 align 148 + code0 {o->value(part->ctl.modwheel.exponential);} + } + Fl_Check_Button {} { + label {Exp BW} + callback {part->ctl.bandwidth.exponential=(int) o->value();} + tooltip {Exponential BandWidth Controller} xywh {85 15 35 25} down_box DOWN_BOX labelsize 10 align 148 + code0 {o->value(part->ctl.bandwidth.exponential);} + } + } + Fl_Window partfx { + label {Part's Insert Effects} + private xywh {121 424 390 145} type Double hide + } { + Fl_Counter inseffnocounter { + label {FX No.} + callback {ninseff=(int) o->value()-1; +insefftype->value(part->partefx[ninseff]->geteffect()); +//insefftype->do_callback(); +inseffectui->refresh(part->partefx[ninseff]); +int x=part->Pefxroute[ninseff]; +if (x==127) x=1; +bypasseff->value(part->Pefxbypass[ninseff]); + +sendtochoice->value(x);} + xywh {5 110 80 20} type Simple labelfont 1 align 6 minimum 1 maximum 127 step 1 textfont 1 + code0 {o->bounds(1,NUM_PART_EFX);} + code1 {o->value(ninseff+1);} + } + Fl_Choice insefftype { + label EffType + callback {pthread_mutex_lock(part->mutex); +part->partefx[ninseff]->changeeffect((int) o->value()); +pthread_mutex_unlock(part->mutex); +inseffectui->refresh(part->partefx[ninseff]);} + xywh {155 110 70 15} down_box BORDER_BOX labelsize 10 align 6 + code0 {o->value(part->partefx[ninseff]->geteffect());} + } { + MenuItem {} { + label {No Effect} + xywh {35 35 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Reverb + xywh {45 45 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Echo + xywh {55 55 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Chorus + xywh {65 65 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Phaser + xywh {70 70 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label AlienWah + xywh {80 80 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label Distortion + xywh {90 90 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label EQ + xywh {100 100 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label DynFilter + xywh {110 110 100 20} labelfont 1 labelsize 10 + } + } + Fl_Group inseffectuigroup { + xywh {5 5 380 100} box FLAT_BOX color 48 + } { + Fl_Group inseffectui { + xywh {5 5 380 95} + code0 {o->init(part->partefx[ninseff]);} + class EffUI + } {} + } + Fl_Button {} { + label Close + callback {partfx->hide();} + xywh {325 115 60 20} box THIN_UP_BOX + } + Fl_Choice sendtochoice { + label {Send To.} + callback {int x=(int) o->value(); +part->Pefxroute[ninseff]=x; +if (x==2) part->partefx[ninseff]->setdryonly(true); + else part->partefx[ninseff]->setdryonly(false);} + xywh {235 110 80 15} down_box BORDER_BOX labelsize 10 align 6 + code0 {int x=part->Pefxroute[ninseff]; if (x==127) x=1;} + code1 {o->value(x);} + } { + MenuItem {} { + label {Next Effect} + xywh {45 45 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label {Part Out} + xywh {55 55 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label {Dry Out} + xywh {65 65 100 20} labelfont 1 labelsize 10 + } + } + Fl_Check_Button bypasseff { + label bypass + callback {part->Pefxbypass[ninseff]=(((int)o->value())!=0);} + tooltip {if the effect is not used (is bypassed)} xywh {90 110 60 15} down_box DOWN_BOX labelsize 11 + code0 {int x=part->Pefxbypass[ninseff];o->value(x);} + } + Fl_Button {} { + label C + callback {presetsui->copy(part->partefx[ninseff]);} + xywh {90 127 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 11 labelcolor 7 + } + Fl_Button {} { + label P + callback {pthread_mutex_lock(&master->mutex); +presetsui->paste(part->partefx[ninseff],inseffectui); +pthread_mutex_unlock(&master->mutex);} + xywh {120 127 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 11 labelcolor 7 + } + } + Fl_Window instrumentkitlist { + label {Instrument Kit} + xywh {113 324 670 370} type Double hide + } { + Fl_Button {} { + label {Close Window} + callback {instrumentkitlist->hide();} + xywh {375 350 160 20} box THIN_UP_BOX + } + Fl_Scroll kitlist { + xywh {0 15 670 330} type VERTICAL box THIN_UP_BOX + code0 {if (part->Pkitmode==0) o->deactivate();} + } { + Fl_Pack {} { + xywh {0 20 670 320} + code0 {for (int i=0;iinit(part,i,master,this);}} + } {} + } + Fl_Box {} { + label {No.} + xywh {5 0 25 15} labelfont 1 labelsize 11 align 18 + } + Fl_Box {} { + label {M.} + xywh {55 0 25 15} labelfont 1 labelsize 11 align 18 + } + Fl_Box {} { + label {Min.k} + xywh {235 0 40 15} labelfont 1 labelsize 11 align 18 + } + Fl_Box {} { + label {Max.k} + xywh {345 0 40 15} labelfont 1 labelsize 11 align 18 + } + Fl_Box {} { + label ADsynth + xywh {405 0 50 15} labelfont 1 labelsize 11 align 18 + } + Fl_Box {} { + label SUBsynth + xywh {470 0 60 15} labelfont 1 labelsize 11 align 18 + } + Fl_Choice {} { + label Mode + callback {part->Pkitmode=(int) o->value(); +if (part->Pkitmode==0) { + kitlist->deactivate(); + } else { + kitlist->activate(); +};} + xywh {35 350 70 15} down_box BORDER_BOX labelsize 11 textfont 1 textsize 11 + code0 {o->value(part->Pkitmode);} + } { + MenuItem {} { + label OFF + xywh {0 0 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label MULTI + xywh {10 10 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label SINGLE + xywh {20 20 100 20} labelfont 1 labelsize 11 + } + } + Fl_Check_Button {} { + label {Drum mode} + callback {part->Pdrummode=(int) o->value();} + xywh {285 350 70 15} down_box DOWN_BOX labelsize 10 + code0 {o->value(part->Pdrummode);} + } + Fl_Box {} { + label {FX.r.} + xywh {620 0 30 15} labelfont 1 labelsize 11 align 18 + } + Fl_Box {} { + label PADsynth + xywh {540 0 60 15} labelfont 1 labelsize 11 align 18 + } + } + Fl_Window instrumenteditwindow { + label {Instrument Edit} + xywh {182 214 395 360} type Double hide + } { + Fl_Group {} { + xywh {0 220 395 110} box ENGRAVED_FRAME + } { + Fl_Group {} { + label PADsynth + xywh {205 245 100 80} box ENGRAVED_FRAME labelfont 1 + } { + Fl_Button padeditbutton { + label Edit + callback {showparameters(0,2);} + xywh {215 280 80 35} box PLASTIC_UP_BOX color 222 selection_color 220 labelfont 1 labelsize 13 align 128 + code0 {if (part->kit[0].Ppadenabled==0) o->deactivate();} + } + Fl_Check_Button padsynenabledcheck { + label Enabled + callback {int x=(int) o->value(); +part->kit[0].Ppadenabled=x; +if (x==0) padeditbutton->deactivate(); + else padeditbutton->activate();} + tooltip {enable/disable PADsynth} xywh {215 255 80 20} box PLASTIC_UP_BOX down_box DOWN_BOX color 222 selection_color 218 labelfont 1 labelsize 11 + code1 {o->value(part->kit[0].Ppadenabled);} + } + } + Fl_Group {} { + label ADDsynth + xywh {5 245 100 80} box ENGRAVED_FRAME labelfont 1 + } { + Fl_Check_Button adsynenabledcheck { + label Enabled + callback {int x=(int) o->value(); +part->kit[0].Padenabled=x; +if (x==0) adeditbutton->deactivate(); + else adeditbutton->activate();} + tooltip {enable/disable ADsynth} xywh {15 255 80 20} box PLASTIC_UP_BOX down_box DOWN_BOX color 222 selection_color 218 labelfont 1 labelsize 11 + code1 {o->value(part->kit[0].Padenabled);} + } + Fl_Button adeditbutton { + label Edit + callback {showparameters(0,0);} + xywh {15 281 80 34} box PLASTIC_UP_BOX color 222 selection_color 220 labelfont 1 labelsize 13 align 128 + code0 {if (part->kit[0].Padenabled==0) o->deactivate();} + } + } + Fl_Group {} { + label SUBsynth + xywh {105 245 100 80} box ENGRAVED_FRAME labelfont 1 + } { + Fl_Check_Button subsynenabledcheck { + label Enabled + callback {int x=(int) o->value(); +part->kit[0].Psubenabled=x; +if (x==0) subeditbutton->deactivate(); + else subeditbutton->activate();} + tooltip {enable/disable SUBsynth} xywh {115 255 80 20} box PLASTIC_UP_BOX down_box DOWN_BOX color 222 selection_color 218 labelfont 1 labelsize 11 + code1 {o->value(part->kit[0].Psubenabled);} + } + Fl_Button subeditbutton { + label Edit + callback {showparameters(0,1);} + xywh {115 280 80 35} box PLASTIC_UP_BOX color 222 selection_color 220 labelfont 1 labelsize 13 align 128 + code0 {if (part->kit[0].Psubenabled==0) o->deactivate();} + } + } + Fl_Button {} { + label {Kit Edit} + callback {instrumentkitlist->show();} + xywh {310 245 80 35} box PLASTIC_UP_BOX color 238 selection_color 220 labelfont 1 align 128 + } + Fl_Button {} { + label Effects + callback {partfx->show();} + xywh {310 290 80 35} box PLASTIC_UP_BOX color 230 labelfont 1 labelsize 13 + } + } + Fl_Group {} { + xywh {0 5 395 215} box ENGRAVED_FRAME + } { + Fl_Input {} { + label {Author and Copyright} + callback {snprintf((char *)part->info.Pauthor,MAX_INFO_TEXT_SIZE,"%s",o->value());} + xywh {5 60 385 50} type Multiline color 26 labelsize 10 align 5 + code0 {o->maximum_size(MAX_INFO_TEXT_SIZE);} + code1 {o->value((char *) &part->info.Pauthor);} + } + Fl_Input {} { + label Comments + callback {snprintf((char *)part->info.Pcomments,MAX_INFO_TEXT_SIZE,"%s",o->value());} + xywh {5 125 385 90} type Multiline color 26 labelsize 11 align 5 + code0 {o->maximum_size(MAX_INFO_TEXT_SIZE);} + code1 {o->value((char *) &part->info.Pcomments);} + } + Fl_Choice {} { + label {Type:} + callback {part->info.Ptype=o->value();} + xywh {5 25 155 20} down_box BORDER_BOX labelfont 1 labelsize 11 align 5 textsize 10 + code0 {o->value(part->info.Ptype);} + } { + MenuItem {} { + label {--------------------------} + xywh {20 20 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label Piano + xywh {10 10 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label {Chromatic Percussion} + xywh {20 20 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label Organ + xywh {30 30 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label Guitar + xywh {40 40 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label Bass + xywh {50 50 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label {Solo Strings} + xywh {60 60 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label Ensemble + xywh {70 70 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label Brass + xywh {80 80 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label Reed + xywh {90 90 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label Pipe + xywh {100 100 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label {Synth Lead} + xywh {110 110 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label {Synth Pad} + xywh {120 120 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label {Synth Effects} + xywh {130 130 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label Ethnic + xywh {140 140 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label Percussive + xywh {150 150 100 20} labelfont 1 labelsize 11 + } + MenuItem {} { + label {Sound Effects} + xywh {160 160 100 20} labelfont 1 labelsize 11 + } + } + } + Fl_Button {} { + label Close + callback {instrumenteditwindow->hide();} + xywh {150 335 95 25} box THIN_UP_BOX + } + } + } + Function {PartUI(int x,int y, int w, int h, const char *label=0):Fl_Group(x,y,w,h,label)} {} { + code {part=NULL; +adnoteui=NULL; +subnoteui=NULL; +padnoteui=NULL; +lastkititem=-1;} {} + } + Function {init(Part *part_,Master *master_,int npart_,BankUI *bankui_)} {} { + code {bankui=bankui_; +part=part_; +npart=npart_; +master=master_; +ninseff=0; + +make_window(); +partgroup->position(this->parent()->x()+2,this->parent()->y()+2); +partgroup->show(); +end(); + + +//if (config.ui.showinstrumentinfo!=0) instrumenteditwindow->show(); + +int klimits[]={1,2,3,4,5,6,7,8,9,10,15,20,30,50,100,0}; + +keylimitlist->add("OFF"); +int k=0; +int val=-1; +char tmp[10]; +while (klimits[k]!=0){ + sprintf(tmp,"%d",klimits[k]); + keylimitlist->add(tmp); + if ((val==-1)){ + if (klimits[k]>part->Pkeylimit) val=k; + }; + k++; +}; + +if (val==-1) val=k; +keylimitlist->value(val);} {} + } + Function {showparameters(int kititem,int engine)} {} { + code {if (engine==-1){//this is used if I want to clear the engine from the part + if (kititem==lastkititem) kititem=-1; + else kititem=lastkititem; +}; + +if (kititem!=lastkititem){ + if (adnoteui!=NULL) delete (adnoteui); + if (subnoteui!=NULL) delete (subnoteui); + if (padnoteui!=NULL) delete (padnoteui); + adnoteui=NULL;subnoteui=NULL;padnoteui=NULL; + lastkititem=kititem; + + if (kititem>=NUM_KIT_ITEMS) return;//bad kit item + if (kititem<0) return; + + if (part->kit[kititem].adpars!=NULL) + adnoteui=new ADnoteUI(part->kit[kititem].adpars,master); + + if (part->kit[kititem].subpars!=NULL) + subnoteui=new SUBnoteUI(part->kit[kititem].subpars); + + if (part->kit[kititem].padpars!=NULL) + padnoteui=new PADnoteUI(part->kit[kititem].padpars,master); + +}; + + + +if ((engine==0)&&(adnoteui!=NULL)) adnoteui->ADnoteGlobalParameters->show(); +if ((engine==1)&&(subnoteui!=NULL)) subnoteui->SUBparameters->show(); +if ((engine==2)&&(adnoteui!=NULL)) padnoteui->padnotewindow->show();} {} + } + Function {~PartUI()} {} { + code {if (adnoteui!=NULL) delete (adnoteui); +if (subnoteui!=NULL) delete (subnoteui); +if (padnoteui!=NULL) delete (padnoteui); + +partgroup->hide(); +//delete(partgroup); + +ctlwindow->hide(); +delete(ctlwindow); + +partfx->hide(); +delete(partfx); + +instrumentkitlist->hide(); +delete(instrumentkitlist); + +instrumenteditwindow->hide(); +delete(instrumenteditwindow);} {} + } + decl {Part *part;} {} + decl {Master *master;} {} + decl {BankUI *bankui;} {} + decl {ADnoteUI *adnoteui;} {} + decl {SUBnoteUI *subnoteui;} {} + decl {PADnoteUI *padnoteui;} {} + decl {PartSysEffSend *psyef[NUM_SYS_EFX];} {} + decl {int npart;} {} + decl {int ninseff;} {} + decl {int lastkititem;} {} + decl {PartKitItem *partkititem[NUM_KIT_ITEMS];} {} +} diff --git a/plugins/zynaddsubfx/src/UI/PartUI.h b/plugins/zynaddsubfx/src/UI/PartUI.h new file mode 100644 index 000000000..48b9d413e --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/PartUI.h @@ -0,0 +1,326 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0109 + +#ifndef PartUI_h +#define PartUI_h +#include +#include +#include +#include +#include "WidgetPDial.h" +#include "EffUI.h" +#include "BankUI.h" +#include "ADnoteUI.h" +#include "SUBnoteUI.h" +#include "PADnoteUI.h" +#include "../Misc/Config.h" +#include "../Misc/Master.h" +#include "../Misc/Part.h" + +class PartSysEffSend : public Fl_Group { + Fl_Group* make_window(); + Fl_Group *syseffsend; + void cb_01_i(WidgetPDial*, void*); + static void cb_01(WidgetPDial*, void*); +public: + PartSysEffSend(int x,int y, int w, int h, const char *label=0); + void init(Master *master_,int npart_,int neff_); + ~PartSysEffSend(); +private: + Master *master; + int neff; + int npart; +}; + +class PartUI_ { +public: + virtual void showparameters(int kititem,int engine); +}; +#include +#include +#include +#include +#include + +class PartKitItem : public Fl_Group { + Fl_Group* make_window(); + Fl_Group *partkititem; + Fl_Group *partkititemgroup; +public: + Fl_Counter *minkcounter; +private: + void cb_minkcounter_i(Fl_Counter*, void*); + static void cb_minkcounter(Fl_Counter*, void*); + void cb_m_i(Fl_Button*, void*); + static void cb_m(Fl_Button*, void*); + void cb_M_i(Fl_Button*, void*); + static void cb_M(Fl_Button*, void*); + void cb_R_i(Fl_Button*, void*); + static void cb_R(Fl_Button*, void*); +public: + Fl_Button *adeditbutton; +private: + void cb_adeditbutton_i(Fl_Button*, void*); + static void cb_adeditbutton(Fl_Button*, void*); +public: + Fl_Button *subeditbutton; +private: + void cb_subeditbutton_i(Fl_Button*, void*); + static void cb_subeditbutton(Fl_Button*, void*); + Fl_Check_Button *mutedcheck; + void cb_mutedcheck_i(Fl_Check_Button*, void*); + static void cb_mutedcheck(Fl_Check_Button*, void*); +public: + Fl_Counter *maxkcounter; +private: + void cb_maxkcounter_i(Fl_Counter*, void*); + static void cb_maxkcounter(Fl_Counter*, void*); +public: + Fl_Button *labelbutton; +private: + void cb_labelbutton_i(Fl_Button*, void*); + static void cb_labelbutton(Fl_Button*, void*); + Fl_Check_Button *adcheck; + void cb_adcheck_i(Fl_Check_Button*, void*); + static void cb_adcheck(Fl_Check_Button*, void*); + Fl_Check_Button *subcheck; + void cb_subcheck_i(Fl_Check_Button*, void*); + static void cb_subcheck(Fl_Check_Button*, void*); +public: + Fl_Choice *sendtoeffect; +private: + void cb_sendtoeffect_i(Fl_Choice*, void*); + static void cb_sendtoeffect(Fl_Choice*, void*); +public: + Fl_Button *padeditbutton; +private: + void cb_padeditbutton_i(Fl_Button*, void*); + static void cb_padeditbutton(Fl_Button*, void*); + Fl_Check_Button *padcheck; + void cb_padcheck_i(Fl_Check_Button*, void*); + static void cb_padcheck(Fl_Check_Button*, void*); + Fl_Check_Button *enabledcheck; + void cb_enabledcheck_i(Fl_Check_Button*, void*); + static void cb_enabledcheck(Fl_Check_Button*, void*); +public: + PartKitItem(int x,int y, int w, int h, const char *label=0); + void refresh(); + void init(Part *part_,int n_,Master *master_,PartUI_ *partui_); + ~PartKitItem(); +private: + Part *part; + int n; + Master *master; + char label[10]; + PartUI_ *partui; +}; +#include +#include +#include +#include +#include + +class PartUI : public Fl_Group,PartUI_ { + Fl_Group* make_window(); + Fl_Group *partgroup; +public: + Fl_Group *partgroupui; +private: + void cb_Pan_i(WidgetPDial*, void*); + static void cb_Pan(WidgetPDial*, void*); + void cb_KeyShift_i(Fl_Counter*, void*); + static void cb_KeyShift(Fl_Counter*, void*); + void cb_Grand_i(Fl_Button*, void*); + static void cb_Grand(Fl_Button*, void*); + void cb_NoteOn_i(Fl_Check_Button*, void*); + static void cb_NoteOn(Fl_Check_Button*, void*); +public: + Fl_Counter *minkcounter; +private: + void cb_minkcounter1_i(Fl_Counter*, void*); + static void cb_minkcounter1(Fl_Counter*, void*); +public: + Fl_Counter *maxkcounter; +private: + void cb_maxkcounter1_i(Fl_Counter*, void*); + static void cb_maxkcounter1(Fl_Counter*, void*); + void cb_Volume_i(WidgetPDial*, void*); + static void cb_Volume(WidgetPDial*, void*); + void cb_Vel_i(WidgetPDial*, void*); + static void cb_Vel(WidgetPDial*, void*); + void cb_Vel1_i(WidgetPDial*, void*); + static void cb_Vel1(WidgetPDial*, void*); + void cb_Controllers_i(Fl_Button*, void*); + static void cb_Controllers(Fl_Button*, void*); + void cb_Portamento_i(Fl_Check_Button*, void*); + static void cb_Portamento(Fl_Check_Button*, void*); + void cb_Edit_i(Fl_Button*, void*); + static void cb_Edit(Fl_Button*, void*); + void cb_m1_i(Fl_Button*, void*); + static void cb_m1(Fl_Button*, void*); + void cb_M1_i(Fl_Button*, void*); + static void cb_M1(Fl_Button*, void*); + void cb_R1_i(Fl_Button*, void*); + static void cb_R1(Fl_Button*, void*); + void cb_MIDI_i(Fl_Choice*, void*); + static void cb_MIDI(Fl_Choice*, void*); +public: + Fl_Choice *keylimitlist; +private: + void cb_keylimitlist_i(Fl_Choice*, void*); + static void cb_keylimitlist(Fl_Choice*, void*); + void cb_Mode_i(Fl_Choice*, void*); + static void cb_Mode(Fl_Choice*, void*); + void cb_Enabled_i(Fl_Check_Button*, void*); + static void cb_Enabled(Fl_Check_Button*, void*); + Fl_Double_Window *ctlwindow; + void cb_Expr_i(Fl_Check_Button*, void*); + static void cb_Expr(Fl_Check_Button*, void*); + void cb_PanDpth_i(WidgetPDial*, void*); + static void cb_PanDpth(WidgetPDial*, void*); + void cb_FltCut_i(WidgetPDial*, void*); + static void cb_FltCut(WidgetPDial*, void*); + void cb_FltQ_i(WidgetPDial*, void*); + static void cb_FltQ(WidgetPDial*, void*); + void cb_BwDpth_i(WidgetPDial*, void*); + static void cb_BwDpth(WidgetPDial*, void*); + void cb_ModWh_i(WidgetPDial*, void*); + static void cb_ModWh(WidgetPDial*, void*); + void cb_PWheelB_i(Fl_Counter*, void*); + static void cb_PWheelB(Fl_Counter*, void*); + void cb_FMamp_i(Fl_Check_Button*, void*); + static void cb_FMamp(Fl_Check_Button*, void*); + void cb_Vol_i(Fl_Check_Button*, void*); + static void cb_Vol(Fl_Check_Button*, void*); + void cb_Sustain_i(Fl_Check_Button*, void*); + static void cb_Sustain(Fl_Check_Button*, void*); + void cb_Close_i(Fl_Button*, void*); + static void cb_Close(Fl_Button*, void*); + void cb_Reset_i(Fl_Button*, void*); + static void cb_Reset(Fl_Button*, void*); + void cb_Rcv_i(Fl_Check_Button*, void*); + static void cb_Rcv(Fl_Check_Button*, void*); + void cb_time_i(WidgetPDial*, void*); + static void cb_time(WidgetPDial*, void*); + void cb_thresh_i(Fl_Counter*, void*); + static void cb_thresh(Fl_Counter*, void*); + void cb_th_i(Fl_Check_Button*, void*); + static void cb_th(Fl_Check_Button*, void*); + void cb_t_i(WidgetPDial*, void*); + static void cb_t(WidgetPDial*, void*); + void cb_BWdpth_i(WidgetPDial*, void*); + static void cb_BWdpth(WidgetPDial*, void*); + void cb_CFdpth_i(WidgetPDial*, void*); + static void cb_CFdpth(WidgetPDial*, void*); + void cb_Exp_i(Fl_Check_Button*, void*); + static void cb_Exp(Fl_Check_Button*, void*); + void cb_Exp1_i(Fl_Check_Button*, void*); + static void cb_Exp1(Fl_Check_Button*, void*); + Fl_Double_Window *partfx; +public: + Fl_Counter *inseffnocounter; +private: + void cb_inseffnocounter_i(Fl_Counter*, void*); + static void cb_inseffnocounter(Fl_Counter*, void*); +public: + Fl_Choice *insefftype; +private: + void cb_insefftype_i(Fl_Choice*, void*); + static void cb_insefftype(Fl_Choice*, void*); + static Fl_Menu_Item menu_insefftype[]; +public: + Fl_Group *inseffectuigroup; + EffUI *inseffectui; +private: + void cb_Close1_i(Fl_Button*, void*); + static void cb_Close1(Fl_Button*, void*); +public: + Fl_Choice *sendtochoice; +private: + void cb_sendtochoice_i(Fl_Choice*, void*); + static void cb_sendtochoice(Fl_Choice*, void*); + static Fl_Menu_Item menu_sendtochoice[]; +public: + Fl_Check_Button *bypasseff; +private: + void cb_bypasseff_i(Fl_Check_Button*, void*); + static void cb_bypasseff(Fl_Check_Button*, void*); + void cb_C_i(Fl_Button*, void*); + static void cb_C(Fl_Button*, void*); + void cb_P_i(Fl_Button*, void*); + static void cb_P(Fl_Button*, void*); +public: + Fl_Double_Window *instrumentkitlist; +private: + void cb_Close2_i(Fl_Button*, void*); + static void cb_Close2(Fl_Button*, void*); +public: + Fl_Scroll *kitlist; +private: + void cb_Mode1_i(Fl_Choice*, void*); + static void cb_Mode1(Fl_Choice*, void*); + static Fl_Menu_Item menu_Mode[]; + void cb_Drum_i(Fl_Check_Button*, void*); + static void cb_Drum(Fl_Check_Button*, void*); +public: + Fl_Double_Window *instrumenteditwindow; + Fl_Button *padeditbutton; +private: + void cb_padeditbutton1_i(Fl_Button*, void*); + static void cb_padeditbutton1(Fl_Button*, void*); +public: + Fl_Check_Button *padsynenabledcheck; +private: + void cb_padsynenabledcheck_i(Fl_Check_Button*, void*); + static void cb_padsynenabledcheck(Fl_Check_Button*, void*); +public: + Fl_Check_Button *adsynenabledcheck; +private: + void cb_adsynenabledcheck_i(Fl_Check_Button*, void*); + static void cb_adsynenabledcheck(Fl_Check_Button*, void*); +public: + Fl_Button *adeditbutton; +private: + void cb_adeditbutton1_i(Fl_Button*, void*); + static void cb_adeditbutton1(Fl_Button*, void*); +public: + Fl_Check_Button *subsynenabledcheck; +private: + void cb_subsynenabledcheck_i(Fl_Check_Button*, void*); + static void cb_subsynenabledcheck(Fl_Check_Button*, void*); +public: + Fl_Button *subeditbutton; +private: + void cb_subeditbutton1_i(Fl_Button*, void*); + static void cb_subeditbutton1(Fl_Button*, void*); + void cb_Kit_i(Fl_Button*, void*); + static void cb_Kit(Fl_Button*, void*); + void cb_Effects_i(Fl_Button*, void*); + static void cb_Effects(Fl_Button*, void*); + void cb_Author_i(Fl_Input*, void*); + static void cb_Author(Fl_Input*, void*); + void cb_Comments_i(Fl_Input*, void*); + static void cb_Comments(Fl_Input*, void*); + void cb_Type_i(Fl_Choice*, void*); + static void cb_Type(Fl_Choice*, void*); + static Fl_Menu_Item menu_Type[]; + void cb_Close3_i(Fl_Button*, void*); + static void cb_Close3(Fl_Button*, void*); +public: + PartUI(int x,int y, int w, int h, const char *label=0); + void init(Part *part_,Master *master_,int npart_,BankUI *bankui_); + void showparameters(int kititem,int engine); + ~PartUI(); +private: + Part *part; + Master *master; + BankUI *bankui; + ADnoteUI *adnoteui; + SUBnoteUI *subnoteui; + PADnoteUI *padnoteui; + PartSysEffSend *psyef[NUM_SYS_EFX]; + int npart; + int ninseff; + int lastkititem; + PartKitItem *partkititem[NUM_KIT_ITEMS]; +}; +#endif diff --git a/plugins/zynaddsubfx/src/UI/PresetsUI.cc b/plugins/zynaddsubfx/src/UI/PresetsUI.cc new file mode 100644 index 000000000..77e77fbfe --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/PresetsUI.cc @@ -0,0 +1,266 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0109 + +#include "PresetsUI.h" + +void PresetsUI_::refresh() { +} + +PresetsUI_::~PresetsUI_() { +} + +void PresetsUI::cb_copybrowse_i(Fl_Browser* o, void*) { + int val=o->value(); +if (val!=0){ + presetname->cut(0,presetname->maximum_size()); + presetname->insert(o->text(val)); +}; +} +void PresetsUI::cb_copybrowse(Fl_Browser* o, void* v) { + ((PresetsUI*)(o->parent()->user_data()))->cb_copybrowse_i(o,v); +} + +void PresetsUI::cb_copypbutton_i(Fl_Button*, void*) { + const char *tmp=presetname->value(); +if (tmp!=NULL) { + if (strlen(tmp)>0){ + p->copy(tmp); + copywin->hide(); + }; +}; +} +void PresetsUI::cb_copypbutton(Fl_Button* o, void* v) { + ((PresetsUI*)(o->parent()->user_data()))->cb_copypbutton_i(o,v); +} + +void PresetsUI::cb_copybutton_i(Fl_Button*, void*) { + p->copy(NULL); +copywin->hide(); +} +void PresetsUI::cb_copybutton(Fl_Button* o, void* v) { + ((PresetsUI*)(o->parent()->user_data()))->cb_copybutton_i(o,v); +} + +void PresetsUI::cb_Cancel_i(Fl_Button*, void*) { + copywin->hide(); +} +void PresetsUI::cb_Cancel(Fl_Button* o, void* v) { + ((PresetsUI*)(o->parent()->user_data()))->cb_Cancel_i(o,v); +} + +void PresetsUI::cb_presetname_i(Fl_Input* o, void*) { + const char *tmp=o->value(); +if (tmp==NULL) tmp=""; +if (strlen(tmp)>0) { + copybutton->deactivate(); + copypbutton->activate(); +} else { + copybutton->activate(); + copypbutton->deactivate(); +}; +} +void PresetsUI::cb_presetname(Fl_Input* o, void* v) { + ((PresetsUI*)(o->parent()->user_data()))->cb_presetname_i(o,v); +} + +void PresetsUI::cb_pastebrowse_i(Fl_Browser* o, void*) { + if (o->value()==0) { + pastepbutton->deactivate(); + deletepbutton->deactivate(); +}else{ + pastepbutton->activate(); + deletepbutton->activate(); +}; +} +void PresetsUI::cb_pastebrowse(Fl_Browser* o, void* v) { + ((PresetsUI*)(o->parent()->user_data()))->cb_pastebrowse_i(o,v); +} + +void PresetsUI::cb_pastepbutton_i(Fl_Button*, void*) { + int n=pastebrowse->value(); +if (n!=0) p->paste(n); +pastewin->hide(); +pui->refresh(); +} +void PresetsUI::cb_pastepbutton(Fl_Button* o, void* v) { + ((PresetsUI*)(o->parent()->user_data()))->cb_pastepbutton_i(o,v); +} + +void PresetsUI::cb_pastebutton_i(Fl_Button*, void*) { + p->paste(0); +pastewin->hide(); +pui->refresh(); +} +void PresetsUI::cb_pastebutton(Fl_Button* o, void* v) { + ((PresetsUI*)(o->parent()->user_data()))->cb_pastebutton_i(o,v); +} + +void PresetsUI::cb_Cancel1_i(Fl_Button*, void*) { + pastewin->hide(); +} +void PresetsUI::cb_Cancel1(Fl_Button* o, void* v) { + ((PresetsUI*)(o->parent()->user_data()))->cb_Cancel1_i(o,v); +} + +void PresetsUI::cb_deletepbutton_i(Fl_Button*, void*) { + int n=pastebrowse->value(); +if (n!=0) p->deletepreset(n); +rescan(); +} +void PresetsUI::cb_deletepbutton(Fl_Button* o, void* v) { + ((PresetsUI*)(o->parent()->user_data()))->cb_deletepbutton_i(o,v); +} + +PresetsUI::PresetsUI() { + p=NULL; +make_window(); +} + +PresetsUI::~PresetsUI() { + copywin->hide();delete(copywin); +pastewin->hide();delete(pastewin); +} + +Fl_Double_Window* PresetsUI::make_window() { + { copywin = new Fl_Double_Window(265, 430, "Copy to Clipboard/Preset"); + copywin->box(FL_PLASTIC_THIN_UP_BOX); + copywin->color((Fl_Color)238); + copywin->user_data((void*)(this)); + { copybrowse = new Fl_Browser(10, 25, 245, 320); + copybrowse->type(1); + copybrowse->callback((Fl_Callback*)cb_copybrowse); + } // Fl_Browser* copybrowse + { copypbutton = new Fl_Button(145, 355, 110, 20, "Copy to Preset"); + copypbutton->box(FL_THIN_UP_BOX); + copypbutton->callback((Fl_Callback*)cb_copypbutton); + } // Fl_Button* copypbutton + { copybutton = new Fl_Button(25, 385, 90, 35, "Copy to Clipboard"); + copybutton->box(FL_THIN_UP_BOX); + copybutton->callback((Fl_Callback*)cb_copybutton); + copybutton->align(192); + } // Fl_Button* copybutton + { Fl_Button* o = new Fl_Button(160, 385, 80, 35, "Cancel"); + o->box(FL_THIN_UP_BOX); + o->callback((Fl_Callback*)cb_Cancel); + o->align(192); + } // Fl_Button* o + { Fl_Box* o = new Fl_Box(10, 5, 40, 15, "Type:"); + o->labelsize(11); + o->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE); + } // Fl_Box* o + { copytypetext = new Fl_Box(50, 5, 205, 15); + copytypetext->box(FL_FLAT_BOX); + copytypetext->color((Fl_Color)238); + copytypetext->labelfont(1); + copytypetext->labelsize(11); + copytypetext->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE); + } // Fl_Box* copytypetext + { presetname = new Fl_Input(10, 355, 130, 20); + presetname->callback((Fl_Callback*)cb_presetname); + presetname->when(FL_WHEN_CHANGED); + } // Fl_Input* presetname + copywin->set_modal(); + copywin->end(); + } // Fl_Double_Window* copywin + { pastewin = new Fl_Double_Window(265, 430, "Paste from Clipboard/Preset"); + pastewin->box(FL_PLASTIC_THIN_UP_BOX); + pastewin->color((Fl_Color)238); + pastewin->user_data((void*)(this)); + { pastebrowse = new Fl_Browser(10, 25, 245, 320); + pastebrowse->type(2); + pastebrowse->callback((Fl_Callback*)cb_pastebrowse); + } // Fl_Browser* pastebrowse + { pastepbutton = new Fl_Button(10, 355, 160, 20, "Paste from Preset"); + pastepbutton->box(FL_THIN_UP_BOX); + pastepbutton->callback((Fl_Callback*)cb_pastepbutton); + } // Fl_Button* pastepbutton + { pastebutton = new Fl_Button(25, 385, 90, 35, "Paste from Clipboard"); + pastebutton->box(FL_THIN_UP_BOX); + pastebutton->callback((Fl_Callback*)cb_pastebutton); + pastebutton->align(192); + } // Fl_Button* pastebutton + { Fl_Button* o = new Fl_Button(160, 385, 80, 35, "Cancel"); + o->box(FL_THIN_UP_BOX); + o->callback((Fl_Callback*)cb_Cancel1); + o->align(192); + } // Fl_Button* o + { pastetypetext = new Fl_Box(55, 5, 200, 15); + pastetypetext->box(FL_FLAT_BOX); + pastetypetext->color((Fl_Color)238); + pastetypetext->labelfont(1); + pastetypetext->labelsize(11); + pastetypetext->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE); + } // Fl_Box* pastetypetext + { Fl_Box* o = new Fl_Box(15, 5, 40, 15, "Type:"); + o->labelsize(11); + o->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE); + } // Fl_Box* o + { deletepbutton = new Fl_Button(180, 355, 75, 20, "Delete"); + deletepbutton->box(FL_THIN_UP_BOX); + deletepbutton->callback((Fl_Callback*)cb_deletepbutton); + } // Fl_Button* deletepbutton + pastewin->set_modal(); + pastewin->end(); + } // Fl_Double_Window* pastewin + return pastewin; +} + +void PresetsUI::copy(Presets *p) { + copybutton->activate(); +copypbutton->deactivate(); + + +this->p=p; +this->pui=NULL; +bool but=(Fl::event_button()!=FL_LEFT_MOUSE); +presetname->cut(0,presetname->maximum_size()); + +if (but) p->copy(NULL); + else { + rescan(); + copytypetext->label(&p->type[1]); + copywin->show(); + }; +} + +void PresetsUI::paste(Presets *p,PresetsUI_ *pui) { + this->p=p; +this->pui=pui; +bool but=(Fl::event_button()!=FL_LEFT_MOUSE); +pastepbutton->deactivate(); +deletepbutton->deactivate(); + +if (but) { + p->paste(0); + pui->refresh(); +} else { + rescan(); + pastetypetext->label(&p->type[1]); + if (p->checkclipboardtype()) pastebutton->activate(); + else pastebutton->deactivate(); + pastewin->show(); + }; +} + +void PresetsUI::copy(Presets *p,int n) { + p->setelement(n); +copy(p); +} + +void PresetsUI::paste(Presets *p,PresetsUI_ *pui,int n) { + p->setelement(n); +paste(p,pui); +} + +void PresetsUI::rescan() { + copybrowse->clear(); +pastebrowse->clear(); +p->rescanforpresets(); + +for (int i=0;iadd(name); + pastebrowse->add(name); +}; +} +PresetsUI *presetsui; diff --git a/plugins/zynaddsubfx/src/UI/PresetsUI.fl b/plugins/zynaddsubfx/src/UI/PresetsUI.fl new file mode 100644 index 000000000..0378d62ef --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/PresetsUI.fl @@ -0,0 +1,200 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0105 +header_name {.h} +code_name {.cc} +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include "../Params/Presets.h"} {public +} + +class PresetsUI_ {} { + Function {refresh()} {open return_type {virtual void} + } {} + Function {~PresetsUI_()} {open return_type virtual + } {} +} + +class PresetsUI {} { + Function {PresetsUI()} {} { + code {p=NULL; +make_window();} {} + } + Function {~PresetsUI()} {} { + code {copywin->hide();delete(copywin); +pastewin->hide();delete(pastewin);} {} + } + Function {make_window()} {} { + Fl_Window copywin { + label {Copy to Clipboard/Preset} + xywh {190 173 265 430} type Double box PLASTIC_THIN_UP_BOX color 238 hide modal + } { + Fl_Browser copybrowse { + callback {int val=o->value(); +if (val!=0){ + presetname->cut(0,presetname->maximum_size()); + presetname->insert(o->text(val)); +};} + xywh {10 25 245 320} type Select + } + Fl_Button copypbutton { + label {Copy to Preset} + callback {const char *tmp=presetname->value(); +if (tmp!=NULL) { + if (strlen(tmp)>0){ + p->copy(tmp); + copywin->hide(); + }; +};} + xywh {145 355 110 20} box THIN_UP_BOX + } + Fl_Button copybutton { + label {Copy to Clipboard} + callback {p->copy(NULL); +copywin->hide();} + xywh {25 385 90 35} box THIN_UP_BOX align 192 + } + Fl_Button {} { + label Cancel + callback {copywin->hide();} + xywh {160 385 80 35} box THIN_UP_BOX align 192 + } + Fl_Box {} { + label {Type:} + xywh {10 5 40 15} labelsize 11 align 20 + } + Fl_Box copytypetext { + xywh {50 5 205 15} box FLAT_BOX color 238 labelfont 1 labelsize 11 align 20 + } + Fl_Input presetname { + callback {const char *tmp=o->value(); +if (tmp==NULL) tmp=""; +if (strlen(tmp)>0) { + copybutton->deactivate(); + copypbutton->activate(); +} else { + copybutton->activate(); + copypbutton->deactivate(); +};} + xywh {10 355 130 20} when 1 + } + } + Fl_Window pastewin { + label {Paste from Clipboard/Preset} + xywh {463 173 265 430} type Double box PLASTIC_THIN_UP_BOX color 238 hide modal + } { + Fl_Browser pastebrowse { + callback {if (o->value()==0) { + pastepbutton->deactivate(); + deletepbutton->deactivate(); +}else{ + pastepbutton->activate(); + deletepbutton->activate(); +};} selected + xywh {10 25 245 320} type Hold + } + Fl_Button pastepbutton { + label {Paste from Preset} + callback {int n=pastebrowse->value(); +if (n!=0) p->paste(n); +pastewin->hide(); +pui->refresh();} + xywh {10 355 160 20} box THIN_UP_BOX + } + Fl_Button pastebutton { + label {Paste from Clipboard} + callback {p->paste(0); +pastewin->hide(); +pui->refresh();} + xywh {25 385 90 35} box THIN_UP_BOX align 192 + } + Fl_Button {} { + label Cancel + callback {pastewin->hide();} + xywh {160 385 80 35} box THIN_UP_BOX align 192 + } + Fl_Box pastetypetext { + xywh {55 5 200 15} box FLAT_BOX color 238 labelfont 1 labelsize 11 align 20 + } + Fl_Box {} { + label {Type:} + xywh {15 5 40 15} labelsize 11 align 20 + } + Fl_Button deletepbutton { + label Delete + callback {int n=pastebrowse->value(); +if (n!=0) p->deletepreset(n); +rescan();} + xywh {180 355 75 20} box THIN_UP_BOX + } + } + } + Function {copy(Presets *p)} {} { + code {copybutton->activate(); +copypbutton->deactivate(); + + +this->p=p; +this->pui=NULL; +bool but=(Fl::event_button()!=FL_LEFT_MOUSE); +presetname->cut(0,presetname->maximum_size()); + +if (but) p->copy(NULL); + else { + rescan(); + copytypetext->label(&p->type[1]); + copywin->show(); + };} {} + } + Function {paste(Presets *p,PresetsUI_ *pui)} {} { + code {this->p=p; +this->pui=pui; +bool but=(Fl::event_button()!=FL_LEFT_MOUSE); +pastepbutton->deactivate(); +deletepbutton->deactivate(); + +if (but) { + p->paste(0); + pui->refresh(); +} else { + rescan(); + pastetypetext->label(&p->type[1]); + if (p->checkclipboardtype()) pastebutton->activate(); + else pastebutton->deactivate(); + pastewin->show(); + };} {} + } + Function {copy(Presets *p,int n)} {} { + code {p->setelement(n); +copy(p);} {} + } + Function {paste(Presets *p,PresetsUI_ *pui,int n)} {} { + code {p->setelement(n); +paste(p,pui);} {} + } + Function {rescan()} {} { + code {copybrowse->clear(); +pastebrowse->clear(); +p->rescanforpresets(); + +for (int i=0;iadd(name); + pastebrowse->add(name); +};} {} + } + decl {Presets *p;} {public + } + decl {PresetsUI_ *pui;} {public + } +} + +decl {PresetsUI *presetsui;} {public +} diff --git a/plugins/zynaddsubfx/src/UI/PresetsUI.h b/plugins/zynaddsubfx/src/UI/PresetsUI.h new file mode 100644 index 000000000..6dc3bd080 --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/PresetsUI.h @@ -0,0 +1,84 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0109 + +#ifndef PresetsUI_h +#define PresetsUI_h +#include +#include +#include +#include +#include "../Params/Presets.h" + +class PresetsUI_ { +public: + virtual void refresh(); + virtual ~PresetsUI_(); +}; +#include +#include +#include +#include +#include + +class PresetsUI { +public: + PresetsUI(); + ~PresetsUI(); + Fl_Double_Window* make_window(); + Fl_Double_Window *copywin; + Fl_Browser *copybrowse; +private: + void cb_copybrowse_i(Fl_Browser*, void*); + static void cb_copybrowse(Fl_Browser*, void*); +public: + Fl_Button *copypbutton; +private: + void cb_copypbutton_i(Fl_Button*, void*); + static void cb_copypbutton(Fl_Button*, void*); +public: + Fl_Button *copybutton; +private: + void cb_copybutton_i(Fl_Button*, void*); + static void cb_copybutton(Fl_Button*, void*); + void cb_Cancel_i(Fl_Button*, void*); + static void cb_Cancel(Fl_Button*, void*); +public: + Fl_Box *copytypetext; + Fl_Input *presetname; +private: + void cb_presetname_i(Fl_Input*, void*); + static void cb_presetname(Fl_Input*, void*); +public: + Fl_Double_Window *pastewin; + Fl_Browser *pastebrowse; +private: + void cb_pastebrowse_i(Fl_Browser*, void*); + static void cb_pastebrowse(Fl_Browser*, void*); +public: + Fl_Button *pastepbutton; +private: + void cb_pastepbutton_i(Fl_Button*, void*); + static void cb_pastepbutton(Fl_Button*, void*); +public: + Fl_Button *pastebutton; +private: + void cb_pastebutton_i(Fl_Button*, void*); + static void cb_pastebutton(Fl_Button*, void*); + void cb_Cancel1_i(Fl_Button*, void*); + static void cb_Cancel1(Fl_Button*, void*); +public: + Fl_Box *pastetypetext; + Fl_Button *deletepbutton; +private: + void cb_deletepbutton_i(Fl_Button*, void*); + static void cb_deletepbutton(Fl_Button*, void*); +public: + void copy(Presets *p); + void paste(Presets *p,PresetsUI_ *pui); + void copy(Presets *p,int n); + void paste(Presets *p,PresetsUI_ *pui,int n); + void rescan(); + Presets *p; + PresetsUI_ *pui; +}; +extern PresetsUI *presetsui; +#endif diff --git a/plugins/zynaddsubfx/src/UI/ResonanceUI.cc b/plugins/zynaddsubfx/src/UI/ResonanceUI.cc new file mode 100644 index 000000000..7fbfdb178 --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/ResonanceUI.cc @@ -0,0 +1,553 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0109 + +#include "ResonanceUI.h" +//Copyright (c) 2002-2005 Nasca Octavian Paul +//License: GNU GPL version 2 or later +#include +#include +#include +#include + +ResonanceGraph::ResonanceGraph(int x,int y, int w, int h, const char *label):Fl_Box(x,y,w,h,label) { + respar=NULL; +cbwidget=NULL; +applybutton=NULL; +} + +void ResonanceGraph::init(Resonance *respar_,Fl_Value_Output *khzvalue_,Fl_Value_Output *dbvalue_) { + respar=respar_; +khzvalue=khzvalue_; +dbvalue=dbvalue_; +oldx=-1; +khzval=-1; +} + +void ResonanceGraph::draw_freq_line(REALTYPE freq,int type) { + REALTYPE freqx=respar->getfreqpos(freq); +switch(type){ + case 0:fl_line_style(FL_SOLID);break; + case 1:fl_line_style(FL_DOT);break; + case 2:fl_line_style(FL_DASH);break; +}; + + +if ((freqx>0.0)&&(freqx<1.0)) + fl_line(x()+(int) (freqx*w()),y(), + x()+(int) (freqx*w()),y()+h()); +} + +void ResonanceGraph::draw() { + int ox=x(),oy=y(),lx=w(),ly=h(),i,ix,iy,oiy; +REALTYPE freqx; + +fl_color(FL_BLACK); +fl_rectf(ox,oy,lx,ly); + + +//draw the lines +fl_color(FL_GRAY); + +fl_line_style(FL_SOLID); +fl_line(ox+2,oy+ly/2,ox+lx-2,oy+ly/2); + +freqx=respar->getfreqpos(1000.0); +if ((freqx>0.0)&&(freqx<1.0)) + fl_line(ox+(int) (freqx*lx),oy, + ox+(int) (freqx*lx),oy+ly); + +for (i=1;i<10;i++){ + if(i==1){ + draw_freq_line(i*100.0,0); + draw_freq_line(i*1000.0,0); + }else + if (i==5){ + draw_freq_line(i*100.0,2); + draw_freq_line(i*1000.0,2); + }else{ + draw_freq_line(i*100.0,1); + draw_freq_line(i*1000.0,1); + }; +}; + +draw_freq_line(10000.0,0); +draw_freq_line(20000.0,1); + +fl_line_style(FL_DOT); +int GY=10;if (lyPrespoints[0]/128.0*ly); +for (i=1;iPrespoints[i]/128.0*ly); + fl_line(ox+ix-1,oy+ly-oiy,ox+ix,oy+ly-iy); + oiy=iy; +}; +} + +int ResonanceGraph::handle(int event) { + int x_=Fl::event_x()-x(); +int y_=Fl::event_y()-y(); +if ( (x_>=0)&&(x_=0)&&(y_value(respar->getfreqx(x_*1.0/w())/1000.0); + dbvalue->value((1.0-y_*2.0/h())*respar->PmaxdB); +}; + +if ((event==FL_PUSH)||(event==FL_DRAG)){ + int leftbutton=1; + if (Fl::event_button()==FL_RIGHT_MOUSE) leftbutton=0; + if (x_<0) x_=0;if (y_<0) y_=0; + if (x_>=w()) x_=w();if (y_>=h()-1) y_=h()-1; + + if ((oldx<0)||(oldx==x_)){ + int sn=(int)(x_*1.0/w()*N_RES_POINTS); + int sp=127-(int)(y_*1.0/h()*127); + if (leftbutton!=0) respar->setpoint(sn,sp); + else respar->setpoint(sn,64); + } else { + int x1=oldx; + int x2=x_; + int y1=oldy; + int y2=y_; + if (oldx>x_){ + x1=x_;y1=y_; + x2=oldx;y2=oldy; + }; + for (int i=0;isetpoint(sn,sp); + else respar->setpoint(sn,64); + }; + }; + + oldx=x_;oldy=y_; + redraw(); +}; + +if (event==FL_RELEASE) { + oldx=-1; + if (cbwidget!=NULL) { + cbwidget->do_callback(); + if (applybutton!=NULL) { + applybutton->color(FL_RED); + applybutton->redraw(); + + }; + }; +}; + +return(1); +} + +void ResonanceGraph::setcbwidget(Fl_Widget *cbwidget,Fl_Widget *applybutton) { + this->cbwidget=cbwidget; +this->applybutton=applybutton; +} + +void ResonanceUI::cb_Close_i(Fl_Button*, void*) { + resonancewindow->hide(); +} +void ResonanceUI::cb_Close(Fl_Button* o, void* v) { + ((ResonanceUI*)(o->parent()->user_data()))->cb_Close_i(o,v); +} + +void ResonanceUI::cb_Zero_i(Fl_Button*, void*) { + for (int i=0;isetpoint(i,64); +resonancewindow->redraw(); +redrawPADnoteApply(); +} +void ResonanceUI::cb_Zero(Fl_Button* o, void* v) { + ((ResonanceUI*)(o->parent()->user_data()))->cb_Zero_i(o,v); +} + +void ResonanceUI::cb_Smooth_i(Fl_Button*, void*) { + respar->smooth(); +resonancewindow->redraw(); +redrawPADnoteApply(); +} +void ResonanceUI::cb_Smooth(Fl_Button* o, void* v) { + ((ResonanceUI*)(o->parent()->user_data()))->cb_Smooth_i(o,v); +} + +void ResonanceUI::cb_enabled_i(Fl_Check_Button* o, void*) { + respar->Penabled=(int) o->value(); +redrawPADnoteApply(); +} +void ResonanceUI::cb_enabled(Fl_Check_Button* o, void* v) { + ((ResonanceUI*)(o->parent()->user_data()))->cb_enabled_i(o,v); +} + +void ResonanceUI::cb_maxdb_i(Fl_Roller* o, void*) { + maxdbvo->value(o->value()); +respar->PmaxdB=(int) o->value(); +redrawPADnoteApply(); +} +void ResonanceUI::cb_maxdb(Fl_Roller* o, void* v) { + ((ResonanceUI*)(o->parent()->user_data()))->cb_maxdb_i(o,v); +} + +void ResonanceUI::cb_maxdbvo_i(Fl_Value_Output* o, void*) { + o->value(respar->PmaxdB); +} +void ResonanceUI::cb_maxdbvo(Fl_Value_Output* o, void* v) { + ((ResonanceUI*)(o->parent()->user_data()))->cb_maxdbvo_i(o,v); +} + +void ResonanceUI::cb_centerfreqvo_i(Fl_Value_Output* o, void*) { + o->value(respar->getcenterfreq()/1000.0); +} +void ResonanceUI::cb_centerfreqvo(Fl_Value_Output* o, void* v) { + ((ResonanceUI*)(o->parent()->user_data()))->cb_centerfreqvo_i(o,v); +} + +void ResonanceUI::cb_octavesfreqvo_i(Fl_Value_Output* o, void*) { + o->value(respar->getoctavesfreq()); +} +void ResonanceUI::cb_octavesfreqvo(Fl_Value_Output* o, void* v) { + ((ResonanceUI*)(o->parent()->user_data()))->cb_octavesfreqvo_i(o,v); +} + +void ResonanceUI::cb_RND2_i(Fl_Button*, void*) { + respar->randomize(1); +resonancewindow->redraw(); +redrawPADnoteApply(); +} +void ResonanceUI::cb_RND2(Fl_Button* o, void* v) { + ((ResonanceUI*)(o->parent()->user_data()))->cb_RND2_i(o,v); +} + +void ResonanceUI::cb_RND1_i(Fl_Button*, void*) { + respar->randomize(0); +resonancewindow->redraw(); +redrawPADnoteApply(); +} +void ResonanceUI::cb_RND1(Fl_Button* o, void* v) { + ((ResonanceUI*)(o->parent()->user_data()))->cb_RND1_i(o,v); +} + +void ResonanceUI::cb_RND3_i(Fl_Button*, void*) { + respar->randomize(2); +resonancewindow->redraw(); +redrawPADnoteApply(); +} +void ResonanceUI::cb_RND3(Fl_Button* o, void* v) { + ((ResonanceUI*)(o->parent()->user_data()))->cb_RND3_i(o,v); +} + +void ResonanceUI::cb_p1st_i(Fl_Check_Button* o, void*) { + respar->Pprotectthefundamental=(int) o->value(); +redrawPADnoteApply(); +} +void ResonanceUI::cb_p1st(Fl_Check_Button* o, void* v) { + ((ResonanceUI*)(o->parent()->user_data()))->cb_p1st_i(o,v); +} + +void ResonanceUI::cb_InterpP_i(Fl_Button*, void*) { + int type; +if (Fl::event_button()==FL_LEFT_MOUSE) type=0; + else type=1; +respar->interpolatepeaks(type); +resonancewindow->redraw(); +redrawPADnoteApply(); +} +void ResonanceUI::cb_InterpP(Fl_Button* o, void* v) { + ((ResonanceUI*)(o->parent()->user_data()))->cb_InterpP_i(o,v); +} + +void ResonanceUI::cb_centerfreq_i(WidgetPDial* o, void*) { + respar->Pcenterfreq=(int)o->value(); +centerfreqvo->do_callback(); +rg->redraw(); +redrawPADnoteApply(); +} +void ResonanceUI::cb_centerfreq(WidgetPDial* o, void* v) { + ((ResonanceUI*)(o->parent()->user_data()))->cb_centerfreq_i(o,v); +} + +void ResonanceUI::cb_octavesfreq_i(WidgetPDial* o, void*) { + respar->Poctavesfreq=(int)o->value(); +octavesfreqvo->do_callback(); +rg->redraw(); +redrawPADnoteApply(); +} +void ResonanceUI::cb_octavesfreq(WidgetPDial* o, void* v) { + ((ResonanceUI*)(o->parent()->user_data()))->cb_octavesfreq_i(o,v); +} + +void ResonanceUI::cb_C_i(Fl_Button*, void*) { + presetsui->copy(respar); +} +void ResonanceUI::cb_C(Fl_Button* o, void* v) { + ((ResonanceUI*)(o->parent()->user_data()))->cb_C_i(o,v); +} + +void ResonanceUI::cb_P_i(Fl_Button*, void*) { + presetsui->paste(respar,this); +} +void ResonanceUI::cb_P(Fl_Button* o, void* v) { + ((ResonanceUI*)(o->parent()->user_data()))->cb_P_i(o,v); +} + +void ResonanceUI::cb_applybutton_i(Fl_Button*, void*) { + applybutton->color(FL_GRAY); +applybutton->redraw(); +if (cbapplywidget!=NULL) { + cbapplywidget->do_callback(); + cbapplywidget->color(FL_GRAY); + cbapplywidget->redraw(); +}; +} +void ResonanceUI::cb_applybutton(Fl_Button* o, void* v) { + ((ResonanceUI*)(o->parent()->user_data()))->cb_applybutton_i(o,v); +} + +Fl_Double_Window* ResonanceUI::make_window() { + { resonancewindow = new Fl_Double_Window(780, 305, "Resonance"); + resonancewindow->user_data((void*)(this)); + { khzvalue = new Fl_Value_Output(415, 264, 45, 18, "kHz"); + khzvalue->labelsize(12); + khzvalue->minimum(0.001); + khzvalue->maximum(48); + khzvalue->step(0.01); + khzvalue->textfont(1); + khzvalue->textsize(12); + khzvalue->align(FL_ALIGN_RIGHT); + //this widget must be before the calling widgets + } // Fl_Value_Output* khzvalue + { dbvalue = new Fl_Value_Output(415, 282, 45, 18, "dB"); + dbvalue->labelsize(12); + dbvalue->minimum(-150); + dbvalue->maximum(150); + dbvalue->step(0.1); + dbvalue->textfont(1); + dbvalue->textsize(12); + dbvalue->align(FL_ALIGN_RIGHT); + //this widget must be before the calling widgets + } // Fl_Value_Output* dbvalue + { Fl_Group* o = new Fl_Group(6, 5, 768, 256); + o->box(FL_BORDER_BOX); + rg=new ResonanceGraph(o->x(),o->y(),o->w(),o->h(),""); + rg->init(respar,khzvalue,dbvalue); + rg->show(); + o->end(); + } // Fl_Group* o + { Fl_Button* o = new Fl_Button(690, 283, 84, 17, "Close"); + o->box(FL_THIN_UP_BOX); + o->callback((Fl_Callback*)cb_Close); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(491, 264, 66, 15, "Zero"); + o->tooltip("Clear the resonance function"); + o->box(FL_THIN_UP_BOX); + o->labelfont(1); + o->labelsize(12); + o->callback((Fl_Callback*)cb_Zero); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(491, 282, 66, 18, "Smooth"); + o->tooltip("Smooth the resonance function"); + o->box(FL_THIN_UP_BOX); + o->labelfont(1); + o->labelsize(12); + o->callback((Fl_Callback*)cb_Smooth); + } // Fl_Button* o + { Fl_Check_Button* o = enabled = new Fl_Check_Button(6, 270, 78, 27, "Enable"); + enabled->box(FL_THIN_UP_BOX); + enabled->down_box(FL_DOWN_BOX); + enabled->callback((Fl_Callback*)cb_enabled); + o->value(respar->Penabled); + } // Fl_Check_Button* enabled + { maxdb = new Fl_Roller(90, 282, 84, 15); + maxdb->type(1); + maxdb->minimum(1); + maxdb->maximum(90); + maxdb->step(1); + maxdb->value(30); + maxdb->callback((Fl_Callback*)cb_maxdb); + } // Fl_Roller* maxdb + { Fl_Value_Output* o = maxdbvo = new Fl_Value_Output(126, 264, 24, 18, "Max."); + maxdbvo->tooltip("The Maximum amplitude (dB)"); + maxdbvo->labelsize(12); + maxdbvo->minimum(1); + maxdbvo->maximum(127); + maxdbvo->step(1); + maxdbvo->value(30); + maxdbvo->textfont(1); + maxdbvo->textsize(12); + maxdbvo->callback((Fl_Callback*)cb_maxdbvo); + o->value(respar->PmaxdB); + } // Fl_Value_Output* maxdbvo + { new Fl_Box(150, 264, 24, 18, "dB"); + } // Fl_Box* o + { Fl_Value_Output* o = centerfreqvo = new Fl_Value_Output(210, 264, 33, 18, "C.f."); + centerfreqvo->tooltip("Center Frequency (kHz)"); + centerfreqvo->labelsize(12); + centerfreqvo->minimum(1); + centerfreqvo->maximum(10); + centerfreqvo->step(0.01); + centerfreqvo->value(1); + centerfreqvo->textfont(1); + centerfreqvo->textsize(12); + centerfreqvo->callback((Fl_Callback*)cb_centerfreqvo); + centerfreqvo->when(3); + o->value(respar->getcenterfreq()/1000.0); + } // Fl_Value_Output* centerfreqvo + { Fl_Value_Output* o = octavesfreqvo = new Fl_Value_Output(210, 282, 33, 18, "Oct."); + octavesfreqvo->tooltip("No. of octaves"); + octavesfreqvo->labelsize(12); + octavesfreqvo->minimum(1); + octavesfreqvo->maximum(127); + octavesfreqvo->step(1); + octavesfreqvo->value(30); + octavesfreqvo->textfont(1); + octavesfreqvo->textsize(12); + octavesfreqvo->callback((Fl_Callback*)cb_octavesfreqvo); + octavesfreqvo->when(3); + o->value(respar->getoctavesfreq()); + } // Fl_Value_Output* octavesfreqvo + { Fl_Button* o = new Fl_Button(566, 276, 42, 12, "RND2"); + o->tooltip("Randomize the resonance function"); + o->box(FL_THIN_UP_BOX); + o->labelfont(1); + o->labelsize(10); + o->callback((Fl_Callback*)cb_RND2); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(566, 264, 42, 12, "RND1"); + o->tooltip("Randomize the resonance function"); + o->box(FL_THIN_UP_BOX); + o->labelfont(1); + o->labelsize(10); + o->callback((Fl_Callback*)cb_RND1); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(566, 288, 42, 12, "RND3"); + o->tooltip("Randomize the resonance function"); + o->box(FL_THIN_UP_BOX); + o->labelfont(1); + o->labelsize(10); + o->callback((Fl_Callback*)cb_RND3); + } // Fl_Button* o + { Fl_Check_Button* o = p1st = new Fl_Check_Button(365, 285, 45, 15, "P.1st"); + p1st->tooltip("Protect the fundamental frequency (do not damp the first harmonic)"); + p1st->down_box(FL_DOWN_BOX); + p1st->labelsize(10); + p1st->callback((Fl_Callback*)cb_p1st); + o->value(respar->Pprotectthefundamental); + } // Fl_Check_Button* p1st + { Fl_Button* o = new Fl_Button(365, 265, 46, 15, "InterpP"); + o->tooltip("Interpolate the peaks"); + o->box(FL_THIN_UP_BOX); + o->labelfont(1); + o->labelsize(10); + o->callback((Fl_Callback*)cb_InterpP); + } // Fl_Button* o + { WidgetPDial* o = centerfreq = new WidgetPDial(245, 265, 30, 30, "C.f."); + centerfreq->box(FL_ROUND_UP_BOX); + centerfreq->color(FL_BACKGROUND_COLOR); + centerfreq->selection_color(FL_INACTIVE_COLOR); + centerfreq->labeltype(FL_NORMAL_LABEL); + centerfreq->labelfont(0); + centerfreq->labelsize(10); + centerfreq->labelcolor(FL_FOREGROUND_COLOR); + centerfreq->maximum(127); + centerfreq->step(1); + centerfreq->callback((Fl_Callback*)cb_centerfreq); + centerfreq->align(FL_ALIGN_BOTTOM); + centerfreq->when(FL_WHEN_CHANGED); + o->value(respar->Pcenterfreq); + } // WidgetPDial* centerfreq + { WidgetPDial* o = octavesfreq = new WidgetPDial(280, 265, 30, 30, "Oct."); + octavesfreq->box(FL_ROUND_UP_BOX); + octavesfreq->color(FL_BACKGROUND_COLOR); + octavesfreq->selection_color(FL_INACTIVE_COLOR); + octavesfreq->labeltype(FL_NORMAL_LABEL); + octavesfreq->labelfont(0); + octavesfreq->labelsize(10); + octavesfreq->labelcolor(FL_FOREGROUND_COLOR); + octavesfreq->maximum(127); + octavesfreq->step(1); + octavesfreq->callback((Fl_Callback*)cb_octavesfreq); + octavesfreq->align(FL_ALIGN_BOTTOM); + octavesfreq->when(FL_WHEN_CHANGED); + o->value(respar->Poctavesfreq); + } // WidgetPDial* octavesfreq + { Fl_Button* o = new Fl_Button(625, 275, 25, 15, "C"); + o->box(FL_THIN_UP_BOX); + o->color((Fl_Color)179); + o->labelfont(1); + o->labelsize(11); + o->labelcolor(FL_BACKGROUND2_COLOR); + o->callback((Fl_Callback*)cb_C); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(655, 275, 25, 15, "P"); + o->box(FL_THIN_UP_BOX); + o->color((Fl_Color)179); + o->labelfont(1); + o->labelsize(11); + o->labelcolor(FL_BACKGROUND2_COLOR); + o->callback((Fl_Callback*)cb_P); + } // Fl_Button* o + { applybutton = new Fl_Button(690, 265, 85, 15, "Apply"); + applybutton->box(FL_THIN_UP_BOX); + applybutton->labelfont(1); + applybutton->labelsize(11); + applybutton->callback((Fl_Callback*)cb_applybutton); + } // Fl_Button* applybutton + resonancewindow->end(); + } // Fl_Double_Window* resonancewindow + return resonancewindow; +} + +ResonanceUI::ResonanceUI(Resonance *respar_) { + respar=respar_; +cbwidget=NULL; +cbapplywidget=NULL; +make_window(); +applybutton->hide(); +} + +ResonanceUI::~ResonanceUI() { + resonancewindow->hide(); +} + +void ResonanceUI::redrawPADnoteApply() { + if (cbwidget!=NULL) { + cbwidget->do_callback(); + applybutton->color(FL_RED); + applybutton->redraw(); +}; +} + +void ResonanceUI::setcbwidget(Fl_Widget *cbwidget,Fl_Widget *cbapplywidget) { + this->cbwidget=cbwidget; +this->cbapplywidget=cbapplywidget; +rg->setcbwidget(cbwidget,applybutton); +applybutton->show(); +} + +void ResonanceUI::refresh() { + redrawPADnoteApply(); + +enabled->value(respar->Penabled); + +maxdb->value(respar->PmaxdB); +maxdbvo->value(respar->PmaxdB); + +centerfreqvo->value(respar->getcenterfreq()/1000.0); +octavesfreqvo->value(respar->getoctavesfreq()); + +centerfreq->value(respar->Pcenterfreq); +octavesfreq->value(respar->Poctavesfreq); + +p1st->value(respar->Pprotectthefundamental); + +rg->redraw(); +} diff --git a/plugins/zynaddsubfx/src/UI/ResonanceUI.fl b/plugins/zynaddsubfx/src/UI/ResonanceUI.fl new file mode 100644 index 000000000..3c06c5215 --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/ResonanceUI.fl @@ -0,0 +1,392 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0107 +header_name {.h} +code_name {.cc} +decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} + +decl {//License: GNU GPL version 2 or later} {} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include } {} + +decl {\#include } {} + +decl {\#include } {} + +decl {\#include } {} + +decl {\#include "../Synth/Resonance.h"} {public +} + +decl {\#include "WidgetPDial.h"} {public +} + +decl {\#include "PresetsUI.h"} {public +} + +class ResonanceGraph {: {public Fl_Box} +} { + Function {ResonanceGraph(int x,int y, int w, int h, const char *label=0):Fl_Box(x,y,w,h,label)} {} { + code {respar=NULL; +cbwidget=NULL; +applybutton=NULL;} {} + } + Function {init(Resonance *respar_,Fl_Value_Output *khzvalue_,Fl_Value_Output *dbvalue_)} {} { + code {respar=respar_; +khzvalue=khzvalue_; +dbvalue=dbvalue_; +oldx=-1; +khzval=-1;} {} + } + Function {draw_freq_line(REALTYPE freq,int type)} {} { + code {REALTYPE freqx=respar->getfreqpos(freq); +switch(type){ + case 0:fl_line_style(FL_SOLID);break; + case 1:fl_line_style(FL_DOT);break; + case 2:fl_line_style(FL_DASH);break; +}; + + +if ((freqx>0.0)&&(freqx<1.0)) + fl_line(x()+(int) (freqx*w()),y(), + x()+(int) (freqx*w()),y()+h());} {} + } + Function {draw()} {} { + code {int ox=x(),oy=y(),lx=w(),ly=h(),i,ix,iy,oiy; +REALTYPE freqx; + +fl_color(FL_BLACK); +fl_rectf(ox,oy,lx,ly); + + +//draw the lines +fl_color(FL_GRAY); + +fl_line_style(FL_SOLID); +fl_line(ox+2,oy+ly/2,ox+lx-2,oy+ly/2); + +freqx=respar->getfreqpos(1000.0); +if ((freqx>0.0)&&(freqx<1.0)) + fl_line(ox+(int) (freqx*lx),oy, + ox+(int) (freqx*lx),oy+ly); + +for (i=1;i<10;i++){ + if(i==1){ + draw_freq_line(i*100.0,0); + draw_freq_line(i*1000.0,0); + }else + if (i==5){ + draw_freq_line(i*100.0,2); + draw_freq_line(i*1000.0,2); + }else{ + draw_freq_line(i*100.0,1); + draw_freq_line(i*1000.0,1); + }; +}; + +draw_freq_line(10000.0,0); +draw_freq_line(20000.0,1); + +fl_line_style(FL_DOT); +int GY=10;if (lyPrespoints[0]/128.0*ly); +for (i=1;iPrespoints[i]/128.0*ly); + fl_line(ox+ix-1,oy+ly-oiy,ox+ix,oy+ly-iy); + oiy=iy; +};} {} + } + Function {handle(int event)} {return_type int + } { + code {int x_=Fl::event_x()-x(); +int y_=Fl::event_y()-y(); +if ( (x_>=0)&&(x_=0)&&(y_value(respar->getfreqx(x_*1.0/w())/1000.0); + dbvalue->value((1.0-y_*2.0/h())*respar->PmaxdB); +}; + +if ((event==FL_PUSH)||(event==FL_DRAG)){ + int leftbutton=1; + if (Fl::event_button()==FL_RIGHT_MOUSE) leftbutton=0; + if (x_<0) x_=0;if (y_<0) y_=0; + if (x_>=w()) x_=w();if (y_>=h()-1) y_=h()-1; + + if ((oldx<0)||(oldx==x_)){ + int sn=(int)(x_*1.0/w()*N_RES_POINTS); + int sp=127-(int)(y_*1.0/h()*127); + if (leftbutton!=0) respar->setpoint(sn,sp); + else respar->setpoint(sn,64); + } else { + int x1=oldx; + int x2=x_; + int y1=oldy; + int y2=y_; + if (oldx>x_){ + x1=x_;y1=y_; + x2=oldx;y2=oldy; + }; + for (int i=0;isetpoint(sn,sp); + else respar->setpoint(sn,64); + }; + }; + + oldx=x_;oldy=y_; + redraw(); +}; + +if (event==FL_RELEASE) { + oldx=-1; + if (cbwidget!=NULL) { + cbwidget->do_callback(); + if (applybutton!=NULL) { + applybutton->color(FL_RED); + applybutton->redraw(); + + }; + }; +}; + +return(1);} {} + } + Function {setcbwidget(Fl_Widget *cbwidget,Fl_Widget *applybutton)} {} { + code {this->cbwidget=cbwidget; +this->applybutton=applybutton;} {} + } + decl {Fl_Value_Output *khzvalue;} {} + decl {Fl_Value_Output *dbvalue;} {} + decl {Resonance *respar;} {} + decl {int oldx,oldy;} {} + decl {REALTYPE khzval;} {public + } + decl {Fl_Widget *cbwidget,*applybutton;} {} +} + +class ResonanceUI {open : PresetsUI_ +} { + Function {make_window()} {open + } { + Fl_Window resonancewindow { + label Resonance selected + xywh {120 70 780 305} type Double hide + } { + Fl_Value_Output khzvalue { + label kHz + xywh {415 264 45 18} labelsize 12 align 8 minimum 0.001 maximum 48 step 0.01 textfont 1 textsize 12 + code0 {//this widget must be before the calling widgets} + } + Fl_Value_Output dbvalue { + label dB + xywh {415 282 45 18} labelsize 12 align 8 minimum -150 maximum 150 step 0.1 textfont 1 textsize 12 + code0 {//this widget must be before the calling widgets} + } + Fl_Group {} { + xywh {6 5 768 256} box BORDER_BOX + code0 {rg=new ResonanceGraph(o->x(),o->y(),o->w(),o->h(),"");} + code1 {rg->init(respar,khzvalue,dbvalue);} + code2 {rg->show();} + } {} + Fl_Button {} { + label Close + callback {resonancewindow->hide();} + xywh {690 283 84 17} box THIN_UP_BOX + } + Fl_Button {} { + label Zero + callback {for (int i=0;isetpoint(i,64); +resonancewindow->redraw(); +redrawPADnoteApply();} + tooltip {Clear the resonance function} xywh {491 264 66 15} box THIN_UP_BOX labelfont 1 labelsize 12 + } + Fl_Button {} { + label Smooth + callback {respar->smooth(); +resonancewindow->redraw(); +redrawPADnoteApply();} + tooltip {Smooth the resonance function} xywh {491 282 66 18} box THIN_UP_BOX labelfont 1 labelsize 12 + } + Fl_Check_Button enabled { + label Enable + callback {respar->Penabled=(int) o->value(); +redrawPADnoteApply();} + xywh {6 270 78 27} box THIN_UP_BOX down_box DOWN_BOX + code0 {o->value(respar->Penabled);} + } + Fl_Roller maxdb { + callback {maxdbvo->value(o->value()); +respar->PmaxdB=(int) o->value(); +redrawPADnoteApply();} + xywh {90 282 84 15} type Horizontal minimum 1 maximum 90 step 1 value 30 + } + Fl_Value_Output maxdbvo { + label {Max.} + callback {o->value(respar->PmaxdB);} + tooltip {The Maximum amplitude (dB)} xywh {126 264 24 18} labelsize 12 minimum 1 maximum 127 step 1 value 30 textfont 1 textsize 12 + code0 {o->value(respar->PmaxdB);} + } + Fl_Box {} { + label dB + xywh {150 264 24 18} + } + Fl_Value_Output centerfreqvo { + label {C.f.} + callback {o->value(respar->getcenterfreq()/1000.0);} + tooltip {Center Frequency (kHz)} xywh {210 264 33 18} labelsize 12 when 3 minimum 1 maximum 10 step 0.01 value 1 textfont 1 textsize 12 + code0 {o->value(respar->getcenterfreq()/1000.0);} + } + Fl_Value_Output octavesfreqvo { + label {Oct.} + callback {o->value(respar->getoctavesfreq());} + tooltip {No. of octaves} xywh {210 282 33 18} labelsize 12 when 3 minimum 1 maximum 127 step 1 value 30 textfont 1 textsize 12 + code0 {o->value(respar->getoctavesfreq());} + } + Fl_Button {} { + label RND2 + callback {respar->randomize(1); +resonancewindow->redraw(); +redrawPADnoteApply();} + tooltip {Randomize the resonance function} xywh {566 276 42 12} box THIN_UP_BOX labelfont 1 labelsize 10 + } + Fl_Button {} { + label RND1 + callback {respar->randomize(0); +resonancewindow->redraw(); +redrawPADnoteApply();} + tooltip {Randomize the resonance function} xywh {566 264 42 12} box THIN_UP_BOX labelfont 1 labelsize 10 + } + Fl_Button {} { + label RND3 + callback {respar->randomize(2); +resonancewindow->redraw(); +redrawPADnoteApply();} + tooltip {Randomize the resonance function} xywh {566 288 42 12} box THIN_UP_BOX labelfont 1 labelsize 10 + } + Fl_Check_Button p1st { + label {P.1st} + callback {respar->Pprotectthefundamental=(int) o->value(); +redrawPADnoteApply();} + tooltip {Protect the fundamental frequency (do not damp the first harmonic)} xywh {365 285 45 15} down_box DOWN_BOX labelsize 10 + code0 {o->value(respar->Pprotectthefundamental);} + } + Fl_Button {} { + label InterpP + callback {int type; +if (Fl::event_button()==FL_LEFT_MOUSE) type=0; + else type=1; +respar->interpolatepeaks(type); +resonancewindow->redraw(); +redrawPADnoteApply();} + tooltip {Interpolate the peaks} xywh {365 265 46 15} box THIN_UP_BOX labelfont 1 labelsize 10 + } + Fl_Dial centerfreq { + label {C.f.} + callback {respar->Pcenterfreq=(int)o->value(); +centerfreqvo->do_callback(); +rg->redraw(); +redrawPADnoteApply();} + xywh {245 265 30 30} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + code0 {o->value(respar->Pcenterfreq);} + class WidgetPDial + } + Fl_Dial octavesfreq { + label {Oct.} + callback {respar->Poctavesfreq=(int)o->value(); +octavesfreqvo->do_callback(); +rg->redraw(); +redrawPADnoteApply();} + xywh {280 265 30 30} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + code0 {o->value(respar->Poctavesfreq);} + class WidgetPDial + } + Fl_Button {} { + label C + callback {presetsui->copy(respar);} + xywh {625 275 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 11 labelcolor 7 + } + Fl_Button {} { + label P + callback {presetsui->paste(respar,this);} + xywh {655 275 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 11 labelcolor 7 + } + Fl_Button applybutton { + label Apply + callback {applybutton->color(FL_GRAY); +applybutton->redraw(); +if (cbapplywidget!=NULL) { + cbapplywidget->do_callback(); + cbapplywidget->color(FL_GRAY); + cbapplywidget->redraw(); +};} + xywh {690 265 85 15} box THIN_UP_BOX labelfont 1 labelsize 11 + } + } + } + Function {ResonanceUI(Resonance *respar_)} {} { + code {respar=respar_; +cbwidget=NULL; +cbapplywidget=NULL; +make_window(); +applybutton->hide();} {} + } + Function {~ResonanceUI()} {} { + code {resonancewindow->hide();} {} + } + Function {redrawPADnoteApply()} {} { + code {if (cbwidget!=NULL) { + cbwidget->do_callback(); + applybutton->color(FL_RED); + applybutton->redraw(); +};} {} + } + Function {setcbwidget(Fl_Widget *cbwidget,Fl_Widget *cbapplywidget)} {} { + code {this->cbwidget=cbwidget; +this->cbapplywidget=cbapplywidget; +rg->setcbwidget(cbwidget,applybutton); +applybutton->show();} {} + } + Function {refresh()} {} { + code {redrawPADnoteApply(); + +enabled->value(respar->Penabled); + +maxdb->value(respar->PmaxdB); +maxdbvo->value(respar->PmaxdB); + +centerfreqvo->value(respar->getcenterfreq()/1000.0); +octavesfreqvo->value(respar->getoctavesfreq()); + +centerfreq->value(respar->Pcenterfreq); +octavesfreq->value(respar->Poctavesfreq); + +p1st->value(respar->Pprotectthefundamental); + +rg->redraw();} {} + } + decl {Resonance *respar;} {public + } + decl {ResonanceGraph *rg;} {} + decl {Fl_Widget *cbwidget,*cbapplywidget;} {} +} diff --git a/plugins/zynaddsubfx/src/UI/ResonanceUI.h b/plugins/zynaddsubfx/src/UI/ResonanceUI.h new file mode 100644 index 000000000..e7c43e4db --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/ResonanceUI.h @@ -0,0 +1,120 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0109 + +#ifndef ResonanceUI_h +#define ResonanceUI_h +#include +#include +#include +#include +#include "../Synth/Resonance.h" +#include "WidgetPDial.h" +#include "PresetsUI.h" + +class ResonanceGraph : public Fl_Box { +public: + ResonanceGraph(int x,int y, int w, int h, const char *label=0); + void init(Resonance *respar_,Fl_Value_Output *khzvalue_,Fl_Value_Output *dbvalue_); + void draw_freq_line(REALTYPE freq,int type); + void draw(); + int handle(int event); + void setcbwidget(Fl_Widget *cbwidget,Fl_Widget *applybutton); +private: + Fl_Value_Output *khzvalue; + Fl_Value_Output *dbvalue; + Resonance *respar; + int oldx,oldy; +public: + REALTYPE khzval; +private: + Fl_Widget *cbwidget,*applybutton; +}; +#include +#include +#include +#include +#include +#include +#include + +class ResonanceUI : PresetsUI_ { +public: + Fl_Double_Window* make_window(); + Fl_Double_Window *resonancewindow; + Fl_Value_Output *khzvalue; + Fl_Value_Output *dbvalue; +private: + void cb_Close_i(Fl_Button*, void*); + static void cb_Close(Fl_Button*, void*); + void cb_Zero_i(Fl_Button*, void*); + static void cb_Zero(Fl_Button*, void*); + void cb_Smooth_i(Fl_Button*, void*); + static void cb_Smooth(Fl_Button*, void*); +public: + Fl_Check_Button *enabled; +private: + void cb_enabled_i(Fl_Check_Button*, void*); + static void cb_enabled(Fl_Check_Button*, void*); +public: + Fl_Roller *maxdb; +private: + void cb_maxdb_i(Fl_Roller*, void*); + static void cb_maxdb(Fl_Roller*, void*); +public: + Fl_Value_Output *maxdbvo; +private: + void cb_maxdbvo_i(Fl_Value_Output*, void*); + static void cb_maxdbvo(Fl_Value_Output*, void*); +public: + Fl_Value_Output *centerfreqvo; +private: + void cb_centerfreqvo_i(Fl_Value_Output*, void*); + static void cb_centerfreqvo(Fl_Value_Output*, void*); +public: + Fl_Value_Output *octavesfreqvo; +private: + void cb_octavesfreqvo_i(Fl_Value_Output*, void*); + static void cb_octavesfreqvo(Fl_Value_Output*, void*); + void cb_RND2_i(Fl_Button*, void*); + static void cb_RND2(Fl_Button*, void*); + void cb_RND1_i(Fl_Button*, void*); + static void cb_RND1(Fl_Button*, void*); + void cb_RND3_i(Fl_Button*, void*); + static void cb_RND3(Fl_Button*, void*); +public: + Fl_Check_Button *p1st; +private: + void cb_p1st_i(Fl_Check_Button*, void*); + static void cb_p1st(Fl_Check_Button*, void*); + void cb_InterpP_i(Fl_Button*, void*); + static void cb_InterpP(Fl_Button*, void*); +public: + WidgetPDial *centerfreq; +private: + void cb_centerfreq_i(WidgetPDial*, void*); + static void cb_centerfreq(WidgetPDial*, void*); +public: + WidgetPDial *octavesfreq; +private: + void cb_octavesfreq_i(WidgetPDial*, void*); + static void cb_octavesfreq(WidgetPDial*, void*); + void cb_C_i(Fl_Button*, void*); + static void cb_C(Fl_Button*, void*); + void cb_P_i(Fl_Button*, void*); + static void cb_P(Fl_Button*, void*); +public: + Fl_Button *applybutton; +private: + void cb_applybutton_i(Fl_Button*, void*); + static void cb_applybutton(Fl_Button*, void*); +public: + ResonanceUI(Resonance *respar_); + ~ResonanceUI(); + void redrawPADnoteApply(); + void setcbwidget(Fl_Widget *cbwidget,Fl_Widget *cbapplywidget); + void refresh(); + Resonance *respar; +private: + ResonanceGraph *rg; + Fl_Widget *cbwidget,*cbapplywidget; +}; +#endif diff --git a/plugins/zynaddsubfx/src/UI/SUBnoteUI.cc b/plugins/zynaddsubfx/src/UI/SUBnoteUI.cc new file mode 100644 index 000000000..6205167fe --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/SUBnoteUI.cc @@ -0,0 +1,735 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0109 + +#include "SUBnoteUI.h" +//Copyright (c) 2002-2005 Nasca Octavian Paul +//License: GNU GPL version 2 or later + +void SUBnoteharmonic::cb_mag_i(Fl_Slider* o, void*) { + int x=0; +if (Fl::event_button1()) x=127-(int)o->value(); + else o->value(127-x); +pars->Phmag[n]=x; +if (pars->Phmag[n]==0) o->selection_color(0); + else o->selection_color(222); +} +void SUBnoteharmonic::cb_mag(Fl_Slider* o, void* v) { + ((SUBnoteharmonic*)(o->parent()->user_data()))->cb_mag_i(o,v); +} + +void SUBnoteharmonic::cb_bw_i(Fl_Slider* o, void*) { + int x=64; +if (Fl::event_button1()) x=127-(int)o->value(); + else o->value(x); +pars->Phrelbw[n]=x; +} +void SUBnoteharmonic::cb_bw(Fl_Slider* o, void* v) { + ((SUBnoteharmonic*)(o->parent()->user_data()))->cb_bw_i(o,v); +} + +Fl_Group* SUBnoteharmonic::make_window() { + { harmonic = new Fl_Group(0, 0, 90, 225); + harmonic->box(FL_FLAT_BOX); + harmonic->color(FL_BACKGROUND_COLOR); + harmonic->selection_color(FL_BACKGROUND_COLOR); + harmonic->labeltype(FL_NO_LABEL); + harmonic->labelfont(0); + harmonic->labelsize(14); + harmonic->labelcolor(FL_FOREGROUND_COLOR); + harmonic->user_data((void*)(this)); + harmonic->align(FL_ALIGN_TOP); + harmonic->when(FL_WHEN_RELEASE); + { Fl_Slider* o = mag = new Fl_Slider(0, 15, 10, 115); + mag->tooltip("harmonic\'s magnitude"); + mag->type(4); + mag->box(FL_FLAT_BOX); + mag->selection_color((Fl_Color)222); + mag->maximum(127); + mag->step(1); + mag->value(127); + mag->callback((Fl_Callback*)cb_mag); + o->value(127-pars->Phmag[n]); + if (pars->Phmag[n]==0) o->selection_color(0); + } // Fl_Slider* mag + { Fl_Slider* o = bw = new Fl_Slider(0, 135, 10, 75); + bw->tooltip("harmonic\'s bandwidth"); + bw->type(4); + bw->box(FL_FLAT_BOX); + bw->selection_color((Fl_Color)222); + bw->maximum(127); + bw->step(1); + bw->value(64); + bw->callback((Fl_Callback*)cb_bw); + o->value(127-pars->Phrelbw[n]); + } // Fl_Slider* bw + { Fl_Box* o = new Fl_Box(10, 170, 5, 5); + o->box(FL_FLAT_BOX); + o->color(FL_DARK2); + if (n+1==MAX_SUB_HARMONICS) o->hide(); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(0, 210, 10, 15, "01"); + o->labelfont(1); + o->labelsize(9); + o->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE); + char tmp[10];snprintf(tmp,10,"%d",n+1);o->label(strdup(tmp)); + } // Fl_Box* o + { Fl_Box* o = new Fl_Box(0, 0, 10, 15, "01"); + o->labelfont(1); + o->labelsize(9); + o->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE); + char tmp[10];snprintf(tmp,10,"%d",n+1);o->label(strdup(tmp)); + } // Fl_Box* o + harmonic->end(); + } // Fl_Group* harmonic + return harmonic; +} + +SUBnoteharmonic::SUBnoteharmonic(int x,int y, int w, int h, const char *label):Fl_Group(x,y,w,h,label) { + n=0; +} + +void SUBnoteharmonic::init(SUBnoteParameters *pars_,int n_) { + pars=pars_; +n=n_; +make_window(); +harmonic->show(); +end(); +} + +void SUBnoteharmonic::refresh() { + mag->value(127-pars->Phmag[n]); +if (pars->Phmag[n]==0) mag->selection_color(0); +bw->value(127-pars->Phrelbw[n]); +} + +SUBnoteharmonic::~SUBnoteharmonic() { + harmonic->hide(); +hide(); +//delete(harmonic); +} + +void SUBnoteUI::cb_Close_i(Fl_Button*, void*) { + SUBparameters->hide(); +} +void SUBnoteUI::cb_Close(Fl_Button* o, void* v) { + ((SUBnoteUI*)(o->parent()->user_data()))->cb_Close_i(o,v); +} + +void SUBnoteUI::cb_vol_i(Fl_Value_Slider* o, void*) { + pars->PVolume=(int)o->value(); +} +void SUBnoteUI::cb_vol(Fl_Value_Slider* o, void* v) { + ((SUBnoteUI*)(o->parent()->parent()->user_data()))->cb_vol_i(o,v); +} + +void SUBnoteUI::cb_vsns_i(Fl_Value_Slider* o, void*) { + pars->PAmpVelocityScaleFunction=(int) o->value(); +} +void SUBnoteUI::cb_vsns(Fl_Value_Slider* o, void* v) { + ((SUBnoteUI*)(o->parent()->parent()->user_data()))->cb_vsns_i(o,v); +} + +void SUBnoteUI::cb_pan_i(WidgetPDial* o, void*) { + pars->PPanning=(int) o->value(); +} +void SUBnoteUI::cb_pan(WidgetPDial* o, void* v) { + ((SUBnoteUI*)(o->parent()->parent()->user_data()))->cb_pan_i(o,v); +} + +void SUBnoteUI::cb_filterstages_i(Fl_Counter* o, void*) { + pars->Pnumstages=(int) o->value(); +} +void SUBnoteUI::cb_filterstages(Fl_Counter* o, void* v) { + ((SUBnoteUI*)(o->parent()->parent()->user_data()))->cb_filterstages_i(o,v); +} + +void SUBnoteUI::cb_magtype_i(Fl_Choice* o, void*) { + pars->Phmagtype=(int) o->value(); +} +void SUBnoteUI::cb_magtype(Fl_Choice* o, void* v) { + ((SUBnoteUI*)(o->parent()->parent()->user_data()))->cb_magtype_i(o,v); +} + +Fl_Menu_Item SUBnoteUI::menu_magtype[] = { + {"Linear", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"-40dB", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"-60dB", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"-80dB", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"-100dB", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void SUBnoteUI::cb_start_i(Fl_Choice* o, void*) { + pars->Pstart=(int) o->value(); +} +void SUBnoteUI::cb_start(Fl_Choice* o, void* v) { + ((SUBnoteUI*)(o->parent()->parent()->user_data()))->cb_start_i(o,v); +} + +Fl_Menu_Item SUBnoteUI::menu_start[] = { + {"Zero", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"RND", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {"Max.", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 11, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void SUBnoteUI::cb_freqee_i(Fl_Check_Button* o, void*) { + pars->PFreqEnvelopeEnabled=o->value(); +if (o->value()==0) freqenvelopegroup->deactivate(); + else freqenvelopegroup->activate(); +o->show(); +freqsettingsui->redraw(); +} +void SUBnoteUI::cb_freqee(Fl_Check_Button* o, void* v) { + ((SUBnoteUI*)(o->parent()->parent()->user_data()))->cb_freqee_i(o,v); +} + +void SUBnoteUI::cb_octave_i(Fl_Counter* o, void*) { + int k=(int) o->value(); +if (k<0) k+=16; +pars->PCoarseDetune = k*1024+ + pars->PCoarseDetune%1024; +} +void SUBnoteUI::cb_octave(Fl_Counter* o, void* v) { + ((SUBnoteUI*)(o->parent()->parent()->user_data()))->cb_octave_i(o,v); +} + +void SUBnoteUI::cb_coarsedet_i(Fl_Counter* o, void*) { + int k=(int) o->value(); +if (k<0) k+=1024; +pars->PCoarseDetune = k+ + (pars->PCoarseDetune/1024)*1024; +} +void SUBnoteUI::cb_coarsedet(Fl_Counter* o, void* v) { + ((SUBnoteUI*)(o->parent()->parent()->user_data()))->cb_coarsedet_i(o,v); +} + +void SUBnoteUI::cb_detune_i(Fl_Slider* o, void*) { + pars->PDetune=(int)o->value()+8192; +detunevalueoutput->do_callback(); +} +void SUBnoteUI::cb_detune(Fl_Slider* o, void* v) { + ((SUBnoteUI*)(o->parent()->parent()->user_data()))->cb_detune_i(o,v); +} + +void SUBnoteUI::cb_detunevalueoutput_i(Fl_Value_Output* o, void*) { + o->value(getdetune(pars->PDetuneType,0,pars->PDetune)); +} +void SUBnoteUI::cb_detunevalueoutput(Fl_Value_Output* o, void* v) { + ((SUBnoteUI*)(o->parent()->parent()->user_data()))->cb_detunevalueoutput_i(o,v); +} + +void SUBnoteUI::cb_hz440_i(Fl_Check_Button* o, void*) { + int x=(int) o->value(); +pars->Pfixedfreq=x; +if (x==0) fixedfreqetdial->deactivate(); + else fixedfreqetdial->activate(); +} +void SUBnoteUI::cb_hz440(Fl_Check_Button* o, void* v) { + ((SUBnoteUI*)(o->parent()->parent()->user_data()))->cb_hz440_i(o,v); +} + +void SUBnoteUI::cb_fixedfreqetdial_i(WidgetPDial* o, void*) { + pars->PfixedfreqET=(int) o->value(); +} +void SUBnoteUI::cb_fixedfreqetdial(WidgetPDial* o, void* v) { + ((SUBnoteUI*)(o->parent()->parent()->user_data()))->cb_fixedfreqetdial_i(o,v); +} + +void SUBnoteUI::cb_detunetype_i(Fl_Choice* o, void*) { + pars->PDetuneType=(int) o->value()+1; +detunevalueoutput->do_callback(); +} +void SUBnoteUI::cb_detunetype(Fl_Choice* o, void* v) { + ((SUBnoteUI*)(o->parent()->parent()->user_data()))->cb_detunetype_i(o,v); +} + +void SUBnoteUI::cb_stereo_i(Fl_Check_Button* o, void*) { + pars->Pstereo=(int) o->value(); +} +void SUBnoteUI::cb_stereo(Fl_Check_Button* o, void* v) { + ((SUBnoteUI*)(o->parent()->user_data()))->cb_stereo_i(o,v); +} + +void SUBnoteUI::cb_Clear_i(Fl_Button*, void*) { + for (int i=0;imag->value(127); + pars->Phmag[i]=0; + h[i]->bw->value(64); + pars->Phrelbw[i]=64; +}; +pars->Phmag[0]=127; +h[0]->mag->value(0); +SUBparameters->redraw(); +} +void SUBnoteUI::cb_Clear(Fl_Button* o, void* v) { + ((SUBnoteUI*)(o->parent()->user_data()))->cb_Clear_i(o,v); +} + +void SUBnoteUI::cb_bwee_i(Fl_Check_Button* o, void*) { + pars->PBandWidthEnvelopeEnabled=o->value(); +if (o->value()==0) bandwidthenvelopegroup->deactivate(); + else bandwidthenvelopegroup->activate(); +o->show(); +bandwidthsettingsui->redraw(); +} +void SUBnoteUI::cb_bwee(Fl_Check_Button* o, void* v) { + ((SUBnoteUI*)(o->parent()->parent()->user_data()))->cb_bwee_i(o,v); +} + +void SUBnoteUI::cb_bandwidth_i(Fl_Value_Slider* o, void*) { + pars->Pbandwidth=(int) o->value(); +} +void SUBnoteUI::cb_bandwidth(Fl_Value_Slider* o, void* v) { + ((SUBnoteUI*)(o->parent()->parent()->user_data()))->cb_bandwidth_i(o,v); +} + +void SUBnoteUI::cb_bwidthscale_i(Fl_Value_Slider* o, void*) { + pars->Pbwscale=(int) o->value()+64; +} +void SUBnoteUI::cb_bwidthscale(Fl_Value_Slider* o, void* v) { + ((SUBnoteUI*)(o->parent()->parent()->user_data()))->cb_bwidthscale_i(o,v); +} + +void SUBnoteUI::cb_filtere_i(Fl_Check_Button* o, void*) { + pars->PGlobalFilterEnabled=o->value(); +if (o->value()==0) globalfiltergroup->deactivate(); + else globalfiltergroup->activate(); +o->show(); +globalfiltergroup->redraw(); +} +void SUBnoteUI::cb_filtere(Fl_Check_Button* o, void* v) { + ((SUBnoteUI*)(o->parent()->user_data()))->cb_filtere_i(o,v); +} + +void SUBnoteUI::cb_C_i(Fl_Button*, void*) { + presetsui->copy(pars); +} +void SUBnoteUI::cb_C(Fl_Button* o, void* v) { + ((SUBnoteUI*)(o->parent()->user_data()))->cb_C_i(o,v); +} + +void SUBnoteUI::cb_P_i(Fl_Button*, void*) { + presetsui->paste(pars,this); +} +void SUBnoteUI::cb_P(Fl_Button* o, void* v) { + ((SUBnoteUI*)(o->parent()->user_data()))->cb_P_i(o,v); +} + +Fl_Double_Window* SUBnoteUI::make_window() { + { SUBparameters = new Fl_Double_Window(735, 390, "SUBsynth Parameters"); + SUBparameters->user_data((void*)(this)); + { Fl_Scroll* o = new Fl_Scroll(5, 140, 435, 245); + o->type(1); + o->box(FL_THIN_UP_BOX); + { Fl_Pack* o = harmonics = new Fl_Pack(10, 145, 425, 235); + harmonics->type(1); + for (int i=0;ih(),"");h[i]->init(pars,i);} + harmonics->end(); + } // Fl_Pack* harmonics + o->end(); + } // Fl_Scroll* o + { Fl_Button* o = new Fl_Button(625, 365, 105, 20, "Close"); + o->box(FL_THIN_UP_BOX); + o->labelfont(1); + o->labelsize(11); + o->callback((Fl_Callback*)cb_Close); + } // Fl_Button* o + { Fl_Group* o = new Fl_Group(5, 5, 215, 135, "AMPLITUDE"); + o->box(FL_THIN_UP_FRAME); + o->labeltype(FL_EMBOSSED_LABEL); + o->labelfont(1); + o->align(FL_ALIGN_TOP|FL_ALIGN_INSIDE); + { Fl_Value_Slider* o = vol = new Fl_Value_Slider(10, 25, 140, 15, "Vol"); + vol->tooltip("Volume"); + vol->type(5); + vol->box(FL_FLAT_BOX); + vol->labelsize(11); + vol->maximum(127); + vol->step(1); + vol->callback((Fl_Callback*)cb_vol); + vol->align(FL_ALIGN_RIGHT); + o->value(pars->PVolume); + } // Fl_Value_Slider* vol + { Fl_Value_Slider* o = vsns = new Fl_Value_Slider(10, 45, 140, 15, "V.Sns"); + vsns->tooltip("Velocity Sensing Function (rightmost to disable)"); + vsns->type(5); + vsns->box(FL_FLAT_BOX); + vsns->labelsize(11); + vsns->maximum(127); + vsns->step(1); + vsns->callback((Fl_Callback*)cb_vsns); + vsns->align(FL_ALIGN_RIGHT); + o->value(pars->PAmpVelocityScaleFunction); + } // Fl_Value_Slider* vsns + { WidgetPDial* o = pan = new WidgetPDial(185, 20, 30, 30, "Pan"); + pan->tooltip("Panning (leftmost is Random)"); + pan->box(FL_ROUND_UP_BOX); + pan->color(FL_BACKGROUND_COLOR); + pan->selection_color(FL_INACTIVE_COLOR); + pan->labeltype(FL_NORMAL_LABEL); + pan->labelfont(0); + pan->labelsize(10); + pan->labelcolor(FL_FOREGROUND_COLOR); + pan->maximum(127); + pan->step(1); + pan->callback((Fl_Callback*)cb_pan); + pan->align(FL_ALIGN_BOTTOM); + pan->when(FL_WHEN_CHANGED); + o->value(pars->PPanning); + } // WidgetPDial* pan + { EnvelopeUI* o = ampenv = new EnvelopeUI(10, 65, 205, 70, "SUBsynth - Amplitude Envelope"); + ampenv->box(FL_FLAT_BOX); + ampenv->color((Fl_Color)51); + ampenv->selection_color(FL_BACKGROUND_COLOR); + ampenv->labeltype(FL_NORMAL_LABEL); + ampenv->labelfont(0); + ampenv->labelsize(14); + ampenv->labelcolor(FL_FOREGROUND_COLOR); + ampenv->align(FL_ALIGN_WRAP|FL_ALIGN_INSIDE); + ampenv->when(FL_WHEN_RELEASE); + o->init(pars->AmpEnvelope); + ampenv->end(); + } // EnvelopeUI* ampenv + o->end(); + } // Fl_Group* o + { Fl_Group* o = new Fl_Group(495, 325, 235, 35); + o->box(FL_THIN_UP_FRAME); + { Fl_Counter* o = filterstages = new Fl_Counter(515, 340, 45, 15, "Filter Stages"); + filterstages->tooltip("How many times the noise is filtered"); + filterstages->type(1); + filterstages->labelfont(1); + filterstages->labelsize(10); + filterstages->minimum(1); + filterstages->maximum(5); + filterstages->step(1); + filterstages->textsize(10); + filterstages->callback((Fl_Callback*)cb_filterstages); + filterstages->align(FL_ALIGN_TOP); + o->value(pars->Pnumstages); + } // Fl_Counter* filterstages + { Fl_Choice* o = magtype = new Fl_Choice(585, 340, 65, 15, "Mag.Type"); + magtype->down_box(FL_BORDER_BOX); + magtype->labelfont(1); + magtype->labelsize(10); + magtype->textsize(11); + magtype->callback((Fl_Callback*)cb_magtype); + magtype->align(FL_ALIGN_TOP); + magtype->menu(menu_magtype); + o->value(pars->Phmagtype); + } // Fl_Choice* magtype + { Fl_Choice* o = start = new Fl_Choice(670, 340, 50, 15, "Start"); + start->down_box(FL_BORDER_BOX); + start->labelfont(1); + start->labelsize(10); + start->textsize(11); + start->callback((Fl_Callback*)cb_start); + start->align(FL_ALIGN_TOP); + start->menu(menu_start); + o->value(pars->Pstart); + } // Fl_Choice* start + o->end(); + } // Fl_Group* o + { freqsettingsui = new Fl_Group(440, 5, 290, 135, "FREQUENCY"); + freqsettingsui->box(FL_THIN_UP_FRAME); + freqsettingsui->labeltype(FL_EMBOSSED_LABEL); + freqsettingsui->labelfont(1); + freqsettingsui->align(FL_ALIGN_TOP|FL_ALIGN_INSIDE); + { EnvelopeUI* o = freqenvelopegroup = new EnvelopeUI(445, 65, 205, 70, "SUBsynth - Frequency Envelope"); + freqenvelopegroup->box(FL_FLAT_BOX); + freqenvelopegroup->color((Fl_Color)51); + freqenvelopegroup->selection_color(FL_BACKGROUND_COLOR); + freqenvelopegroup->labeltype(FL_NORMAL_LABEL); + freqenvelopegroup->labelfont(0); + freqenvelopegroup->labelsize(14); + freqenvelopegroup->labelcolor(FL_FOREGROUND_COLOR); + freqenvelopegroup->align(FL_ALIGN_WRAP|FL_ALIGN_INSIDE); + freqenvelopegroup->when(FL_WHEN_RELEASE); + o->init(pars->FreqEnvelope); + if (pars->PFreqEnvelopeEnabled==0) o->deactivate(); + freqenvelopegroup->end(); + } // EnvelopeUI* freqenvelopegroup + { Fl_Check_Button* o = freqee = new Fl_Check_Button(445, 68, 55, 15, "Enabled"); + freqee->down_box(FL_DOWN_BOX); + freqee->labelfont(1); + freqee->labelsize(10); + freqee->callback((Fl_Callback*)cb_freqee); + o->value(pars->PFreqEnvelopeEnabled); + } // Fl_Check_Button* freqee + { Fl_Counter* o = octave = new Fl_Counter(670, 50, 45, 15, "Octave"); + octave->tooltip("Octave"); + octave->type(1); + octave->labelsize(10); + octave->minimum(-8); + octave->maximum(7); + octave->step(1); + octave->textfont(1); + octave->textsize(11); + octave->callback((Fl_Callback*)cb_octave); + octave->align(FL_ALIGN_TOP); + int k=pars->PCoarseDetune/1024;if (k>=8) k-=16; + o->value(k); + } // Fl_Counter* octave + { Fl_Counter* o = coarsedet = new Fl_Counter(655, 115, 60, 20, "Coarse Det."); + coarsedet->tooltip("Coarse Detune"); + coarsedet->labelsize(10); + coarsedet->minimum(-64); + coarsedet->maximum(63); + coarsedet->step(1); + coarsedet->textfont(1); + coarsedet->textsize(11); + coarsedet->callback((Fl_Callback*)cb_coarsedet); + coarsedet->align(FL_ALIGN_TOP); + int k=pars->PCoarseDetune%1024;if (k>=512) k-=1024; + o->value(k); + o->lstep(10); + } // Fl_Counter* coarsedet + { Fl_Slider* o = detune = new Fl_Slider(495, 25, 230, 15); + detune->tooltip("Fine Detune (cents)"); + detune->type(5); + detune->box(FL_FLAT_BOX); + detune->minimum(-8192); + detune->maximum(8191); + detune->step(1); + detune->callback((Fl_Callback*)cb_detune); + o->value(pars->PDetune-8192); + } // Fl_Slider* detune + { Fl_Value_Output* o = detunevalueoutput = new Fl_Value_Output(448, 25, 45, 15, "Detune"); + detunevalueoutput->labelsize(10); + detunevalueoutput->minimum(-5000); + detunevalueoutput->maximum(5000); + detunevalueoutput->step(0.01); + detunevalueoutput->textfont(1); + detunevalueoutput->textsize(10); + detunevalueoutput->callback((Fl_Callback*)cb_detunevalueoutput); + detunevalueoutput->align(FL_ALIGN_TOP_LEFT); + o->value(getdetune(pars->PDetuneType,0,pars->PDetune)); + } // Fl_Value_Output* detunevalueoutput + { Fl_Check_Button* o = hz440 = new Fl_Check_Button(555, 45, 50, 15, "440Hz"); + hz440->tooltip("set the base frequency to 440Hz"); + hz440->down_box(FL_DOWN_BOX); + hz440->labelfont(1); + hz440->labelsize(10); + hz440->callback((Fl_Callback*)cb_hz440); + o->value(pars->Pfixedfreq); + } // Fl_Check_Button* hz440 + { WidgetPDial* o = fixedfreqetdial = new WidgetPDial(610, 45, 15, 15, "Eq.T."); + fixedfreqetdial->tooltip("How the frequency varies acording to the keyboard (leftmost for fixed frequen\ +cy)"); + fixedfreqetdial->box(FL_ROUND_UP_BOX); + fixedfreqetdial->color(FL_BACKGROUND_COLOR); + fixedfreqetdial->selection_color(FL_INACTIVE_COLOR); + fixedfreqetdial->labeltype(FL_NORMAL_LABEL); + fixedfreqetdial->labelfont(0); + fixedfreqetdial->labelsize(10); + fixedfreqetdial->labelcolor(FL_FOREGROUND_COLOR); + fixedfreqetdial->maximum(127); + fixedfreqetdial->step(1); + fixedfreqetdial->callback((Fl_Callback*)cb_fixedfreqetdial); + fixedfreqetdial->align(FL_ALIGN_RIGHT); + fixedfreqetdial->when(FL_WHEN_CHANGED); + o->value(pars->PfixedfreqET); + if (pars->Pfixedfreq==0) o->deactivate(); + } // WidgetPDial* fixedfreqetdial + { Fl_Choice* o = detunetype = new Fl_Choice(655, 85, 70, 15, "Detune Type"); + detunetype->down_box(FL_BORDER_BOX); + detunetype->labelsize(10); + detunetype->textfont(1); + detunetype->textsize(10); + detunetype->callback((Fl_Callback*)cb_detunetype); + detunetype->align(FL_ALIGN_TOP_LEFT); + o->add("L35cents");o->add("L10cents");o->add("E100cents");o->add("E1200cents"); + o->value(pars->PDetuneType-1); + } // Fl_Choice* detunetype + freqsettingsui->end(); + } // Fl_Group* freqsettingsui + { Fl_Check_Button* o = stereo = new Fl_Check_Button(440, 325, 55, 35, "Stereo"); + stereo->box(FL_THIN_UP_BOX); + stereo->down_box(FL_DOWN_BOX); + stereo->labelfont(1); + stereo->labelsize(10); + stereo->callback((Fl_Callback*)cb_stereo); + o->value(pars->Pstereo); + } // Fl_Check_Button* stereo + { Fl_Button* o = new Fl_Button(445, 365, 70, 20, "Clear"); + o->tooltip("Clear the harmonics"); + o->box(FL_THIN_UP_BOX); + o->labelfont(1); + o->labelsize(11); + o->callback((Fl_Callback*)cb_Clear); + } // Fl_Button* o + { bandwidthsettingsui = new Fl_Group(220, 5, 220, 135, "BANDWIDTH"); + bandwidthsettingsui->box(FL_THIN_UP_FRAME); + bandwidthsettingsui->labeltype(FL_EMBOSSED_LABEL); + bandwidthsettingsui->labelfont(1); + bandwidthsettingsui->align(FL_ALIGN_TOP|FL_ALIGN_INSIDE); + { EnvelopeUI* o = bandwidthenvelopegroup = new EnvelopeUI(225, 65, 205, 70, "SUBsynth - BandWidth Envelope"); + bandwidthenvelopegroup->box(FL_FLAT_BOX); + bandwidthenvelopegroup->color((Fl_Color)51); + bandwidthenvelopegroup->selection_color(FL_BACKGROUND_COLOR); + bandwidthenvelopegroup->labeltype(FL_NORMAL_LABEL); + bandwidthenvelopegroup->labelfont(0); + bandwidthenvelopegroup->labelsize(14); + bandwidthenvelopegroup->labelcolor(FL_FOREGROUND_COLOR); + bandwidthenvelopegroup->align(FL_ALIGN_WRAP|FL_ALIGN_INSIDE); + bandwidthenvelopegroup->when(FL_WHEN_RELEASE); + o->init(pars->BandWidthEnvelope); + if (pars->PBandWidthEnvelopeEnabled==0) o->deactivate(); + bandwidthenvelopegroup->end(); + } // EnvelopeUI* bandwidthenvelopegroup + { Fl_Check_Button* o = bwee = new Fl_Check_Button(225, 67, 55, 15, "Enabled"); + bwee->down_box(FL_DOWN_BOX); + bwee->labelfont(1); + bwee->labelsize(10); + bwee->callback((Fl_Callback*)cb_bwee); + o->value(pars->PBandWidthEnvelopeEnabled); + } // Fl_Check_Button* bwee + { Fl_Value_Slider* o = bandwidth = new Fl_Value_Slider(225, 40, 115, 15, "Band Width"); + bandwidth->type(5); + bandwidth->box(FL_FLAT_BOX); + bandwidth->labelsize(10); + bandwidth->maximum(127); + bandwidth->step(1); + bandwidth->callback((Fl_Callback*)cb_bandwidth); + bandwidth->align(FL_ALIGN_TOP); + o->value(pars->Pbandwidth); + } // Fl_Value_Slider* bandwidth + { Fl_Value_Slider* o = bwidthscale = new Fl_Value_Slider(345, 40, 90, 15, "B.Width Scale"); + bwidthscale->tooltip("How much I increase the BandWidth according to lower/higher harmonics"); + bwidthscale->type(5); + bwidthscale->box(FL_FLAT_BOX); + bwidthscale->labelsize(10); + bwidthscale->minimum(-64); + bwidthscale->maximum(63); + bwidthscale->step(1); + bwidthscale->callback((Fl_Callback*)cb_bwidthscale); + bwidthscale->align(FL_ALIGN_TOP); + o->value(pars->Pbwscale-64); + } // Fl_Value_Slider* bwidthscale + bandwidthsettingsui->end(); + } // Fl_Group* bandwidthsettingsui + { Fl_Group* o = globalfiltergroup = new Fl_Group(440, 140, 290, 185, "FILTER"); + globalfiltergroup->box(FL_THIN_UP_FRAME); + globalfiltergroup->labeltype(FL_EMBOSSED_LABEL); + globalfiltergroup->labelfont(1); + globalfiltergroup->labelsize(13); + globalfiltergroup->align(FL_ALIGN_TOP|FL_ALIGN_INSIDE); + { EnvelopeUI* o = filterenv = new EnvelopeUI(445, 250, 275, 70, "SUBsynth - Filter Envelope"); + filterenv->box(FL_FLAT_BOX); + filterenv->color((Fl_Color)51); + filterenv->selection_color(FL_BACKGROUND_COLOR); + filterenv->labeltype(FL_NORMAL_LABEL); + filterenv->labelfont(0); + filterenv->labelsize(14); + filterenv->labelcolor(FL_FOREGROUND_COLOR); + filterenv->align(FL_ALIGN_WRAP|FL_ALIGN_INSIDE); + filterenv->when(FL_WHEN_RELEASE); + o->init(pars->GlobalFilterEnvelope); + filterenv->end(); + } // EnvelopeUI* filterenv + { FilterUI* o = filterui = new FilterUI(445, 170, 275, 75, "SUBsynthl - Filter"); + filterui->box(FL_FLAT_BOX); + filterui->color(FL_LIGHT1); + filterui->selection_color(FL_BACKGROUND_COLOR); + filterui->labeltype(FL_NORMAL_LABEL); + filterui->labelfont(0); + filterui->labelsize(14); + filterui->labelcolor(FL_FOREGROUND_COLOR); + filterui->align(FL_ALIGN_WRAP|FL_ALIGN_INSIDE); + filterui->when(FL_WHEN_RELEASE); + o->init(pars->GlobalFilter,&pars->PGlobalFilterVelocityScale,&pars->PGlobalFilterVelocityScaleFunction); + filterui->end(); + } // FilterUI* filterui + if (pars->PGlobalFilterEnabled==0) o->deactivate(); + globalfiltergroup->end(); + } // Fl_Group* globalfiltergroup + { Fl_Check_Button* o = filtere = new Fl_Check_Button(445, 145, 85, 20, "Enabled"); + filtere->down_box(FL_DOWN_BOX); + filtere->labelfont(1); + filtere->labelsize(11); + filtere->callback((Fl_Callback*)cb_filtere); + o->value(pars->PGlobalFilterEnabled); + } // Fl_Check_Button* filtere + { Fl_Button* o = new Fl_Button(540, 370, 25, 15, "C"); + o->box(FL_THIN_UP_BOX); + o->color((Fl_Color)179); + o->labelfont(1); + o->labelsize(11); + o->labelcolor(FL_BACKGROUND2_COLOR); + o->callback((Fl_Callback*)cb_C); + } // Fl_Button* o + { Fl_Button* o = new Fl_Button(570, 370, 25, 15, "P"); + o->box(FL_THIN_UP_BOX); + o->color((Fl_Color)179); + o->labelfont(1); + o->labelsize(11); + o->labelcolor(FL_BACKGROUND2_COLOR); + o->callback((Fl_Callback*)cb_P); + } // Fl_Button* o + SUBparameters->end(); + } // Fl_Double_Window* SUBparameters + return SUBparameters; +} + +void SUBnoteUI::refresh() { + for (int i=0;irefresh(); +vol->value(pars->PVolume); +vsns->value(pars->PAmpVelocityScaleFunction); +pan->value(pars->PPanning); + + +bandwidth->value(pars->Pbandwidth); +bwidthscale->value(pars->Pbwscale-64); +bwee->value(pars->PBandWidthEnvelopeEnabled); +if (pars->PBandWidthEnvelopeEnabled==0) bandwidthenvelopegroup->deactivate(); + else bandwidthenvelopegroup->activate(); +bwee->show(); +bandwidthsettingsui->redraw(); + +detunevalueoutput->value(getdetune(pars->PDetuneType,0,pars->PDetune)); +freqee->value(pars->PFreqEnvelopeEnabled); +if (pars->PFreqEnvelopeEnabled==0) freqenvelopegroup->deactivate(); + else freqenvelopegroup->activate(); +freqee->show(); +freqsettingsui->redraw(); + +detune->value(pars->PDetune-8192); +hz440->value(pars->Pfixedfreq); + +fixedfreqetdial->value(pars->PfixedfreqET); + +int k=pars->PCoarseDetune/1024;if (k>=8) k-=16; +octave->value(k); + +detunetype->value(pars->PDetuneType-1); + +k=pars->PCoarseDetune%1024;if (k>=512) k-=1024; +coarsedet->value(k); + +filtere->value(pars->PGlobalFilterEnabled); +if (pars->PGlobalFilterEnabled==0) globalfiltergroup->deactivate(); + else globalfiltergroup->activate(); +filtere->show(); +globalfiltergroup->redraw(); + +stereo->value(pars->Pstereo); +filterstages->value(pars->Pnumstages); +magtype->value(pars->Phmagtype); +start->value(pars->Pstart); + +ampenv->refresh(); +bandwidthenvelopegroup->refresh(); +freqenvelopegroup->refresh(); +filterui->refresh(); +filterenv->refresh(); +} + +SUBnoteUI::SUBnoteUI(SUBnoteParameters *parameters) { + pars=parameters; +make_window(); +} + +SUBnoteUI::~SUBnoteUI() { + //for (int i=0;ihide(); +delete(SUBparameters); +} diff --git a/plugins/zynaddsubfx/src/UI/SUBnoteUI.fl b/plugins/zynaddsubfx/src/UI/SUBnoteUI.fl new file mode 100644 index 000000000..ef50a0bb9 --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/SUBnoteUI.fl @@ -0,0 +1,449 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0105 +header_name {.h} +code_name {.cc} +decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} + +decl {//License: GNU GPL version 2 or later} {} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include "../globals.h"} {public +} + +decl {\#include "WidgetPDial.h"} {public +} + +decl {\#include "EnvelopeUI.h"} {public +} + +decl {\#include "FilterUI.h"} {public +} + +decl {\#include "../Misc/Util.h"} {public +} + +decl {\#include "../Params/SUBnoteParameters.h"} {public +} + +decl {\#include "PresetsUI.h"} {public +} + +class SUBnoteharmonic {: {public Fl_Group} +} { + Function {make_window()} {private + } { + Fl_Window harmonic { + xywh {329 403 90 225} type Double hide + class Fl_Group + } { + Fl_Slider mag { + callback {int x=0; +if (Fl::event_button1()) x=127-(int)o->value(); + else o->value(127-x); +pars->Phmag[n]=x; +if (pars->Phmag[n]==0) o->selection_color(0); + else o->selection_color(222);} + tooltip {harmonic's magnitude} xywh {0 15 10 115} type {Vert Knob} box FLAT_BOX selection_color 222 labelcolor 0 maximum 127 step 1 value 127 + code0 {o->value(127-pars->Phmag[n]);} + code1 {if (pars->Phmag[n]==0) o->selection_color(0);} + } + Fl_Slider bw { + callback {int x=64; +if (Fl::event_button1()) x=127-(int)o->value(); + else o->value(x); +pars->Phrelbw[n]=x;} + tooltip {harmonic's bandwidth} xywh {0 135 10 75} type {Vert Knob} box FLAT_BOX selection_color 222 maximum 127 step 1 value 64 + code0 {o->value(127-pars->Phrelbw[n]);} + } + Fl_Box {} { + xywh {10 170 5 5} box FLAT_BOX color 45 + code0 {if (n+1==MAX_SUB_HARMONICS) o->hide();} + } + Fl_Box {} { + label 01 + xywh {0 210 10 15} labelfont 1 labelsize 9 align 20 + code0 {char tmp[10];snprintf(tmp,10,"%d",n+1);o->label(strdup(tmp));} + } + Fl_Box {} { + label 01 + xywh {0 0 10 15} labelfont 1 labelsize 9 align 20 + code0 {char tmp[10];snprintf(tmp,10,"%d",n+1);o->label(strdup(tmp));} + } + } + } + Function {SUBnoteharmonic(int x,int y, int w, int h, const char *label=0):Fl_Group(x,y,w,h,label)} {} { + code {n=0;} {} + } + Function {init(SUBnoteParameters *pars_,int n_)} {} { + code {pars=pars_; +n=n_; +make_window(); +harmonic->show(); +end();} {} + } + Function {refresh()} {} { + code {mag->value(127-pars->Phmag[n]); +if (pars->Phmag[n]==0) mag->selection_color(0); +bw->value(127-pars->Phrelbw[n]);} {selected + } + } + Function {~SUBnoteharmonic()} {} { + code {harmonic->hide(); +hide(); +//delete(harmonic);} {} + } + decl {SUBnoteParameters *pars;} {} + decl {int n;} {} +} + +class SUBnoteUI {: {public PresetsUI_} +} { + Function {make_window()} {} { + Fl_Window SUBparameters { + label {SUBsynth Parameters} + xywh {26 214 735 390} type Double hide + } { + Fl_Scroll {} { + xywh {5 140 435 245} type HORIZONTAL box THIN_UP_BOX + } { + Fl_Pack harmonics {open + xywh {10 145 425 235} type HORIZONTAL + code0 {for (int i=0;ih(),"");h[i]->init(pars,i);}} + } {} + } + Fl_Button {} { + label Close + callback {SUBparameters->hide();} + xywh {625 365 105 20} box THIN_UP_BOX labelfont 1 labelsize 11 + } + Fl_Group {} { + label AMPLITUDE + xywh {5 5 215 135} box THIN_UP_FRAME labeltype EMBOSSED_LABEL labelfont 1 align 17 + } { + Fl_Value_Slider vol { + label Vol + callback {pars->PVolume=(int)o->value();} + tooltip Volume xywh {10 25 140 15} type {Horz Knob} box FLAT_BOX labelsize 11 align 8 maximum 127 step 1 + code0 {o->value(pars->PVolume);} + } + Fl_Value_Slider vsns { + label {V.Sns} + callback {pars->PAmpVelocityScaleFunction=(int) o->value();} + tooltip {Velocity Sensing Function (rightmost to disable)} xywh {10 45 140 15} type {Horz Knob} box FLAT_BOX labelsize 11 align 8 maximum 127 step 1 + code0 {o->value(pars->PAmpVelocityScaleFunction);} + } + Fl_Dial pan { + label Pan + callback {pars->PPanning=(int) o->value();} + tooltip {Panning (leftmost is Random)} xywh {185 20 30 30} box ROUND_UP_BOX labelsize 10 maximum 127 step 1 + code0 {o->value(pars->PPanning);} + class WidgetPDial + } + Fl_Group ampenv { + label {SUBsynth - Amplitude Envelope} open + xywh {10 65 205 70} box FLAT_BOX color 51 align 144 + code0 {o->init(pars->AmpEnvelope);} + class EnvelopeUI + } {} + } + Fl_Group {} { + xywh {495 325 235 35} box THIN_UP_FRAME + } { + Fl_Counter filterstages { + label {Filter Stages} + callback {pars->Pnumstages=(int) o->value();} + tooltip {How many times the noise is filtered} xywh {515 340 45 15} type Simple labelfont 1 labelsize 10 align 1 minimum 1 maximum 5 step 1 textsize 10 + code0 {o->value(pars->Pnumstages);} + } + Fl_Choice magtype { + label {Mag.Type} + callback {pars->Phmagtype=(int) o->value();} + xywh {585 340 65 15} down_box BORDER_BOX labelfont 1 labelsize 10 align 1 textsize 11 + code0 {o->value(pars->Phmagtype);} + } { + menuitem {} { + label Linear + xywh {20 20 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label {-40dB} + xywh {30 30 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label {-60dB} + xywh {40 40 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label {-80dB} + xywh {50 50 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label {-100dB} + xywh {60 60 100 20} labelfont 1 labelsize 11 + } + } + Fl_Choice start { + label Start + callback {pars->Pstart=(int) o->value();} open + xywh {670 340 50 15} down_box BORDER_BOX labelfont 1 labelsize 10 align 1 textsize 11 + code0 {o->value(pars->Pstart);} + } { + menuitem {} { + label Zero + xywh {30 30 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label RND + xywh {40 40 100 20} labelfont 1 labelsize 11 + } + menuitem {} { + label {Max.} + xywh {50 50 100 20} labelfont 1 labelsize 11 + } + } + } + Fl_Group freqsettingsui { + label FREQUENCY + xywh {440 5 290 135} box THIN_UP_FRAME labeltype EMBOSSED_LABEL labelfont 1 align 17 + } { + Fl_Group freqenvelopegroup { + label {SUBsynth - Frequency Envelope} open + xywh {445 65 205 70} box FLAT_BOX color 51 align 144 + code0 {o->init(pars->FreqEnvelope);} + code1 {if (pars->PFreqEnvelopeEnabled==0) o->deactivate();} + class EnvelopeUI + } {} + Fl_Check_Button freqee { + label Enabled + callback {pars->PFreqEnvelopeEnabled=o->value(); +if (o->value()==0) freqenvelopegroup->deactivate(); + else freqenvelopegroup->activate(); +o->show(); +freqsettingsui->redraw();} + xywh {445 68 55 15} down_box DOWN_BOX labelfont 1 labelsize 10 + code0 {o->value(pars->PFreqEnvelopeEnabled);} + } + Fl_Counter octave { + label Octave + callback {int k=(int) o->value(); +if (k<0) k+=16; +pars->PCoarseDetune = k*1024+ + pars->PCoarseDetune%1024;} + tooltip Octave xywh {670 50 45 15} type Simple labelsize 10 align 1 minimum -8 maximum 7 step 1 textfont 1 textsize 11 + code0 {int k=pars->PCoarseDetune/1024;if (k>=8) k-=16;} + code2 {o->value(k);} + } + Fl_Counter coarsedet { + label {Coarse Det.} + callback {int k=(int) o->value(); +if (k<0) k+=1024; +pars->PCoarseDetune = k+ + (pars->PCoarseDetune/1024)*1024;} + tooltip {Coarse Detune} xywh {655 115 60 20} labelsize 10 align 1 minimum -64 maximum 63 step 1 textfont 1 textsize 11 + code0 {int k=pars->PCoarseDetune%1024;if (k>=512) k-=1024;} + code2 {o->value(k);} + code3 {o->lstep(10);} + } + Fl_Slider detune { + callback {pars->PDetune=(int)o->value()+8192; +detunevalueoutput->do_callback();} + tooltip {Fine Detune (cents)} xywh {495 25 230 15} type {Horz Knob} box FLAT_BOX minimum -8192 maximum 8191 step 1 + code0 {o->value(pars->PDetune-8192);} + } + Fl_Value_Output detunevalueoutput { + label Detune + callback {o->value(getdetune(pars->PDetuneType,0,pars->PDetune));} + xywh {448 25 45 15} labelsize 10 align 5 minimum -5000 maximum 5000 step 0.01 textfont 1 textsize 10 + code0 {o->value(getdetune(pars->PDetuneType,0,pars->PDetune));} + } + Fl_Check_Button hz440 { + label 440Hz + callback {int x=(int) o->value(); +pars->Pfixedfreq=x; +if (x==0) fixedfreqetdial->deactivate(); + else fixedfreqetdial->activate();} + tooltip {set the base frequency to 440Hz} xywh {555 45 50 15} down_box DOWN_BOX labelfont 1 labelsize 10 + code0 {o->value(pars->Pfixedfreq);} + } + Fl_Dial fixedfreqetdial { + label {Eq.T.} + callback {pars->PfixedfreqET=(int) o->value();} + tooltip {How the frequency varies acording to the keyboard (leftmost for fixed frequency)} xywh {610 45 15 15} box ROUND_UP_BOX labelsize 10 align 8 maximum 127 step 1 + code0 {o->value(pars->PfixedfreqET);} + code1 {if (pars->Pfixedfreq==0) o->deactivate();} + class WidgetPDial + } + Fl_Choice detunetype { + label {Detune Type} + callback {pars->PDetuneType=(int) o->value()+1; +detunevalueoutput->do_callback();} open + xywh {655 85 70 15} down_box BORDER_BOX labelsize 10 align 5 textfont 1 textsize 10 + code0 {o->add("L35cents");o->add("L10cents");o->add("E100cents");o->add("E1200cents");} + code1 {o->value(pars->PDetuneType-1);} + } {} + } + Fl_Check_Button stereo { + label Stereo + callback {pars->Pstereo=(int) o->value();} + xywh {440 325 55 35} box THIN_UP_BOX down_box DOWN_BOX labelfont 1 labelsize 10 + code0 {o->value(pars->Pstereo);} + } + Fl_Button {} { + label Clear + callback {for (int i=0;imag->value(127); + pars->Phmag[i]=0; + h[i]->bw->value(64); + pars->Phrelbw[i]=64; +}; +pars->Phmag[0]=127; +h[0]->mag->value(0); +SUBparameters->redraw();} + tooltip {Clear the harmonics} xywh {445 365 70 20} box THIN_UP_BOX labelfont 1 labelsize 11 + } + Fl_Group bandwidthsettingsui { + label BANDWIDTH + xywh {220 5 220 135} box THIN_UP_FRAME labeltype EMBOSSED_LABEL labelfont 1 align 17 + } { + Fl_Group bandwidthenvelopegroup { + label {SUBsynth - BandWidth Envelope} open + xywh {225 65 205 70} box FLAT_BOX color 51 align 144 + code0 {o->init(pars->BandWidthEnvelope);} + code1 {if (pars->PBandWidthEnvelopeEnabled==0) o->deactivate();} + class EnvelopeUI + } {} + Fl_Check_Button bwee { + label Enabled + callback {pars->PBandWidthEnvelopeEnabled=o->value(); +if (o->value()==0) bandwidthenvelopegroup->deactivate(); + else bandwidthenvelopegroup->activate(); +o->show(); +bandwidthsettingsui->redraw();} + xywh {225 67 55 15} down_box DOWN_BOX labelfont 1 labelsize 10 + code0 {o->value(pars->PBandWidthEnvelopeEnabled);} + } + Fl_Value_Slider bandwidth { + label {Band Width} + callback {pars->Pbandwidth=(int) o->value();} + xywh {225 40 115 15} type {Horz Knob} box FLAT_BOX labelsize 10 align 1 maximum 127 step 1 + code0 {o->value(pars->Pbandwidth);} + } + Fl_Value_Slider bwidthscale { + label {B.Width Scale} + callback {pars->Pbwscale=(int) o->value()+64;} + tooltip {How much I increase the BandWidth according to lower/higher harmonics} xywh {345 40 90 15} type {Horz Knob} box FLAT_BOX labelsize 10 align 1 minimum -64 maximum 63 step 1 + code0 {o->value(pars->Pbwscale-64);} + } + } + Fl_Group globalfiltergroup { + label FILTER + xywh {440 140 290 185} box THIN_UP_FRAME labeltype EMBOSSED_LABEL labelfont 1 labelsize 13 align 17 + code0 {if (pars->PGlobalFilterEnabled==0) o->deactivate();} + } { + Fl_Group filterenv { + label {SUBsynth - Filter Envelope} open + xywh {445 250 275 70} box FLAT_BOX color 51 align 144 + code0 {o->init(pars->GlobalFilterEnvelope);} + class EnvelopeUI + } {} + Fl_Group filterui { + label {SUBsynthl - Filter} open + xywh {445 170 275 75} box FLAT_BOX color 50 align 144 + code0 {o->init(pars->GlobalFilter,&pars->PGlobalFilterVelocityScale,&pars->PGlobalFilterVelocityScaleFunction);} + class FilterUI + } {} + } + Fl_Check_Button filtere { + label Enabled + callback {pars->PGlobalFilterEnabled=o->value(); +if (o->value()==0) globalfiltergroup->deactivate(); + else globalfiltergroup->activate(); +o->show(); +globalfiltergroup->redraw();} + xywh {445 145 85 20} down_box DOWN_BOX labelfont 1 labelsize 11 + code0 {o->value(pars->PGlobalFilterEnabled);} + } + Fl_Button {} { + label C + callback {presetsui->copy(pars);} + xywh {540 370 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 11 labelcolor 7 + } + Fl_Button {} { + label P + callback {presetsui->paste(pars,this);} + xywh {570 370 25 15} box THIN_UP_BOX color 179 labelfont 1 labelsize 11 labelcolor 7 + } + } + } + Function {refresh()} {} { + code {for (int i=0;irefresh(); +vol->value(pars->PVolume); +vsns->value(pars->PAmpVelocityScaleFunction); +pan->value(pars->PPanning); + + +bandwidth->value(pars->Pbandwidth); +bwidthscale->value(pars->Pbwscale-64); +bwee->value(pars->PBandWidthEnvelopeEnabled); +if (pars->PBandWidthEnvelopeEnabled==0) bandwidthenvelopegroup->deactivate(); + else bandwidthenvelopegroup->activate(); +bwee->show(); +bandwidthsettingsui->redraw(); + +detunevalueoutput->value(getdetune(pars->PDetuneType,0,pars->PDetune)); +freqee->value(pars->PFreqEnvelopeEnabled); +if (pars->PFreqEnvelopeEnabled==0) freqenvelopegroup->deactivate(); + else freqenvelopegroup->activate(); +freqee->show(); +freqsettingsui->redraw(); + +detune->value(pars->PDetune-8192); +hz440->value(pars->Pfixedfreq); + +fixedfreqetdial->value(pars->PfixedfreqET); + +int k=pars->PCoarseDetune/1024;if (k>=8) k-=16; +octave->value(k); + +detunetype->value(pars->PDetuneType-1); + +k=pars->PCoarseDetune%1024;if (k>=512) k-=1024; +coarsedet->value(k); + +filtere->value(pars->PGlobalFilterEnabled); +if (pars->PGlobalFilterEnabled==0) globalfiltergroup->deactivate(); + else globalfiltergroup->activate(); +filtere->show(); +globalfiltergroup->redraw(); + +stereo->value(pars->Pstereo); +filterstages->value(pars->Pnumstages); +magtype->value(pars->Phmagtype); +start->value(pars->Pstart); + +ampenv->refresh(); +bandwidthenvelopegroup->refresh(); +freqenvelopegroup->refresh(); +filterui->refresh(); +filterenv->refresh();} {} + } + Function {SUBnoteUI(SUBnoteParameters *parameters)} {} { + code {pars=parameters; +make_window();} {} + } + Function {~SUBnoteUI()} {} { + code {//for (int i=0;ihide(); +delete(SUBparameters);} {} + } + decl {SUBnoteParameters *pars;} {} + decl {SUBnoteharmonic *h[MAX_SUB_HARMONICS];} {} +} diff --git a/plugins/zynaddsubfx/src/UI/SUBnoteUI.h b/plugins/zynaddsubfx/src/UI/SUBnoteUI.h new file mode 100644 index 000000000..b8bdfff60 --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/SUBnoteUI.h @@ -0,0 +1,179 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0109 + +#ifndef SUBnoteUI_h +#define SUBnoteUI_h +#include +#include +#include +#include +#include "../globals.h" +#include "WidgetPDial.h" +#include "EnvelopeUI.h" +#include "FilterUI.h" +#include "../Misc/Util.h" +#include "../Params/SUBnoteParameters.h" +#include "PresetsUI.h" +#include +#include + +class SUBnoteharmonic : public Fl_Group { + Fl_Group* make_window(); +public: + Fl_Group *harmonic; + Fl_Slider *mag; +private: + void cb_mag_i(Fl_Slider*, void*); + static void cb_mag(Fl_Slider*, void*); +public: + Fl_Slider *bw; +private: + void cb_bw_i(Fl_Slider*, void*); + static void cb_bw(Fl_Slider*, void*); +public: + SUBnoteharmonic(int x,int y, int w, int h, const char *label=0); + void init(SUBnoteParameters *pars_,int n_); + void refresh(); + ~SUBnoteharmonic(); +private: + SUBnoteParameters *pars; + int n; +}; +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class SUBnoteUI : public PresetsUI_ { +public: + Fl_Double_Window* make_window(); + Fl_Double_Window *SUBparameters; + Fl_Pack *harmonics; +private: + void cb_Close_i(Fl_Button*, void*); + static void cb_Close(Fl_Button*, void*); +public: + Fl_Value_Slider *vol; +private: + void cb_vol_i(Fl_Value_Slider*, void*); + static void cb_vol(Fl_Value_Slider*, void*); +public: + Fl_Value_Slider *vsns; +private: + void cb_vsns_i(Fl_Value_Slider*, void*); + static void cb_vsns(Fl_Value_Slider*, void*); +public: + WidgetPDial *pan; +private: + void cb_pan_i(WidgetPDial*, void*); + static void cb_pan(WidgetPDial*, void*); +public: + EnvelopeUI *ampenv; + Fl_Counter *filterstages; +private: + void cb_filterstages_i(Fl_Counter*, void*); + static void cb_filterstages(Fl_Counter*, void*); +public: + Fl_Choice *magtype; +private: + void cb_magtype_i(Fl_Choice*, void*); + static void cb_magtype(Fl_Choice*, void*); + static Fl_Menu_Item menu_magtype[]; +public: + Fl_Choice *start; +private: + void cb_start_i(Fl_Choice*, void*); + static void cb_start(Fl_Choice*, void*); + static Fl_Menu_Item menu_start[]; +public: + Fl_Group *freqsettingsui; + EnvelopeUI *freqenvelopegroup; + Fl_Check_Button *freqee; +private: + void cb_freqee_i(Fl_Check_Button*, void*); + static void cb_freqee(Fl_Check_Button*, void*); +public: + Fl_Counter *octave; +private: + void cb_octave_i(Fl_Counter*, void*); + static void cb_octave(Fl_Counter*, void*); +public: + Fl_Counter *coarsedet; +private: + void cb_coarsedet_i(Fl_Counter*, void*); + static void cb_coarsedet(Fl_Counter*, void*); +public: + Fl_Slider *detune; +private: + void cb_detune_i(Fl_Slider*, void*); + static void cb_detune(Fl_Slider*, void*); +public: + Fl_Value_Output *detunevalueoutput; +private: + void cb_detunevalueoutput_i(Fl_Value_Output*, void*); + static void cb_detunevalueoutput(Fl_Value_Output*, void*); +public: + Fl_Check_Button *hz440; +private: + void cb_hz440_i(Fl_Check_Button*, void*); + static void cb_hz440(Fl_Check_Button*, void*); +public: + WidgetPDial *fixedfreqetdial; +private: + void cb_fixedfreqetdial_i(WidgetPDial*, void*); + static void cb_fixedfreqetdial(WidgetPDial*, void*); +public: + Fl_Choice *detunetype; +private: + void cb_detunetype_i(Fl_Choice*, void*); + static void cb_detunetype(Fl_Choice*, void*); +public: + Fl_Check_Button *stereo; +private: + void cb_stereo_i(Fl_Check_Button*, void*); + static void cb_stereo(Fl_Check_Button*, void*); + void cb_Clear_i(Fl_Button*, void*); + static void cb_Clear(Fl_Button*, void*); +public: + Fl_Group *bandwidthsettingsui; + EnvelopeUI *bandwidthenvelopegroup; + Fl_Check_Button *bwee; +private: + void cb_bwee_i(Fl_Check_Button*, void*); + static void cb_bwee(Fl_Check_Button*, void*); +public: + Fl_Value_Slider *bandwidth; +private: + void cb_bandwidth_i(Fl_Value_Slider*, void*); + static void cb_bandwidth(Fl_Value_Slider*, void*); +public: + Fl_Value_Slider *bwidthscale; +private: + void cb_bwidthscale_i(Fl_Value_Slider*, void*); + static void cb_bwidthscale(Fl_Value_Slider*, void*); +public: + Fl_Group *globalfiltergroup; + EnvelopeUI *filterenv; + FilterUI *filterui; + Fl_Check_Button *filtere; +private: + void cb_filtere_i(Fl_Check_Button*, void*); + static void cb_filtere(Fl_Check_Button*, void*); + void cb_C_i(Fl_Button*, void*); + static void cb_C(Fl_Button*, void*); + void cb_P_i(Fl_Button*, void*); + static void cb_P(Fl_Button*, void*); +public: + void refresh(); + SUBnoteUI(SUBnoteParameters *parameters); + ~SUBnoteUI(); +private: + SUBnoteParameters *pars; + SUBnoteharmonic *h[MAX_SUB_HARMONICS]; +}; +#endif diff --git a/plugins/zynaddsubfx/src/UI/SeqUI.cc b/plugins/zynaddsubfx/src/UI/SeqUI.cc new file mode 100644 index 000000000..84c1b2e61 --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/SeqUI.cc @@ -0,0 +1,98 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0109 + +#include "SeqUI.h" +//Copyright (c) 2002-2005 Nasca Octavian Paul +//License: GNU GPL version 2 or later + +void SeqUI::cb_playbutton_i(Fl_Button* o, void*) { + o->deactivate(); +stopbutton_play->activate(); + +master->seq.startplay(); +} +void SeqUI::cb_playbutton(Fl_Button* o, void* v) { + ((SeqUI*)(o->parent()->parent()->user_data()))->cb_playbutton_i(o,v); +} + +void SeqUI::cb_stopbutton_play_i(Fl_Button* o, void*) { + o->deactivate(); +playbutton->activate(); + +master->seq.stopplay(); +} +void SeqUI::cb_stopbutton_play(Fl_Button* o, void* v) { + ((SeqUI*)(o->parent()->parent()->user_data()))->cb_stopbutton_play_i(o,v); +} + +void SeqUI::cb_Open_i(Fl_Button*, void*) { + master->seq.importmidifile("test.mid"); +} +void SeqUI::cb_Open(Fl_Button* o, void* v) { + ((SeqUI*)(o->parent()->user_data()))->cb_Open_i(o,v); +} + +void SeqUI::cb_Play_i(Fl_Value_Slider* o, void*) { + master->seq.setplayspeed((int) o->value()); +} +void SeqUI::cb_Play(Fl_Value_Slider* o, void* v) { + ((SeqUI*)(o->parent()->user_data()))->cb_Play_i(o,v); +} + +Fl_Double_Window* SeqUI::make_window() { + { seqwin = new Fl_Double_Window(280, 265, "Sequencer - ZynAddSubFX"); + seqwin->user_data((void*)(this)); + { Fl_Group* o = new Fl_Group(120, 20, 100, 65, "Player"); + o->box(FL_ENGRAVED_BOX); + o->labelfont(1); + { playbutton = new Fl_Button(130, 30, 30, 30, "Play"); + playbutton->tooltip("Start Playing"); + playbutton->box(FL_DIAMOND_UP_BOX); + playbutton->color((Fl_Color)79); + playbutton->labelfont(1); + playbutton->labelsize(13); + playbutton->callback((Fl_Callback*)cb_playbutton); + playbutton->align(FL_ALIGN_BOTTOM); + } // Fl_Button* playbutton + { stopbutton_play = new Fl_Button(175, 29, 30, 31, "Stop"); + stopbutton_play->tooltip("Stop Playing"); + stopbutton_play->box(FL_THIN_UP_BOX); + stopbutton_play->color((Fl_Color)4); + stopbutton_play->labelfont(1); + stopbutton_play->labelsize(13); + stopbutton_play->callback((Fl_Callback*)cb_stopbutton_play); + stopbutton_play->align(FL_ALIGN_BOTTOM); + stopbutton_play->deactivate(); + } // Fl_Button* stopbutton_play + o->end(); + } // Fl_Group* o + { Fl_Button* o = new Fl_Button(20, 25, 75, 55, "Open test.mid"); + o->callback((Fl_Callback*)cb_Open); + o->align(FL_ALIGN_WRAP); + } // Fl_Button* o + { Fl_Value_Slider* o = new Fl_Value_Slider(15, 105, 190, 20, "Play speed"); + o->type(5); + o->minimum(-128); + o->maximum(128); + o->step(1); + o->callback((Fl_Callback*)cb_Play); + o->value(master->seq.playspeed); + } // Fl_Value_Slider* o + { Fl_Box* o = new Fl_Box(25, 155, 225, 90, "This is not finished"); + o->labelfont(1); + o->labelsize(22); + o->align(FL_ALIGN_WRAP); + } // Fl_Box* o + seqwin->end(); + } // Fl_Double_Window* seqwin + return seqwin; +} + +SeqUI::SeqUI(Master *master_) { + master=master_; + +make_window(); +} + +void SeqUI::show() { + seqwin->show(); +} diff --git a/plugins/zynaddsubfx/src/UI/SeqUI.fl b/plugins/zynaddsubfx/src/UI/SeqUI.fl new file mode 100644 index 000000000..343719c65 --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/SeqUI.fl @@ -0,0 +1,73 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0105 +header_name {.h} +code_name {.cc} +decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} + +decl {//License: GNU GPL version 2 or later} {} + +decl {\#include "../globals.h"} {public +} + +decl {\#include "../Misc/Master.h"} {public +} + +decl {\#include "WidgetPDial.h"} {public +} + +class SeqUI {} { + Function {make_window()} {} { + Fl_Window seqwin { + label {Sequencer - ZynAddSubFX} + xywh {104 235 280 265} type Double hide + } { + Fl_Group {} { + label Player + xywh {120 20 100 65} box ENGRAVED_BOX labelfont 1 + } { + Fl_Button playbutton { + label Play + callback {o->deactivate(); +stopbutton_play->activate(); + +master->seq.startplay();} + tooltip {Start Playing} xywh {130 30 30 30} box DIAMOND_UP_BOX color 79 labelfont 1 labelsize 13 align 2 + } + Fl_Button stopbutton_play { + label Stop + callback {o->deactivate(); +playbutton->activate(); + +master->seq.stopplay();} + tooltip {Stop Playing} xywh {175 29 30 31} box THIN_UP_BOX color 4 labelfont 1 labelsize 13 align 2 deactivate + } + } + Fl_Button {} { + label {Open test.mid} + callback {master->seq.importmidifile("test.mid");} + xywh {20 25 75 55} align 128 + } + Fl_Value_Slider {} { + label {Play speed} + callback {master->seq.setplayspeed((int) o->value());} + xywh {15 105 190 20} type {Horz Knob} minimum -128 maximum 128 step 1 + code0 {o->value(master->seq.playspeed);} + } + Fl_Box {} { + label {This is not finished} selected + xywh {25 155 225 90} labelfont 1 labelsize 22 align 128 + } + } + } + Function {SeqUI(Master *master_)} {open + } { + code {master=master_; + +make_window();} {} + } + decl {Master *master} {} + Function {show()} {open + } { + code {seqwin->show();} {} + } +} diff --git a/plugins/zynaddsubfx/src/UI/SeqUI.h b/plugins/zynaddsubfx/src/UI/SeqUI.h new file mode 100644 index 000000000..67dbdf42a --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/SeqUI.h @@ -0,0 +1,39 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0109 + +#ifndef SeqUI_h +#define SeqUI_h +#include +#include "../globals.h" +#include "../Misc/Master.h" +#include "WidgetPDial.h" +#include +#include +#include +#include +#include + +class SeqUI { +public: + Fl_Double_Window* make_window(); + Fl_Double_Window *seqwin; + Fl_Button *playbutton; +private: + void cb_playbutton_i(Fl_Button*, void*); + static void cb_playbutton(Fl_Button*, void*); +public: + Fl_Button *stopbutton_play; +private: + void cb_stopbutton_play_i(Fl_Button*, void*); + static void cb_stopbutton_play(Fl_Button*, void*); + void cb_Open_i(Fl_Button*, void*); + static void cb_Open(Fl_Button*, void*); + void cb_Play_i(Fl_Value_Slider*, void*); + static void cb_Play(Fl_Value_Slider*, void*); +public: + SeqUI(Master *master_); +private: + Master *master; +public: + void show(); +}; +#endif diff --git a/plugins/zynaddsubfx/src/UI/VirKeyboard.cc b/plugins/zynaddsubfx/src/UI/VirKeyboard.cc new file mode 100644 index 000000000..e32a7cd8e --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/VirKeyboard.cc @@ -0,0 +1,487 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0109 + +#include "VirKeyboard.h" +//Copyright (c) 2002-2005 Nasca Octavian Paul +//License: GNU GPL version 2 or later +static const int keyspos[12]={0,-1,1,-2,2,3,-4,4,-5,5,-6,6}; +static const int keysoct1qwerty[]={'q','2','w','3','e','r','5','t','6','y','7','u','i','9','o','0','p','[','=',']','\\',FL_Enter,0}; +static const int keysoct2qwerty[]={'z','s','x','d','c','v','g','b','h','n','j','m',',','l','.',';','/',0}; +static const int keysoct1dw[]={'\'','2',',','3','.','p','5','y','6','f','7','g','c','9','r','0','l','/',']','=','\\',FL_Enter,0}; +static const int keysoct2dw[]={';','o','q','e','j','k','i','x','d','b','h','m','w','n','v','s','z',0}; +static const int keysoct1qwertz[]={'q','2','w','3','e','r','5','t','6','z','7','u','i','9','o','0','p',252,'\'','+','\\',FL_Enter,0}; +static const int keysoct2qwertz[]={'y','s','x','d','c','v','g','b','h','n','j','m',',','l','.',246,'-',0}; + +VirKeys::VirKeys(int x,int y, int w, int h, const char *label):Fl_Box(x,y,w,h,label) { + master=NULL; +} + +void VirKeys::init(Master *master_) { + master=master_; +for (int i=0;i=0){//white keys + if (pressed[i]==0) fl_color(250,240,230); + else fl_color(FL_BLUE); + fl_rectf(ox+(kv+7*noct)*SIZE_WHITE+3,oy+ly*3/5+2, + SIZE_WHITE-4,ly*2/5-3); + } else {//black keys + kv=keyspos[(i+1)%12]; + if (pressed[i]==0) fl_color(FL_BLACK); + else fl_color(FL_BLUE); + fl_rectf(ox+(kv+7*noct)*SIZE_WHITE-SIZE_BLACK/2+2,oy+2, + SIZE_BLACK-3,ly*3/5-5); + }; +}; +} + +int VirKeys::handle(int event) { + int i; +int ly=h(); +int x_=Fl::event_x()-x(); +int y_=Fl::event_y()-y(); +if ( (x_<0)&&(x_>w()) && (y_<0)&&(y_>h())){ + return(0); +}; + + +if ((event==FL_PUSH)||(event==FL_DRAG)||(event==FL_RELEASE)){ + int kpos=-1; + + if (y_>ly*3/5){//white keys + int pos=x_/SIZE_WHITE; + if (pos<0) return(1); + for (i=0;i<12;i++) { + if (pos%7==keyspos[i]) { + kpos=pos/7*12+i; + break; + }; + }; + } else {//black keys + int pos=(x_+SIZE_WHITE/2)/SIZE_WHITE; + if (pos<0) return(1); + for (i=1;i<12;i++) { + if (pos%7==-keyspos[i]) { + kpos=pos/7*12+i; + break; + }; + }; + }; + + if (((event==FL_PUSH)||(event==FL_DRAG))&& + (Fl::event_shift()==0)) { + presskey(kpos,1,1); + }; + + if ((event==FL_PUSH)&&(Fl::event_shift()!=0)) { + if (pressed[kpos]==0) presskey(kpos,0,1); + else relasekey(kpos,1); + }; + if ((event==FL_RELEASE)&&(Fl::event_shift()==0)) + relaseallkeys(1); + take_focus(); +}; + + +const int *keysoct1=keysoct1qwerty; +const int *keysoct2=keysoct2qwerty; + +if (config.cfg.VirKeybLayout==2) { + keysoct1=keysoct1dw; + keysoct2=keysoct2dw; +}else if (config.cfg.VirKeybLayout==3) { + keysoct1=keysoct1qwertz; + keysoct2=keysoct2qwertz; +}; + +if ((event==FL_KEYDOWN)||(event==FL_KEYUP)){ + int key=Fl::event_key(); + int kpos=-1; + for (i=0;keysoct1[i]!=0;i++) if (key==keysoct1[i]) kpos=i+12*keyoct1; + for (i=0;keysoct2[i]!=0;i++) if (key==keysoct2[i]) kpos=i+12*keyoct2; + + + + + if (kpos==-1) return(0); + if ((event==FL_KEYUP) && (Fl::event_key(key)==0) && (Fl::get_key(key)!=0)) return(0); + if (event==FL_KEYDOWN) presskey(kpos,0,2); + else relasekey(kpos,2); +}; + +return(1); +} + +void VirKeys::presskey(int nk,int exclusive,int type) { + if (nk>=N_OCT*12) return; +if ((nk<0)&&(exclusive==0)) { + relaseallkeys(type); + return; +}; +if (pressed[nk]!=0) return;//the key is already pressed + +if (exclusive!=0) relaseallkeys(type); +pressed[nk]=type; + +damage(1); +float vel=midivel; +if (rndvelocity!=0){ + vel=midivel*(127.0-rndvelocity)/127.0+RND*rndvelocity; +}; + +pthread_mutex_lock(&master->mutex); + master->NoteOn(midich,nk+midioct*12,(int)vel); +pthread_mutex_unlock(&master->mutex); +} + +void VirKeys::relasekey(int nk,int type) { + if ((nk<0)||(nk>=N_OCT*12)) return; +if (pressed[nk]==0) return;//the key is not pressed +if ((type!=0)&&(pressed[nk]!=type)) return; + +pressed[nk]=0; + + +damage(1); + +pthread_mutex_lock(&master->mutex); + master->NoteOff(midich,nk+12*midioct); +pthread_mutex_unlock(&master->mutex); +} + +void VirKeys::relaseallkeys(int type) { + for (int i=0;ihide(); +} +void VirKeyboard::cb_virkeyboardwindow(Fl_Double_Window* o, void* v) { + ((VirKeyboard*)(o->user_data()))->cb_virkeyboardwindow_i(o,v); +} + +void VirKeyboard::cb_qwer_i(Fl_Counter* o, void*) { + relaseallkeys(); +virkeys->keyoct1=(int) o->value(); +virkeys->take_focus(); +} +void VirKeyboard::cb_qwer(Fl_Counter* o, void* v) { + ((VirKeyboard*)(o->parent()->user_data()))->cb_qwer_i(o,v); +} + +void VirKeyboard::cb_zxcv_i(Fl_Counter* o, void*) { + relaseallkeys(); +virkeys->keyoct2=(int) o->value(); +virkeys->take_focus(); +} +void VirKeyboard::cb_zxcv(Fl_Counter* o, void* v) { + ((VirKeyboard*)(o->parent()->user_data()))->cb_zxcv_i(o,v); +} + +void VirKeyboard::cb_Vel_i(Fl_Value_Slider* o, void*) { + virkeys->midivel=(int) o->value(); +virkeys->take_focus(); +} +void VirKeyboard::cb_Vel(Fl_Value_Slider* o, void* v) { + ((VirKeyboard*)(o->parent()->user_data()))->cb_Vel_i(o,v); +} + +void VirKeyboard::cb_Oct_i(Fl_Counter* o, void*) { + relaseallkeys(); +virkeys->midioct=(int) o->value(); +virkeys->take_focus(); +} +void VirKeyboard::cb_Oct(Fl_Counter* o, void* v) { + ((VirKeyboard*)(o->parent()->user_data()))->cb_Oct_i(o,v); +} + +void VirKeyboard::cb_Close_i(Fl_Button*, void*) { + relaseallkeys(); +virkeyboardwindow->hide(); +} +void VirKeyboard::cb_Close(Fl_Button* o, void* v) { + ((VirKeyboard*)(o->parent()->user_data()))->cb_Close_i(o,v); +} + +void VirKeyboard::cb_Cval_i(Fl_Value_Slider* o, void*) { + int ctl=midictl; + +pthread_mutex_lock(&master->mutex); + master->SetController(virkeys->midich,ctl,(int) o->value()); +pthread_mutex_unlock(&master->mutex); +virkeys->take_focus(); +} +void VirKeyboard::cb_Cval(Fl_Value_Slider* o, void* v) { + ((VirKeyboard*)(o->parent()->user_data()))->cb_Cval_i(o,v); +} + +void VirKeyboard::cb_Controller_i(Fl_Choice* o, void*) { + switch((int) o->value()+1){ + case 1: midictl=C_modwheel; break; + case 2: midictl=C_volume; break; + case 3: midictl=C_panning; break; + case 4: midictl=C_expression; break; + case 5: midictl=C_sustain; break; + case 6: midictl=C_portamento; break; + case 7: midictl=C_filterq; break; + case 8: midictl=C_filtercutoff; break; + case 9: midictl=C_bandwidth; break; + case 10: midictl=C_fmamp; break; + case 11: midictl=C_resonance_center; break; + case 12: midictl=C_resonance_bandwidth; break; + default: midictl=C_NULL; break; + +}; + + + +virkeys->take_focus(); +} +void VirKeyboard::cb_Controller(Fl_Choice* o, void* v) { + ((VirKeyboard*)(o->parent()->user_data()))->cb_Controller_i(o,v); +} + +Fl_Menu_Item VirKeyboard::menu_Controller[] = { + {"01: Mod.Wheel", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"07: Volume", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"10: Panning", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"11: Expression", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"64: Sustain", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"65: Portamento", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"71: Filter Q", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"74: Filter Freq.", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"75: Bandwidth", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"76: FM Gain", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"77: Res. c. freq", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {"78: Res. bw.", 0, 0, 0, 0, FL_NORMAL_LABEL, 1, 10, 0}, + {0,0,0,0,0,0,0,0,0} +}; + +void VirKeyboard::cb_pitchwheelroller_i(Fl_Roller* o, void*) { + pthread_mutex_lock(&master->mutex); + master->SetController(virkeys->midich,C_pitchwheel,-(int) o->value()); +pthread_mutex_unlock(&master->mutex); +virkeys->take_focus(); +} +void VirKeyboard::cb_pitchwheelroller(Fl_Roller* o, void* v) { + ((VirKeyboard*)(o->parent()->user_data()))->cb_pitchwheelroller_i(o,v); +} + +void VirKeyboard::cb_R_i(Fl_Button*, void*) { + pitchwheelroller->value(0); +pitchwheelroller->do_callback(); +} +void VirKeyboard::cb_R(Fl_Button* o, void* v) { + ((VirKeyboard*)(o->parent()->user_data()))->cb_R_i(o,v); +} + +void VirKeyboard::cb_Vrnd_i(WidgetPDial* o, void*) { + virkeys->rndvelocity=(int) o->value(); +} +void VirKeyboard::cb_Vrnd(WidgetPDial* o, void* v) { + ((VirKeyboard*)(o->parent()->user_data()))->cb_Vrnd_i(o,v); +} + +void VirKeyboard::cb_partrcv_i(Fl_Choice* o, void*) { + relaseallkeys(); +virkeys->midich=(int) o->value(); +virkeys->take_focus(); +} +void VirKeyboard::cb_partrcv(Fl_Choice* o, void* v) { + ((VirKeyboard*)(o->parent()->user_data()))->cb_partrcv_i(o,v); +} + +Fl_Double_Window* VirKeyboard::make_window() { + { virkeyboardwindow = new Fl_Double_Window(650, 130, "Virtual Keyboard - ZynAddSubFX"); + virkeyboardwindow->callback((Fl_Callback*)cb_virkeyboardwindow, (void*)(this)); + { VirKeys* o = virkeys = new VirKeys(10, 10, 590, 80, "Keyboard"); + virkeys->box(FL_FLAT_BOX); + virkeys->color((Fl_Color)17); + virkeys->selection_color(FL_BACKGROUND_COLOR); + virkeys->labeltype(FL_NORMAL_LABEL); + virkeys->labelfont(0); + virkeys->labelsize(14); + virkeys->labelcolor(FL_FOREGROUND_COLOR); + virkeys->align(FL_ALIGN_CENTER); + virkeys->when(FL_WHEN_RELEASE); + o->init(master); + } // VirKeys* virkeys + { Fl_Counter* o = new Fl_Counter(380, 95, 45, 15, "\"qwer..\" Oct"); + o->tooltip("keys \"q2w3er5t6y...\" octave"); + o->type(1); + o->labelsize(10); + o->minimum(0); + o->maximum(5); + o->step(1); + o->textfont(1); + o->textsize(10); + o->callback((Fl_Callback*)cb_qwer); + o->align(FL_ALIGN_LEFT); + o->when(FL_WHEN_RELEASE_ALWAYS); + o->value(virkeys->keyoct1); + } // Fl_Counter* o + { Fl_Counter* o = new Fl_Counter(380, 110, 45, 15, "\"zxcv..\" Oct"); + o->tooltip("keys \"zsxdcvgbh...\" octave"); + o->type(1); + o->labelsize(10); + o->minimum(0); + o->maximum(5); + o->step(1); + o->textfont(1); + o->textsize(10); + o->callback((Fl_Callback*)cb_zxcv); + o->align(FL_ALIGN_LEFT); + o->when(FL_WHEN_RELEASE_ALWAYS); + o->value(virkeys->keyoct2); + } // Fl_Counter* o + { Fl_Value_Slider* o = new Fl_Value_Slider(95, 105, 100, 15, "Vel"); + o->tooltip("Velocity"); + o->type(5); + o->box(FL_FLAT_BOX); + o->labelsize(10); + o->minimum(1); + o->maximum(127); + o->step(1); + o->callback((Fl_Callback*)cb_Vel); + o->align(FL_ALIGN_TOP_LEFT); + o->value(virkeys->midivel); + } // Fl_Value_Slider* o + { Fl_Counter* o = new Fl_Counter(255, 100, 55, 20, "Oct."); + o->tooltip("Midi Octave"); + o->type(1); + o->labelsize(11); + o->minimum(0); + o->maximum(5); + o->step(1); + o->textfont(1); + o->textsize(11); + o->callback((Fl_Callback*)cb_Oct); + o->align(FL_ALIGN_LEFT); + o->when(FL_WHEN_RELEASE_ALWAYS); + o->value(virkeys->midioct); + } // Fl_Counter* o + { Fl_Button* o = new Fl_Button(545, 105, 55, 20, "Close"); + o->box(FL_THIN_UP_BOX); + o->callback((Fl_Callback*)cb_Close); + } // Fl_Button* o + { Fl_Value_Slider* o = new Fl_Value_Slider(605, 10, 15, 115, "Cval"); + o->tooltip("Controller value"); + o->type(2); + o->box(FL_ENGRAVED_BOX); + o->selection_color((Fl_Color)229); + o->labelsize(8); + o->minimum(127); + o->maximum(0); + o->step(1); + o->value(64); + o->textsize(7); + o->callback((Fl_Callback*)cb_Cval); + o->align(FL_ALIGN_TOP_LEFT); + } // Fl_Value_Slider* o + { Fl_Choice* o = new Fl_Choice(435, 105, 100, 15, "Controller"); + o->down_box(FL_BORDER_BOX); + o->labelsize(10); + o->textfont(1); + o->textsize(10); + o->callback((Fl_Callback*)cb_Controller); + o->align(FL_ALIGN_TOP_LEFT); + o->when(FL_WHEN_RELEASE_ALWAYS); + o->menu(menu_Controller); + midictl=C_filtercutoff;o->value(7); + } // Fl_Choice* o + { pitchwheelroller = new Fl_Roller(625, 10, 20, 95, "Pwh"); + pitchwheelroller->tooltip("Pitch Wheel"); + pitchwheelroller->box(FL_PLASTIC_UP_BOX); + pitchwheelroller->labelsize(8); + pitchwheelroller->minimum(-8192); + pitchwheelroller->maximum(8192); + pitchwheelroller->step(64); + pitchwheelroller->callback((Fl_Callback*)cb_pitchwheelroller); + pitchwheelroller->align(FL_ALIGN_TOP); + pitchwheelroller->when(3); + } // Fl_Roller* pitchwheelroller + { Fl_Button* o = new Fl_Button(625, 110, 20, 15, "R"); + o->tooltip("Reset Pitch Bend"); + o->box(FL_THIN_UP_BOX); + o->labelfont(1); + o->callback((Fl_Callback*)cb_R); + } // Fl_Button* o + { WidgetPDial* o = new WidgetPDial(205, 105, 20, 20, "Vrnd"); + o->tooltip("Velocity Randomness"); + o->box(FL_ROUND_UP_BOX); + o->color(FL_BACKGROUND_COLOR); + o->selection_color(FL_INACTIVE_COLOR); + o->labeltype(FL_NORMAL_LABEL); + o->labelfont(0); + o->labelsize(10); + o->labelcolor(FL_FOREGROUND_COLOR); + o->maximum(127); + o->step(1); + o->callback((Fl_Callback*)cb_Vrnd); + o->align(129); + o->when(FL_WHEN_CHANGED); + o->value(virkeys->rndvelocity); + } // WidgetPDial* o + { Fl_Choice* o = partrcv = new Fl_Choice(20, 105, 65, 20, "MIDI Ch."); + partrcv->tooltip("Send to Midi Channel"); + partrcv->down_box(FL_BORDER_BOX); + partrcv->labelsize(10); + partrcv->textfont(1); + partrcv->textsize(10); + partrcv->callback((Fl_Callback*)cb_partrcv); + partrcv->align(FL_ALIGN_TOP_LEFT); + char nrstr[10]; for(int i=0;iadd(nrstr); else o->add("Drum10");}; + o->value(virkeys->midich); + } // Fl_Choice* partrcv + virkeyboardwindow->end(); + } // Fl_Double_Window* virkeyboardwindow + return virkeyboardwindow; +} + +VirKeyboard::VirKeyboard(Master *master_) { + master=master_; +midictl=75; +make_window(); +} + +void VirKeyboard::show() { + virkeyboardwindow->show(); +} + +void VirKeyboard::relaseallkeys() { + virkeys->relaseallkeys(0); +} diff --git a/plugins/zynaddsubfx/src/UI/VirKeyboard.fl b/plugins/zynaddsubfx/src/UI/VirKeyboard.fl new file mode 100644 index 000000000..0b1b8c575 --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/VirKeyboard.fl @@ -0,0 +1,412 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0107 +header_name {.h} +code_name {.cc} +decl {//Copyright (c) 2002-2005 Nasca Octavian Paul} {} + +decl {//License: GNU GPL version 2 or later} {} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include "../globals.h"} {public +} + +decl {\#include "../Misc/Master.h"} {public +} + +decl {\#include "../Input/MidiIn.h"} {public +} + +decl {\#include "WidgetPDial.h"} {public +} + +decl {const int keyspos[12]={0,-1,1,-2,2,3,-4,4,-5,5,-6,6};} {} + +decl {const int keysoct1qwerty[]={'q','2','w','3','e','r','5','t','6','y','7','u','i','9','o','0','p','[','=',']','\\\\',FL_Enter,0};} {} + +decl {const int keysoct2qwerty[]={'z','s','x','d','c','v','g','b','h','n','j','m',',','l','.',';','/',0};} {} + +decl {const int keysoct1dw[]={'\\'','2',',','3','.','p','5','y','6','f','7','g','c','9','r','0','l','/',']','=','\\\\',FL_Enter,0};} {} + +decl {const int keysoct2dw[]={';','o','q','e','j','k','i','x','d','b','h','m','w','n','v','s','z',0};} {} + +decl {const int keysoct1qwertz[]={'q','2','w','3','e','r','5','t','6','z','7','u','i','9','o','0','p',252,'\\\'','+','\\\\',FL_Enter,0};} {} + +decl {const int keysoct2qwertz[]={'y','s','x','d','c','v','g','b','h','n','j','m',',','l','.',246,'-',0};} {} + +class VirKeys {open : {public Fl_Box} +} { + decl {static const int N_OCT=6;} {} + decl {static const int SIZE_WHITE=14;} {} + decl {static const int SIZE_BLACK=8;} {} + Function {VirKeys(int x,int y, int w, int h, const char *label=0):Fl_Box(x,y,w,h,label)} {} { + code {master=NULL;} {} + } + Function {init(Master *master_)} {} { + code {master=master_; +for (int i=0;i=0){//white keys + if (pressed[i]==0) fl_color(250,240,230); + else fl_color(FL_BLUE); + fl_rectf(ox+(kv+7*noct)*SIZE_WHITE+3,oy+ly*3/5+2, + SIZE_WHITE-4,ly*2/5-3); + } else {//black keys + kv=keyspos[(i+1)%12]; + if (pressed[i]==0) fl_color(FL_BLACK); + else fl_color(FL_BLUE); + fl_rectf(ox+(kv+7*noct)*SIZE_WHITE-SIZE_BLACK/2+2,oy+2, + SIZE_BLACK-3,ly*3/5-5); + }; +};} {} + } + Function {handle(int event)} {return_type int + } { + code {int i; +int ly=h(); +int x_=Fl::event_x()-x(); +int y_=Fl::event_y()-y(); +if ( (x_<0)&&(x_>w()) && (y_<0)&&(y_>h())){ + return(0); +}; + + +if ((event==FL_PUSH)||(event==FL_DRAG)||(event==FL_RELEASE)){ + int kpos=-1; + + if (y_>ly*3/5){//white keys + int pos=x_/SIZE_WHITE; + if (pos<0) return(1); + for (i=0;i<12;i++) { + if (pos%7==keyspos[i]) { + kpos=pos/7*12+i; + break; + }; + }; + } else {//black keys + int pos=(x_+SIZE_WHITE/2)/SIZE_WHITE; + if (pos<0) return(1); + for (i=1;i<12;i++) { + if (pos%7==-keyspos[i]) { + kpos=pos/7*12+i; + break; + }; + }; + }; + + if (((event==FL_PUSH)||(event==FL_DRAG))&& + (Fl::event_shift()==0)) { + presskey(kpos,1,1); + }; + + if ((event==FL_PUSH)&&(Fl::event_shift()!=0)) { + if (pressed[kpos]==0) presskey(kpos,0,1); + else relasekey(kpos,1); + }; + if ((event==FL_RELEASE)&&(Fl::event_shift()==0)) + relaseallkeys(1); + take_focus(); +}; + + +const int *keysoct1=keysoct1qwerty; +const int *keysoct2=keysoct2qwerty; + +if (config.cfg.VirKeybLayout==2) { + keysoct1=keysoct1dw; + keysoct2=keysoct2dw; +}else if (config.cfg.VirKeybLayout==3) { + keysoct1=keysoct1qwertz; + keysoct2=keysoct2qwertz; +}; + +if ((event==FL_KEYDOWN)||(event==FL_KEYUP)){ + int key=Fl::event_key(); + int kpos=-1; + for (i=0;keysoct1[i]!=0;i++) if (key==keysoct1[i]) kpos=i+12*keyoct1; + for (i=0;keysoct2[i]!=0;i++) if (key==keysoct2[i]) kpos=i+12*keyoct2; + + + + + if (kpos==-1) return(0); + if ((event==FL_KEYUP) && (Fl::event_key(key)==0) && (Fl::get_key(key)!=0)) return(0); + if (event==FL_KEYDOWN) presskey(kpos,0,2); + else relasekey(kpos,2); +}; + +return(1);} {} + } + Function {presskey(int nk,int exclusive,int type)} {selected + } { + code {if (nk>=N_OCT*12) return; +if ((nk<0)&&(exclusive==0)) { + relaseallkeys(type); + return; +}; +if (pressed[nk]!=0) return;//the key is already pressed + +if (exclusive!=0) relaseallkeys(type); +pressed[nk]=type; + +damage(1); +float vel=midivel; +if (rndvelocity!=0){ + vel=midivel*(127.0-rndvelocity)/127.0+RND*rndvelocity; +}; + +pthread_mutex_lock(&master->mutex); + master->NoteOn(midich,nk+midioct*12,(int)vel); +pthread_mutex_unlock(&master->mutex);} {} + } + Function {relasekey(int nk,int type)} {} { + code {if ((nk<0)||(nk>=N_OCT*12)) return; +if (pressed[nk]==0) return;//the key is not pressed +if ((type!=0)&&(pressed[nk]!=type)) return; + +pressed[nk]=0; + + +damage(1); + +pthread_mutex_lock(&master->mutex); + master->NoteOff(midich,nk+12*midioct); +pthread_mutex_unlock(&master->mutex);} {} + } + Function {relaseallkeys(int type)} {} { + code {for (int i=0;ihide();} + xywh {95 563 650 130} type Double hide + } { + Fl_Box virkeys { + label Keyboard + xywh {10 10 590 80} box FLAT_BOX color 17 + code0 {o->init(master);} + class VirKeys + } + Fl_Counter {} { + label {"qwer.." Oct} + callback {relaseallkeys(); +virkeys->keyoct1=(int) o->value(); +virkeys->take_focus();} + tooltip {keys "q2w3er5t6y..." octave} xywh {380 95 45 15} type Simple labelsize 10 align 4 when 6 minimum 0 maximum 5 step 1 textfont 1 textsize 10 + code0 {o->value(virkeys->keyoct1);} + } + Fl_Counter {} { + label {"zxcv.." Oct} + callback {relaseallkeys(); +virkeys->keyoct2=(int) o->value(); +virkeys->take_focus();} + tooltip {keys "zsxdcvgbh..." octave} xywh {380 110 45 15} type Simple labelsize 10 align 4 when 6 minimum 0 maximum 5 step 1 textfont 1 textsize 10 + code0 {o->value(virkeys->keyoct2);} + } + Fl_Value_Slider {} { + label Vel + callback {virkeys->midivel=(int) o->value(); +virkeys->take_focus();} + tooltip Velocity xywh {95 105 100 15} type {Horz Knob} box FLAT_BOX labelsize 10 align 5 minimum 1 maximum 127 step 1 + code0 {o->value(virkeys->midivel);} + } + Fl_Counter {} { + label {Oct.} + callback {relaseallkeys(); +virkeys->midioct=(int) o->value(); +virkeys->take_focus();} + tooltip {Midi Octave} xywh {255 100 55 20} type Simple labelsize 11 align 4 when 6 minimum 0 maximum 5 step 1 textfont 1 textsize 11 + code0 {o->value(virkeys->midioct);} + } + Fl_Button {} { + label Close + callback {relaseallkeys(); +virkeyboardwindow->hide();} + xywh {545 105 55 20} box THIN_UP_BOX + } + Fl_Value_Slider {} { + label Cval + callback {int ctl=midictl; + +pthread_mutex_lock(&master->mutex); + master->SetController(virkeys->midich,ctl,(int) o->value()); +pthread_mutex_unlock(&master->mutex); +virkeys->take_focus();} + tooltip {Controller value} xywh {605 10 15 115} type {Vert Fill} box ENGRAVED_BOX selection_color 229 labelsize 8 align 5 minimum 127 maximum 0 step 1 value 64 textsize 7 + } + Fl_Choice {} { + label Controller + callback {switch((int) o->value()+1){ + case 1: midictl=C_modwheel; break; + case 2: midictl=C_volume; break; + case 3: midictl=C_panning; break; + case 4: midictl=C_expression; break; + case 5: midictl=C_sustain; break; + case 6: midictl=C_portamento; break; + case 7: midictl=C_filterq; break; + case 8: midictl=C_filtercutoff; break; + case 9: midictl=C_bandwidth; break; + case 10: midictl=C_fmamp; break; + case 11: midictl=C_resonance_center; break; + case 12: midictl=C_resonance_bandwidth; break; + default: midictl=C_NULL; break; + +}; + + + +virkeys->take_focus();} + xywh {435 105 100 15} down_box BORDER_BOX labelsize 10 align 5 when 6 textfont 1 textsize 10 + code0 {midictl=C_filtercutoff;o->value(7);} + } { + MenuItem {} { + label {01: Mod.Wheel} + xywh {0 0 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label {07: Volume} + xywh {10 10 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label {10: Panning} + xywh {20 20 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label {11: Expression} + xywh {30 30 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label {64: Sustain} + xywh {40 40 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label {65: Portamento} + xywh {50 50 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label {71: Filter Q} + xywh {60 60 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label {74: Filter Freq.} + xywh {70 70 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label {75: Bandwidth} + xywh {80 80 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label {76: FM Gain} + xywh {90 90 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label {77: Res. c. freq} + xywh {100 100 100 20} labelfont 1 labelsize 10 + } + MenuItem {} { + label {78: Res. bw.} + xywh {110 110 100 20} labelfont 1 labelsize 10 + } + } + Fl_Roller pitchwheelroller { + label Pwh + callback {pthread_mutex_lock(&master->mutex); + master->SetController(virkeys->midich,C_pitchwheel,-(int) o->value()); +pthread_mutex_unlock(&master->mutex); +virkeys->take_focus();} + tooltip {Pitch Wheel} xywh {625 10 20 95} box PLASTIC_UP_BOX labelsize 8 align 1 when 3 minimum -8192 maximum 8192 step 64 + } + Fl_Button {} { + label R + callback {pitchwheelroller->value(0); +pitchwheelroller->do_callback();} + tooltip {Reset Pitch Bend} xywh {625 110 20 15} box THIN_UP_BOX labelfont 1 + } + Fl_Dial {} { + label Vrnd + callback {virkeys->rndvelocity=(int) o->value();} + tooltip {Velocity Randomness} xywh {205 105 20 20} box ROUND_UP_BOX labelsize 10 align 129 maximum 127 step 1 + code0 {o->value(virkeys->rndvelocity);} + class WidgetPDial + } + Fl_Choice partrcv { + label {MIDI Ch.} + callback {relaseallkeys(); +virkeys->midich=(int) o->value(); +virkeys->take_focus();} open + tooltip {Send to Midi Channel} xywh {20 105 65 20} down_box BORDER_BOX labelsize 10 align 5 textfont 1 textsize 10 + code0 {char nrstr[10]; for(int i=0;iadd(nrstr); else o->add("Drum10");};} + code1 {o->value(virkeys->midich);} + } {} + } + } + Function {VirKeyboard(Master *master_)} {} { + code {master=master_; +midictl=75; +make_window();} {} + } + Function {show()} {} { + code {virkeyboardwindow->show();} {} + } + Function {relaseallkeys()} {} { + code {virkeys->relaseallkeys(0);} {} + } + decl {Master *master;} {} + decl {int midictl;} {} +} diff --git a/plugins/zynaddsubfx/src/UI/VirKeyboard.h b/plugins/zynaddsubfx/src/UI/VirKeyboard.h new file mode 100644 index 000000000..e57d3dcca --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/VirKeyboard.h @@ -0,0 +1,89 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0109 + +#ifndef VirKeyboard_h +#define VirKeyboard_h +#include +#include +#include +#include +#include "../globals.h" +#include "../Misc/Master.h" +#include "../Input/MidiIn.h" +#include "WidgetPDial.h" + +class VirKeys : public Fl_Box { + static const int N_OCT=6; + static const int SIZE_WHITE=14; + static const int SIZE_BLACK=8; +public: + VirKeys(int x,int y, int w, int h, const char *label=0); + void init(Master *master_); + void draw(); + int handle(int event); + void presskey(int nk,int exclusive,int type); + void relasekey(int nk,int type); + void relaseallkeys(int type); +private: + Master *master; + int pressed[N_OCT*12+1]; +public: + unsigned char midich; + unsigned char midivel; + char midioct,keyoct1,keyoct2; + unsigned char rndvelocity; +}; +#include +#include +#include +#include +#include +#include + +class VirKeyboard { +public: + Fl_Double_Window* make_window(); + Fl_Double_Window *virkeyboardwindow; +private: + void cb_virkeyboardwindow_i(Fl_Double_Window*, void*); + static void cb_virkeyboardwindow(Fl_Double_Window*, void*); +public: + VirKeys *virkeys; +private: + void cb_qwer_i(Fl_Counter*, void*); + static void cb_qwer(Fl_Counter*, void*); + void cb_zxcv_i(Fl_Counter*, void*); + static void cb_zxcv(Fl_Counter*, void*); + void cb_Vel_i(Fl_Value_Slider*, void*); + static void cb_Vel(Fl_Value_Slider*, void*); + void cb_Oct_i(Fl_Counter*, void*); + static void cb_Oct(Fl_Counter*, void*); + void cb_Close_i(Fl_Button*, void*); + static void cb_Close(Fl_Button*, void*); + void cb_Cval_i(Fl_Value_Slider*, void*); + static void cb_Cval(Fl_Value_Slider*, void*); + void cb_Controller_i(Fl_Choice*, void*); + static void cb_Controller(Fl_Choice*, void*); + static Fl_Menu_Item menu_Controller[]; +public: + Fl_Roller *pitchwheelroller; +private: + void cb_pitchwheelroller_i(Fl_Roller*, void*); + static void cb_pitchwheelroller(Fl_Roller*, void*); + void cb_R_i(Fl_Button*, void*); + static void cb_R(Fl_Button*, void*); + void cb_Vrnd_i(WidgetPDial*, void*); + static void cb_Vrnd(WidgetPDial*, void*); +public: + Fl_Choice *partrcv; +private: + void cb_partrcv_i(Fl_Choice*, void*); + static void cb_partrcv(Fl_Choice*, void*); +public: + VirKeyboard(Master *master_); + void show(); + void relaseallkeys(); +private: + Master *master; + int midictl; +}; +#endif diff --git a/plugins/zynaddsubfx/src/UI/WidgetPDial.cc b/plugins/zynaddsubfx/src/UI/WidgetPDial.cc new file mode 100644 index 000000000..4e2b96d06 --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/WidgetPDial.cc @@ -0,0 +1,214 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0109 + +#include "WidgetPDial.h" +//Copyright (c) 2003-2005 Nasca Octavian Paul +//License: GNU GPL version 2 or later + +TipWin::TipWin():Fl_Menu_Window(1,1) { + strcpy(tip, "X.XX"); +set_override(); +end(); +} + +void TipWin::draw() { + draw_box(FL_BORDER_BOX, 0, 0, w(), h(), Fl_Color(175)); + fl_color(FL_BLACK); + fl_font(labelfont(), labelsize()); + if(textmode) + fl_draw(text, 3, 3, w()-6, h()-6, Fl_Align(FL_ALIGN_LEFT|FL_ALIGN_WRAP)); + else + fl_draw(tip, 3, 3, w()-6, h()-6, Fl_Align(FL_ALIGN_LEFT|FL_ALIGN_WRAP)); +} + +void TipWin::value(float f) { + sprintf(tip, "%.2f", f); +textmode=false; + // Recalc size of window + fl_font(labelfont(), labelsize()); + int W = w(), H = h(); + fl_measure(tip, W, H, 0); + W += 8; + size(W, H); + redraw(); +} + +void TipWin::setText(const char * c) { + strcpy(text,c); +textmode=true; + // Recalc size of window + fl_font(labelfont(), labelsize()); + int W = w(), H = h(); + fl_measure(text, W, H, 0); + W += 8; + size(W, H); + redraw(); +} + +void TipWin::setTextmode() { + textmode=true; + // Recalc size of window + fl_font(labelfont(), labelsize()); + int W = w(), H = h(); + fl_measure(text, W, H, 0); + W += 8; + size(W, H); + redraw(); +} + +WidgetPDial::WidgetPDial(int x,int y, int w, int h, const char *label):Fl_Dial(x,y,w,h,label) { + callback(value_cb, (void*)this); +Fl_Group *save = Fl_Group::current(); +tipwin = new TipWin(); +tipwin->hide(); +Fl_Group::current(save); +oldvalue=0.0; +pos=false; +textset=false; +} + +WidgetPDial::~WidgetPDial() { + delete tipwin; +} + +int WidgetPDial::handle(int event) { + double dragsize,v,min=minimum(),max=maximum(); +int my; + +switch (event){ +case FL_PUSH: + oldvalue=value(); +case FL_DRAG: + if(!pos){ + tipwin->position(Fl::event_x_root(), Fl::event_y_root()+20); + pos=true; + } + tipwin->value(value()); + tipwin->show(); + my=-(Fl::event_y()-y()-h()/2); + + dragsize=200.0; + if (Fl::event_state(FL_BUTTON1)==0) dragsize*=10; + v=oldvalue+my/dragsize*(max-min); + if (vmax) v=max; + + //printf("%d %g %g\n",my,v,oldvalue); + value(v); + value_damage(); + if (this->when()!=0) do_callback(); + return(1); + break; +case FL_ENTER: + if(textset){ + if(!pos){ + tipwin->position(Fl::event_x_root(), Fl::event_y_root()+20); + pos=true; + } + tipwin->setTextmode(); + tipwin->show(); + return(1);} + break; +case FL_HIDE: +case FL_LEAVE: + tipwin->hide(); + pos=false; + break; +case FL_RELEASE: + tipwin->hide(); + pos=false; + if (this->when()==0) do_callback(); + return(1); + break; +}; +return(0); +} + +void WidgetPDial::drawgradient(int cx,int cy,int sx,double m1,double m2) { + for (int i=(int)(m1*sx);i<(int)(m2*sx);i++){ + double tmp=1.0-pow(i*1.0/sx,2.0); + pdialcolor(140+(int) (tmp*90),140+(int)(tmp*90),140+(int) (tmp*100)); + fl_arc(cx+sx/2-i/2,cy+sx/2-i/2,i,i,0,360); +}; +} + +void WidgetPDial::draw() { + int cx=x(),cy=y(),sx=w(),sy=h(); + + +//clears the button face +pdialcolor(190,190,200); +fl_pie(cx-1,cy-1,sx+2,sy+2,0,360); + +//Draws the button face (gradinet) +drawgradient(cx,cy,sx,0.5,1.0); + +double val=(value()-minimum())/(maximum()-minimum()); + +//draws the scale +pdialcolor(220,220,250); +double a1=angle1(),a2=angle2(); +for (int i=0;i<12;i++){ + double a=-i/12.0*360.0-val*(a2-a1)-a1; + fl_pie(cx,cy,sx,sy,a+270-3,a+3+270); +}; + +drawgradient(cx,cy,sx,0.0,0.75); + +//draws the value +double a=-(a2-a1)*val-a1; + + + + + +//draws the max and min points +pdialcolor(0,100,200); +int xp=(int)(cx+sx/2.0+sx/2.0*sin(angle1()/180.0*3.141592)); +int yp=(int)(cy+sy/2.0+sy/2.0*cos(angle1()/180.0*3.141592)); +fl_pie(xp-2,yp-2,4,4,0,360); + +xp=(int)(cx+sx/2.0+sx/2.0*sin(angle2()/180.0*3.141592)); +yp=(int)(cy+sy/2.0+sy/2.0*cos(angle2()/180.0*3.141592)); +fl_pie(xp-2,yp-2,4,4,0,360); + + + + + +fl_push_matrix(); + + fl_translate(cx+sx/2,cy+sy/2); + fl_rotate(a-90.0); + + fl_translate(sx/2,0); + + + fl_begin_polygon(); + pdialcolor(0,0,0); + fl_vertex(-10,-4); + fl_vertex(-10,4); + fl_vertex(0,0); + fl_end_polygon(); + + +fl_pop_matrix(); +} + +void WidgetPDial::pdialcolor(int r,int g,int b) { + if (active_r()) fl_color(r,g,b); + else fl_color(160-(160-r)/3,160-(160-b)/3,160-(160-b)/3); +} + +void WidgetPDial::value_cb2() { + tipwin->value(value()); +} + +void WidgetPDial::value_cb(Fl_Widget*, void*data) { + WidgetPDial *val = (WidgetPDial*)data; + val->value_cb2(); +} + +void WidgetPDial::tooltip(const char * c) { + tipwin->setText(c); +textset=true; +} diff --git a/plugins/zynaddsubfx/src/UI/WidgetPDial.fl b/plugins/zynaddsubfx/src/UI/WidgetPDial.fl new file mode 100644 index 000000000..0fed5b571 --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/WidgetPDial.fl @@ -0,0 +1,251 @@ +# data file for the Fltk User Interface Designer (fluid) +version 1.0109 +header_name {.h} +code_name {.cc} +decl {//Copyright (c) 2003-2005 Nasca Octavian Paul} {} + +decl {//License: GNU GPL version 2 or later} {} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include } {public +} + +decl {\#include } {public +} + +class TipWin {: {public Fl_Menu_Window} +} { + Function {TipWin():Fl_Menu_Window(1,1)} {} { + code {strcpy(tip, "X.XX"); +set_override(); +end();} {} + } + Function {draw()} {return_type void + } { + code {draw_box(FL_BORDER_BOX, 0, 0, w(), h(), Fl_Color(175)); + fl_color(FL_BLACK); + fl_font(labelfont(), labelsize()); + if(textmode) + fl_draw(text, 3, 3, w()-6, h()-6, Fl_Align(FL_ALIGN_LEFT|FL_ALIGN_WRAP)); + else + fl_draw(tip, 3, 3, w()-6, h()-6, Fl_Align(FL_ALIGN_LEFT|FL_ALIGN_WRAP));} {} + } + Function {value(float f)} {return_type void + } { + code {sprintf(tip, "%.2f", f); +textmode=false; + // Recalc size of window + fl_font(labelfont(), labelsize()); + int W = w(), H = h(); + fl_measure(tip, W, H, 0); + W += 8; + size(W, H); + redraw();} {} + } + Function {setText(const char * c)} {return_type void + } { + code {strcpy(text,c); +textmode=true; + // Recalc size of window + fl_font(labelfont(), labelsize()); + int W = w(), H = h(); + fl_measure(text, W, H, 0); + W += 8; + size(W, H); + redraw();} {} + } + Function {setTextmode()} {return_type void + } { + code {textmode=true; + // Recalc size of window + fl_font(labelfont(), labelsize()); + int W = w(), H = h(); + fl_measure(text, W, H, 0); + W += 8; + size(W, H); + redraw();} {} + } + decl {char tip[40];} {} + decl {bool textmode;} {} + decl {char text[400];//bad stuff will happen if too much is put in this (perhaps dynamically allocate?)} {} +} + +class WidgetPDial {: {public Fl_Dial} +} { + Function {WidgetPDial(int x,int y, int w, int h, const char *label=0):Fl_Dial(x,y,w,h,label)} {} { + code {callback(value_cb, (void*)this); +Fl_Group *save = Fl_Group::current(); +tipwin = new TipWin(); +tipwin->hide(); +Fl_Group::current(save); +oldvalue=0.0; +pos=false; +textset=false;} {} + } + Function {~WidgetPDial()} {} { + code {delete tipwin;} {} + } + Function {handle(int event)} {return_type int + } { + code {double dragsize,v,min=minimum(),max=maximum(); +int my; + +switch (event){ +case FL_PUSH: + oldvalue=value(); +case FL_DRAG: + if(!pos){ + tipwin->position(Fl::event_x_root(), Fl::event_y_root()+20); + pos=true; + } + tipwin->value(value()); + tipwin->show(); + my=-(Fl::event_y()-y()-h()/2); + + dragsize=200.0; + if (Fl::event_state(FL_BUTTON1)==0) dragsize*=10; + v=oldvalue+my/dragsize*(max-min); + if (vmax) v=max; + + //printf("%d %g %g\\n",my,v,oldvalue); + value(v); + value_damage(); + if (this->when()!=0) do_callback(); + return(1); + break; +case FL_ENTER: + if(textset){ + if(!pos){ + tipwin->position(Fl::event_x_root(), Fl::event_y_root()+20); + pos=true; + } + tipwin->setTextmode(); + tipwin->show(); + return(1);} + break; +case FL_HIDE: +case FL_LEAVE: + tipwin->hide(); + pos=false; + break; +case FL_RELEASE: + tipwin->hide(); + pos=false; + if (this->when()==0) do_callback(); + return(1); + break; +}; +return(0);} {selected + } + } + Function {drawgradient(int cx,int cy,int sx,double m1,double m2)} {return_type void + } { + code {for (int i=(int)(m1*sx);i<(int)(m2*sx);i++){ + double tmp=1.0-pow(i*1.0/sx,2.0); + pdialcolor(140+(int) (tmp*90),140+(int)(tmp*90),140+(int) (tmp*100)); + fl_arc(cx+sx/2-i/2,cy+sx/2-i/2,i,i,0,360); +};} {} + } + Function {draw()} {} { + code {int cx=x(),cy=y(),sx=w(),sy=h(); + + +//clears the button face +pdialcolor(190,190,200); +fl_pie(cx-1,cy-1,sx+2,sy+2,0,360); + +//Draws the button face (gradinet) +drawgradient(cx,cy,sx,0.5,1.0); + +double val=(value()-minimum())/(maximum()-minimum()); + +//draws the scale +pdialcolor(220,220,250); +double a1=angle1(),a2=angle2(); +for (int i=0;i<12;i++){ + double a=-i/12.0*360.0-val*(a2-a1)-a1; + fl_pie(cx,cy,sx,sy,a+270-3,a+3+270); +}; + +drawgradient(cx,cy,sx,0.0,0.75); + +//draws the value +double a=-(a2-a1)*val-a1; + + + + + +//draws the max and min points +pdialcolor(0,100,200); +int xp=(int)(cx+sx/2.0+sx/2.0*sin(angle1()/180.0*3.141592)); +int yp=(int)(cy+sy/2.0+sy/2.0*cos(angle1()/180.0*3.141592)); +fl_pie(xp-2,yp-2,4,4,0,360); + +xp=(int)(cx+sx/2.0+sx/2.0*sin(angle2()/180.0*3.141592)); +yp=(int)(cy+sy/2.0+sy/2.0*cos(angle2()/180.0*3.141592)); +fl_pie(xp-2,yp-2,4,4,0,360); + + + + + +fl_push_matrix(); + + fl_translate(cx+sx/2,cy+sy/2); + fl_rotate(a-90.0); + + fl_translate(sx/2,0); + + + fl_begin_polygon(); + pdialcolor(0,0,0); + fl_vertex(-10,-4); + fl_vertex(-10,4); + fl_vertex(0,0); + fl_end_polygon(); + + +fl_pop_matrix();} {} + } + Function {pdialcolor(int r,int g,int b)} {} { + code {if (active_r()) fl_color(r,g,b); + else fl_color(160-(160-r)/3,160-(160-b)/3,160-(160-b)/3);} {} + } + Function {value_cb2()} {return_type void + } { + code {tipwin->value(value());} {} + } + Function {value_cb(Fl_Widget*, void*data)} {return_type {static void} + } { + code {WidgetPDial *val = (WidgetPDial*)data; + val->value_cb2();} {} + } + Function {tooltip(const char * c)} {return_type void + } { + code {tipwin->setText(c); +textset=true;} {} + } + decl {bool textset;} {} + decl {bool pos;} {} + decl {double oldvalue;} {} + decl {TipWin *tipwin;} {} +} diff --git a/plugins/zynaddsubfx/src/UI/WidgetPDial.h b/plugins/zynaddsubfx/src/UI/WidgetPDial.h new file mode 100644 index 000000000..c602a8bac --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/WidgetPDial.h @@ -0,0 +1,45 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0109 + +#ifndef WidgetPDial_h +#define WidgetPDial_h +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class TipWin : public Fl_Menu_Window { +public: + TipWin(); + void draw(); + void value(float f); + void setText(const char * c); + void setTextmode(); +private: + char tip[40]; + bool textmode; + char text[400]; //bad stuff will happen if too much is put in this (perhaps dynamically allocate?) +}; + +class WidgetPDial : public Fl_Dial { +public: + WidgetPDial(int x,int y, int w, int h, const char *label=0); + ~WidgetPDial(); + int handle(int event); + void drawgradient(int cx,int cy,int sx,double m1,double m2); + void draw(); + void pdialcolor(int r,int g,int b); + void value_cb2(); + static void value_cb(Fl_Widget*, void*data); + void tooltip(const char * c); +private: + bool textset; + bool pos; + double oldvalue; + TipWin *tipwin; +}; +#endif diff --git a/plugins/zynaddsubfx/src/UI/filechooser.h b/plugins/zynaddsubfx/src/UI/filechooser.h new file mode 100644 index 000000000..b557db94c --- /dev/null +++ b/plugins/zynaddsubfx/src/UI/filechooser.h @@ -0,0 +1,27 @@ +#define fl_file_chooser fixed_file_chooser +#include + +extern std::string __presets_dir; + +static inline char * fixed_file_chooser(const char * message, const char *pattern, const char *fname, int relative = 0) +{ + Fl_File_Chooser* fc = new Fl_File_Chooser( __presets_dir.c_str(), + pattern, + Fl_File_Chooser::SINGLE, + message ); + fc->show(); + while( fc->shown() ) + { + Fl::wait(); + } + + char * r = NULL; + if( fc->count() > 0 ) + { + r = strdup( fc->value() ); + } + delete fc; + + return r; +} + diff --git a/plugins/zynaddsubfx/src/globals.h b/plugins/zynaddsubfx/src/globals.h new file mode 100644 index 000000000..07ce9a98f --- /dev/null +++ b/plugins/zynaddsubfx/src/globals.h @@ -0,0 +1,213 @@ +/* + ZynAddSubFX - a software synthesizer + + globals.h - it contains program settings and the program capabilities + like number of parts, of effects + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + + +#ifndef GLOBALS_H +#define GLOBALS_H + +//What float type I use for internal sampledata +#define REALTYPE float + +struct FFTFREQS{ + REALTYPE *s,*c;//sine and cosine components +}; + +extern void newFFTFREQS(FFTFREQS *f,int size); +extern void deleteFFTFREQS(FFTFREQS *f); + +// Sampling rate +extern int SAMPLE_RATE; + +/* + * The size of a sound buffer (or the granularity) + * All internal transfer of sound data use buffer of this size + * All parameters are constant during this period of time, exception + * some parameters(like amplitudes) which are linear interpolated. + * If you increase this you'll ecounter big latencies, but if you + * decrease this the CPU requirements gets high. + */ +extern int SOUND_BUFFER_SIZE; + + +/* + * The size of ADnote Oscillator + * Decrease this => poor quality + * Increase this => CPU requirements gets high (only at start of the note) + */ +extern int OSCIL_SIZE; + +/* + * The number of harmonics of additive synth + * This must be smaller than OSCIL_SIZE/2 + */ +#define MAX_AD_HARMONICS 128 + + +/* + * The number of harmonics of substractive + */ +#define MAX_SUB_HARMONICS 64 + + +/* + * The maximum number of samples that are used for 1 PADsynth instrument(or item) + */ +#define PAD_MAX_SAMPLES 64 + + +/* + * Number of parts + */ +#define NUM_MIDI_PARTS 16 + +/* + * Number of Midi channes + */ +#define NUM_MIDI_CHANNELS 16 + +/* + * The number of voices of additive synth for a single note + */ +#define NUM_VOICES 8 + +/* + * The poliphony (notes) + */ +#define POLIPHONY 60 + +/* + * Number of system effects + */ +#define NUM_SYS_EFX 4 + + +/* + * Number of insertion effects + */ +#define NUM_INS_EFX 8 + +/* + * Number of part's insertion effects + */ +#define NUM_PART_EFX 3 + +/* + * Maximum number of the instrument on a part + */ +#define NUM_KIT_ITEMS 16 + + +/* + * How is applied the velocity sensing + */ +#define VELOCITY_MAX_SCALE 8.0 + +/* + * The maximum length of instrument's name + */ +#define PART_MAX_NAME_LEN 30 + +/* + * The maximum number of bands of the equaliser + */ +#define MAX_EQ_BANDS 8 +#if (MAX_EQ_BANDS>=20) +#error "Too many EQ bands in globals.h" +#endif + + +/* + * Maximum filter stages + */ +#define MAX_FILTER_STAGES 5 + +/* + * Formant filter (FF) limits + */ +#define FF_MAX_VOWELS 6 +#define FF_MAX_FORMANTS 12 +#define FF_MAX_SEQUENCE 8 + +#define LOG_2 0.693147181 +#define PI 3.1415926536 +#define LOG_10 2.302585093 + +/* + * The threshold for the amplitude interpolation used if the amplitude + * is changed (by LFO's or Envelope's). If the change of the amplitude + * is below this, the amplitude is not interpolated + */ +#define AMPLITUDE_INTERPOLATION_THRESHOLD 0.0001 + +/* + * How the amplitude threshold is computed + */ +#define ABOVE_AMPLITUDE_THRESHOLD(a,b) ( ( 2.0*fabs( (b) - (a) ) / \ + ( fabs( (b) + (a) + 0.0000000001) ) ) > AMPLITUDE_INTERPOLATION_THRESHOLD ) + +/* + * Interpolate Amplitude + */ +#define INTERPOLATE_AMPLITUDE(a,b,x,size) ( (a) + \ + ( (b) - (a) ) * (REALTYPE)(x) / (REALTYPE) (size) ) + + +/* + * dB + */ +#define dB2rap(dB) ((exp((dB)*LOG_10/20.0))) +#define rap2dB(rap) ((20*log(rap)/LOG_10)) + +/* + * The random generator (0.0..1.0) + */ +#define RND (rand()/(RAND_MAX+1.0)) + +#define ZERO(data,size) {char *data_=(char *) data;for (int i=0;i0) ? ( (int)(f) ) :( (int)(f-1.0) )); +#endif + + + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +#endif + diff --git a/plugins/zynaddsubfx/src/main.C b/plugins/zynaddsubfx/src/main.C new file mode 100644 index 000000000..b084d55f7 --- /dev/null +++ b/plugins/zynaddsubfx/src/main.C @@ -0,0 +1,782 @@ +/* + ZynAddSubFX - a software synthesizer + + main.c - Main file of the synthesizer + Copyright (C) 2002-2005 Nasca Octavian Paul + Author: Nasca Octavian Paul + + This program is free software; you can redistribute it and/or modify + it under the terms of version 2 of the GNU General Public License + as published by the Free Software Foundation. + + 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 (version 2 or later) for more details. + + You should have received a copy of the GNU General Public License (version 2) + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include +#include +#include +#include + +#include +#include + +#ifdef OS_LINUX +#include +#elif OS_WINDOIWS +#include +#include +#endif + +#include "Misc/Master.h" +#include "Misc/Util.h" +#include "Misc/Dump.h" +extern Dump dump; + +#ifdef ALSAMIDIIN +#include "Input/ALSAMidiIn.h" +#endif + +#ifdef OSSMIDIIN +#include "Input/OSSMidiIn.h" +#endif + +#if (defined(NONEMIDIIN)||defined(VSTMIDIIN)) +#include "Input/NULLMidiIn.h" +#endif + +#ifdef WINMIDIIN +#include "Input/WINMidiIn.h" +#endif + +#ifndef DISABLE_GUI +#include "UI/MasterUI.h" +MasterUI *ui; +#endif + +pthread_t thr1,thr2,thr3,thr4; +Master *master; +int swaplr=0;//1 for left-right swapping +bool usejackit=false; + +#ifdef JACKAUDIOOUT +#include "Output/JACKaudiooutput.h" +#endif + +#ifdef JACK_RTAUDIOOUT +#include "Output/JACKaudiooutput.h" +#endif + +#ifdef PAAUDIOOUT +#include "Output/PAaudiooutput.h" +#endif + +#ifdef OSSAUDIOOUT +#include "Output/OSSaudiooutput.h" +OSSaudiooutput *audioout; +#endif + +#ifdef USE_LASH +#include "Misc/LASHClient.h" +LASHClient *lash; +#endif + +MidiIn *Midi; +int Pexitprogram=0;//if the UI set this to 1, the program will exit + +/* + * Try to get the realtime priority + */ +void set_realtime(){ +#ifdef OS_LINUX + sched_param sc; + + sc.sched_priority=50; + + //if you want get "sched_setscheduler undeclared" from compilation, you can safely remove the folowing line + sched_setscheduler(0,SCHED_FIFO,&sc); +// if (err==0) printf("Real-time"); +#endif +}; + +/* + * Midi input thread + */ +#if !(defined(WINMIDIIN)||defined(VSTMIDIIN)) +void *thread1(void *arg){ + MidiCmdType cmdtype; + unsigned char cmdchan,note,vel; + int cmdparams[MP_MAX_BYTES]; + + set_realtime(); + while (Pexitprogram==0){ + Midi->getmidicmd(cmdtype,cmdchan,cmdparams); + note=cmdparams[0]; + vel=cmdparams[1]; + + pthread_mutex_lock(&master->mutex); + + if ((cmdtype==MidiNoteON)&&(note!=0)) master->NoteOn(cmdchan,note,vel); + if ((cmdtype==MidiNoteOFF)&&(note!=0)) master->NoteOff(cmdchan,note); + if (cmdtype==MidiController) master->SetController(cmdchan,cmdparams[0],cmdparams[1]); + + pthread_mutex_unlock(&master->mutex); + }; + + return(0); +}; +#endif + +/* + * Wave output thread (for OSS AUDIO out) + */ +#if defined(OSSAUDIOOUT) +//!(defined(JACKAUDIOOUT)||defined(JACK_RTAUDIOOUT)||defined(PAAUDIOOUT)||defined(VSTAUDIOOUT)) + +void *thread2(void *arg){ + REALTYPE outputl[SOUND_BUFFER_SIZE]; + REALTYPE outputr[SOUND_BUFFER_SIZE]; + + set_realtime(); + while (Pexitprogram==0){ + pthread_mutex_lock(&master->mutex); + master->AudioOut(outputl,outputr); + pthread_mutex_unlock(&master->mutex); + +#ifndef NONEAUDIOOUT + audioout->OSSout(outputl,outputr); +#endif + +/** / int i,x,x2; + REALTYPE xx,xx2; + + short int xsmps[SOUND_BUFFER_SIZE*2]; + for (i=0;i32767) xx=32767; + if (xx2<-32768) xx2=-32768; + if (xx2>32767) xx2=32767; + x=(short int) xx; + x2=(short int) xx2; + xsmps[i*2]=x;xsmps[i*2+1]=x2; + }; + write(1,&xsmps,SOUND_BUFFER_SIZE*2*2); + + / * */ + }; + return(0); +}; +#endif + +/* + * User Interface thread + */ + + +void *thread3(void *arg){ +#ifndef DISABLE_GUI + ui->showUI(); + while (Pexitprogram==0) { +#ifdef USE_LASH + std::string filename; + switch (lash->checkevents(filename)) { + case LASHClient::Save: + ui->do_save_master(const_cast(filename.c_str())); + lash->confirmevent(LASHClient::Save); + break; + case LASHClient::Restore: + ui->do_load_master(const_cast(filename.c_str())); + lash->confirmevent(LASHClient::Restore); + break; + case LASHClient::Quit: + Pexitprogram = 1; + default: + break; + } +#endif + Fl::wait(); + } +#endif + return(0); +}; + +/* + * Sequencer thread (test) + */ +void *thread4(void *arg){ + while (Pexitprogram==0){ + int type,par1,par2,again,midichan; + for (int ntrack=0;ntrackseq.play==0) break; + do{ + again=master->seq.getevent(ntrack,&midichan,&type,&par1,&par2); +// printf("ntrack=%d again=%d\n",ntrack,again); + if (type>0) { +// printf("%d %d %d %d %d\n",type,midichan,chan,par1,par2); + +// if (cmdtype==MidiController) master->SetController(cmdchan,cmdparams[0],cmdparams[1]); + + + + pthread_mutex_lock(&master->mutex); + if (type==1){//note_on or note_off + if (par2!=0) master->NoteOn(midichan,par1,par2); + else master->NoteOff(midichan,par1); + }; + pthread_mutex_unlock(&master->mutex); + }; + } while (again>0); + + }; +//if (!realtime player) atunci fac asta +//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +#ifdef OS_LINUX + usleep(1000); +#elif OS_WINDOWS + Sleep(1); +#endif + }; + + return(0); +}; + +/* + * Program initialisation + */ + + +void initprogram(){ +#ifndef JACKAUDIOOUT +#ifndef JACK_RTAUDIOOUT + fprintf(stderr,"\nSample Rate = \t\t%d\n",SAMPLE_RATE); +#endif +#endif + fprintf(stderr,"Sound Buffer Size = \t%d samples\n",SOUND_BUFFER_SIZE); + fprintf(stderr,"Internal latency = \t%.1f ms\n",SOUND_BUFFER_SIZE*1000.0/SAMPLE_RATE); + fprintf(stderr,"ADsynth Oscil.Size = \t%d samples\n",OSCIL_SIZE); + + fflush(stderr); + srand(time(NULL)); + denormalkillbuf=new REALTYPE [SOUND_BUFFER_SIZE]; + for (int i=0;iswaplr=swaplr; + +#if defined(JACKAUDIOOUT) + if (usejackit) { + bool tmp=JACKaudiooutputinit(master); +#if defined(OSSAUDIOOUT) + if (!tmp) printf("\nUsing OSS instead.\n"); +#else + if (!tmp) exit(1); +#endif + usejackit=tmp; + }; +#endif +#if defined(OSSAUDIOOUT) + if (!usejackit) audioout=new OSSaudiooutput(); + else audioout=NULL; +#endif + +#ifdef JACK_RTAUDIOOUT + JACKaudiooutputinit(master); +#endif +#ifdef PAAUDIOOUT + PAaudiooutputinit(master); +#endif + +#ifdef ALSAMIDIIN + Midi=new ALSAMidiIn(); +#endif +#ifdef OSSMIDIIN + Midi=new OSSMidiIn(); +#endif +#if (defined(NONEMIDIIN)||(defined(VSTMIDIIN))) + Midi=new NULLMidiIn(); +#endif +#ifndef DISABLE_GUI + ui=new MasterUI(master,&Pexitprogram); +#endif +}; + +/* + * Program exit + */ +void exitprogram(){ + pthread_mutex_lock(&master->mutex); +#ifdef OSSAUDIOOUT + delete(audioout); +#endif +#ifdef JACKAUDIOOUT + if (usejackit) JACKfinish(); +#endif +#ifdef JACK_RTAUDIOOUT + JACKfinish(); +#endif +#ifdef PAAUDIOOUT + PAfinish(); +#endif + +#ifndef DISABLE_GUI + delete(ui); +#endif + delete(Midi); + delete(master); + +#ifdef USE_LASH + delete(lash); +#endif + +// pthread_mutex_unlock(&master->mutex); + delete [] denormalkillbuf; + delete [] OscilGen::tmpsmps; + deleteFFTFREQS(&OscilGen::outoscilFFTfreqs); + +}; + +#ifdef OS_WINDOWS +#define ARGSIZE 100 + char winoptarguments[ARGSIZE]; + char getopt(int argc, char *argv[], const char *shortopts, int *index){ + winoptarguments[0]=0; + char result=0; + + if (*index>=argc) return(-1); + + if (strlen(argv[*index])==2) + if (argv[*index][0]=='-') { + result=argv[*index][1]; + if (*index+1=4000) { + SAMPLE_RATE=tmp; + } else { + fprintf(stderr,"ERROR:Incorrect sample rate %s .\n",optarguments); + exit(1); + }; + break; + case 'b':tmp=0; + if (optarguments!=NULL) tmp=atoi(optarguments); + if (tmp>=2) { + SOUND_BUFFER_SIZE=tmp; + } else { + fprintf(stderr,"ERROR:Incorrect buffer size %s .\n",optarguments); + exit(1); + }; + break; + case 'o':tmp=0; + if (optarguments!=NULL) tmp=atoi(optarguments); + OSCIL_SIZE=tmp; + if (OSCIL_SIZE Right\n"); + fprintf(stderr,"%s"," -D , --dump\t\t\t\t Dumps midi note ON/OFF commands\n"); + fprintf(stderr,"%s"," -U , --no-gui\t\t\t\t Run ZynAddSubFX without user interface\n"); +#ifdef JACKAUDIOOUT +#ifdef OSSAUDIOOUT + fprintf(stderr,"%s"," -A , --not-use-jack\t\t\t Use OSS/ALSA instead of JACK\n"); +#endif +#endif +#ifdef OS_WINDOWS + fprintf(stderr,"%s","\nWARNING: On Windows systems, only short comandline parameters works.\n"); + fprintf(stderr,"%s"," eg. instead '--buffer-size=512' use '-b 512'\n"); +#endif + fprintf(stderr,"%s","\n\n"); + return(0); + }; + + //--------- + + initprogram(); + +#ifdef USE_LASH +#ifdef ALSAMIDIIN + ALSAMidiIn* alsamidi = dynamic_cast(Midi); + if (alsamidi) + lash->setalsaid(alsamidi->getalsaid()); +#endif +#ifdef JACKAUDIOOUT + lash->setjackname(JACKgetname()); +#endif +#endif + + if (strlen(loadfile)>1){ + int tmp=master->loadXML(loadfile); + if (tmp<0) { + fprintf(stderr,"ERROR:Could not load master file %s .\n",loadfile); + exit(1); + } else { + master->applyparameters(); +#ifndef DISABLE_GUI + if (noui==0) ui->refresh_master_ui(); +#endif + printf("Master file loaded.\n"); + }; + }; + + if (strlen(loadinstrument)>1){ + int loadtopart=0; + int tmp=master->part[loadtopart]->loadXMLinstrument(loadinstrument); + if (tmp<0) { + fprintf(stderr,"ERROR:Could not load instrument file %s .\n",loadinstrument); + exit(1); + } else { + master->part[loadtopart]->applyparameters(); +#ifndef DISABLE_GUI + if (noui==0) ui->refresh_master_ui(); +#endif + printf("Instrument file loaded.\n"); + }; + }; + + +#if !(defined(NONEMIDIIN)||defined(WINMIDIIN)||defined(VSTMIDIIN)) + pthread_create(&thr1,NULL,thread1,NULL); +#endif + +#ifdef OSSAUDIOOUT +//!(defined(JACKAUDIOOUT)||defined(JACK_RTAUDIOOUT)||defined(PAAUDIOOUT)||defined(VSTAUDIOOUT)) + if (!usejackit) pthread_create(&thr2,NULL,thread2,NULL); +#endif + +/*It is not working and I don't know why +//drop the suid-root permisions +#if !(defined(JACKAUDIOOUT)||defined(PAAUDIOOUT)||defined(VSTAUDIOOUT)|| (defined (WINMIDIIN)) ) + setuid(getuid()); + seteuid(getuid()); +// setreuid(getuid(),getuid()); +// setregid(getuid(),getuid()); +#endif +*/ + if (noui==0) pthread_create(&thr3,NULL,thread3,NULL); + + pthread_create(&thr4,NULL,thread4,NULL); +#ifdef WINMIDIIN + InitWinMidi(master); +#endif + + while (Pexitprogram==0){ +#ifdef OS_LINUX + usleep(100000); +#elif OS_WINDOWS + Sleep(100); +#endif + }; + +#ifdef WINMIDIIN + StopWinMidi(); +#endif + + exitprogram(); + return(0); +}; + + +#else + +#include "Output/VSTaudiooutput.h" + +#define main main_plugin +extern "C" __declspec(dllexport) AEffect *main_plugin(audioMasterCallback audioMaster); + +int instances=-1; + +AEffect *main (audioMasterCallback audioMaster){ +// if (audioMaster(0,audioMasterVersion,0,0,0,0)!=0) { +// return(0); +// }; + + if (instances==-1){ + Midi=new NULLMidiIn(); + denormalkillbuf=new REALTYPE [SOUND_BUFFER_SIZE]; + for (int i=0;igetAeffect(); +}; + +void* hInstance; +BOOL WINAPI DllMain (HINSTANCE hInst,DWORD dwReason,LPVOID lpvReserved){ + hInstance=hInst; + return(1); +}; + +void *thread(void *arg){ + VSTSynth *vs=(VSTSynth *) arg; + +/* FILE *a=fopen("aaaa1","a"); + fprintf(a,"%lx %lx %lx -i=%d\n",vs,0,vs->vmaster,instances); + fflush(a);fclose(a); +*/ + + vs->ui=new MasterUI(vs->vmaster,&vs->Pexitprogram); + +/* a=fopen("aaaa1","a"); + fprintf(a,"%lx %lx %lx\n",vs,vs->ui->master,vs->vmaster); + fflush(a);fclose(a); +*/ + + vs->ui->showUI(); + +/* a=fopen("aaaa1","a"); + fprintf(a,"%lx %lx %lx\n",vs,vs->ui,vs->vmaster); + fflush(a);fclose(a); +*/ + + while (vs->Pexitprogram==0) Fl::wait(0.01); + + delete(vs->ui); + Fl::wait(0.01); + +/* a=fopen("aaaa1","a"); + fprintf(a,"EXIT\n"); + fflush(a);fclose(a); +*/ + + + pthread_exit(0); + return(0); +}; + +//Parts of the VSTSynth class +VSTSynth::VSTSynth (audioMasterCallback audioMaster):AudioEffectX(audioMaster,1,0){ + instances++; + + if (audioMaster){ + setNumInputs(0); + setNumOutputs(2); + setUniqueID('ZASF'); + canProcessReplacing(); +// hasVu(false); +// hasClip(false); + + isSynth(true); + + programsAreChunks(true); + + }; + + + SAMPLE_RATE=config.cfg.SampleRate; + SOUND_BUFFER_SIZE=config.cfg.SoundBufferSize; + OSCIL_SIZE=config.cfg.OscilSize; + swaplr=config.cfg.SwapStereo; + this->Pexitprogram=0; + + this->vmaster=new Master(); + this->vmaster->swaplr=swaplr; + + +// FILE *a=fopen("aaaa0","a"); +// fprintf(a,"%lx %lx %lx\n",this,this->ui,this->ui->masterwindow); +// fflush(a);fclose(a); + + pthread_create(&this->thr,NULL,thread,this); + +// suspend(); + +}; + + + +VSTSynth::~VSTSynth(){ + this->Pexitprogram=1; + + Sleep(200);//wait the thread to finish + +// pthread_mutex_lock(&vmaster->mutex); + + + delete(this->vmaster); + + instances--; +}; + +long VSTSynth::processEvents(VstEvents *events){ + for (int i=0;inumEvents;i++){ + + //debug stuff +// FILE *a=fopen("events","a"); +// fprintf(a,"%lx\n",events->events[i]->type); +// fflush(a);fclose(a); + + if ((events->events[i])->type != kVstMidiType) continue; + VstMidiEvent *ev= (VstMidiEvent*) events->events[i]; + unsigned char *data= (unsigned char *)ev->midiData; + int status=data[0]/16; + int cmdchan=data[0]&0x0f; + int cntl; + + pthread_mutex_lock(&vmaster->mutex); + switch(status){ + case 0x8:vmaster->NoteOff(cmdchan,data[1]&0x7f); + break; + case 0x9:if (data[2]==0) vmaster->NoteOff(cmdchan,data[1]&0x7f); + else vmaster->NoteOn(cmdchan,data[1]&0x7f,data[2]&0x7f); + break; + case 0xB: cntl=Midi->getcontroller(data[1]&0x7f); + vmaster->SetController(cmdchan,cntl,data[2]&0x7f); + break; + case 0xE: vmaster->SetController(cmdchan,C_pitchwheel,data[1]+data[2]*(long int) 128-8192); + break; + }; + pthread_mutex_unlock(&vmaster->mutex); + + }; + +return(1); +}; + +long VSTSynth::getChunk(void** data,bool isPreset){ + int size=0; + size=vmaster->getalldata((char **)data); + return((long)size); +}; + +long VSTSynth::setChunk(void *data,long size,bool isPreset){ + vmaster->putalldata((char*)data,size); + return(0); +}; +#endif + diff --git a/plugins/zynaddsubfx/zynaddsubfx.cpp b/plugins/zynaddsubfx/zynaddsubfx.cpp new file mode 100644 index 000000000..88b8538c1 --- /dev/null +++ b/plugins/zynaddsubfx/zynaddsubfx.cpp @@ -0,0 +1,299 @@ +/* + * zynaddsubfx.cpp - ZynAddSubFX-embedding plugin + * + * Copyright (c) 2008-2009 Tobias Doerffel + * + * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net + * + * 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 (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + + +#include "lmmsconfig.h" + +#include +#include +#include + +#include "zynaddsubfx.h" +#include "engine.h" +#include "instrument_play_handle.h" +#include "instrument_track.h" +#include "gui_templates.h" +#include "remote_zynaddsubfx.h" + +#undef SINGLE_SOURCE_COMPILE +#include "embed.cpp" +#include "moc_zynaddsubfx.cxx" + + +extern "C" +{ + +plugin::descriptor PLUGIN_EXPORT zynaddsubfx_plugin_descriptor = +{ + STRINGIFY( PLUGIN_NAME ), + "ZynAddSubFX", + QT_TRANSLATE_NOOP( "pluginBrowser", + "Embedded ZynAddSubFX" ), + "Tobias Doerffel ", + 0x0100, + plugin::Instrument, + new pluginPixmapLoader( "logo" ), + "xiz", + NULL, +} ; + +} + + + +zynAddSubFx::zynAddSubFx( instrumentTrack * _instrumentTrack ) : + instrument( _instrumentTrack, &zynaddsubfx_plugin_descriptor ), + remotePlugin( "remote_zynaddsubfx" ) +{ + // now we need a play-handle which cares for calling play() + instrumentPlayHandle * iph = new instrumentPlayHandle( this ); + engine::getMixer()->addPlayHandle( iph ); + + connect( engine::getMixer(), SIGNAL( sampleRateChanged() ), + this, SLOT( updateSampleRate() ) ); + sendMessage( message( IdZasfPresetDirectory ). + addString( + ( configManager::inst()->factoryPresetsDir() + + QDir::separator() + "ZynAddSubFX" ). + toStdString() ) ); +} + + + + +zynAddSubFx::~zynAddSubFx() +{ + engine::getMixer()->removePlayHandles( getInstrumentTrack() ); +} + + + + +void zynAddSubFx::saveSettings( QDomDocument & _doc, + QDomElement & _this ) +{ + QTemporaryFile tf; + if( tf.open() ) + { + lock(); + sendMessage( message( IdSaveSettingsToFile ). + addString( QDir::toNativeSeparators( + tf.fileName() ).toStdString() ) ); + waitForMessage( IdSaveSettingsToFile ); + unlock(); + QByteArray a = tf.readAll(); + // remove first blank line + a.remove( 0, +#ifdef LMMS_BUILD_WIN32 + 2 +#else + 1 +#endif + ); + QDomDocument doc( "mydoc" ); + doc.setContent( a ); + _this.appendChild( doc.documentElement() ); + } +} + + + + +void zynAddSubFx::loadSettings( const QDomElement & _this ) +{ + if( !_this.hasChildNodes() ) + { + return; + } + + QDomDocument doc; + doc.appendChild( doc.importNode( _this.firstChild(), TRUE ) ); + QTemporaryFile tf; + tf.setAutoRemove( false ); + if( tf.open() ) + { + QByteArray a = doc.toString( 0 ).toUtf8(); + a.prepend( "\n" ); + tf.write( a ); + lock(); + sendMessage( message( IdLoadSettingsFromFile ). + addString( QDir::toNativeSeparators( + tf.fileName() ).toStdString() ) ); + waitForMessage( IdLoadSettingsFromFile ); + unlock(); + + emit settingsChanged(); + } +} + + + + +void zynAddSubFx::loadFile( const QString & _file ) +{ + lock(); + sendMessage( message( IdLoadPresetFromFile ). + addString( _file.toStdString() ) ); + waitForMessage( IdLoadPresetFromFile ); + unlock(); + emit settingsChanged(); +} + + + + +QString zynAddSubFx::nodeName( void ) const +{ + return( zynaddsubfx_plugin_descriptor.name ); +} + + + + +void zynAddSubFx::play( sampleFrame * _buf ) +{ + process( NULL, _buf ); + getInstrumentTrack()->processAudioBuffer( _buf, + engine::getMixer()->framesPerPeriod(), NULL ); +} + + + + +bool zynAddSubFx::handleMidiEvent( const midiEvent & _me, + const midiTime & _time ) +{ + processMidiEvent( _me, 0 ); + return true; +} + + + + +void zynAddSubFx::updateSampleRate( void ) +{ + remotePlugin::updateSampleRate( + engine::getMixer()->processingSampleRate() ); +} + + + + +pluginView * zynAddSubFx::instantiateView( QWidget * _parent ) +{ + return( new zynAddSubFxView( this, _parent ) ); +} + + + + + + + +zynAddSubFxView::zynAddSubFxView( instrument * _instrument, QWidget * _parent ) : + instrumentView( _instrument, _parent ), + m_exit( 0 ) +{ + setAutoFillBackground( TRUE ); + QPalette pal; + pal.setBrush( backgroundRole(), PLUGIN_NAME::getIconPixmap( + "artwork" ) ); + setPalette( pal ); + + m_toggleUIButton = new QPushButton( tr( "Show GUI" ), this ); + m_toggleUIButton->setCheckable( TRUE ); + m_toggleUIButton->setChecked( FALSE ); + m_toggleUIButton->setGeometry( 45, 80, 160, 24 ); + m_toggleUIButton->setIcon( embed::getIconPixmap( "zoom" ) ); + m_toggleUIButton->setFont( pointSize<8>( m_toggleUIButton->font() ) ); + connect( m_toggleUIButton, SIGNAL( toggled( bool ) ), this, + SLOT( toggleUI() ) ); + m_toggleUIButton->setWhatsThis( + tr( "Click here to show or hide the graphical user interface " + "(GUI) of ZynAddSubFX." ) ); +} + + + + +zynAddSubFxView::~zynAddSubFxView() +{ +} + + + + +void zynAddSubFxView::modelChanged( void ) +{ + zynAddSubFx * z = castModel(); + connect( z, SIGNAL( settingsChanged() ), + this, SLOT( updateUI() ) ); + toggleUI(); +} + + + + +void zynAddSubFxView::updateUI( void ) +{ +/* zynAddSubFxManager::instance()->m_uiMutex.lock(); + m_ui->refresh_master_ui(); + zynAddSubFxManager::instance()->m_uiMutex.unlock();*/ +} + + + + +void zynAddSubFxView::toggleUI( void ) +{ + if( m_toggleUIButton->isChecked() ) + { + castModel()->showUI(); + } + else + { + castModel()->hideUI(); + } + +} + + + + + +extern "C" +{ + +// neccessary for getting instance out of shared lib +plugin * PLUGIN_EXPORT lmms_plugin_main( model *, void * _data ) +{ + + return( new zynAddSubFx( + static_cast( _data ) ) ); +} + + +} + + diff --git a/plugins/zynaddsubfx/zynaddsubfx.h b/plugins/zynaddsubfx/zynaddsubfx.h new file mode 100644 index 000000000..f2d581bad --- /dev/null +++ b/plugins/zynaddsubfx/zynaddsubfx.h @@ -0,0 +1,112 @@ +/* + * zynaddsubfx.h - ZynAddSubFX-embedding plugin + * + * Copyright (c) 2008 Tobias Doerffel + * + * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net + * + * 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 (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + + +#ifndef _ZYNADDSUBFX_H +#define _ZYNADDSUBFX_H + +#include +#include + +#include "instrument.h" +#include "instrument_view.h" +#include "remote_plugin.h" + + +class QPushButton; + +class zynAddSubFxView; +class notePlayHandle; + + +class zynAddSubFx : public instrument, public remotePlugin +{ + Q_OBJECT +public: + zynAddSubFx( instrumentTrack * _instrument_track ); + virtual ~zynAddSubFx(); + + virtual void play( sampleFrame * _working_buffer ); + + virtual bool handleMidiEvent( const midiEvent & _me, + const midiTime & _time ); + + virtual void saveSettings( QDomDocument & _doc, QDomElement & _parent ); + virtual void loadSettings( const QDomElement & _this ); + + virtual void loadFile( const QString & _file ); + + + virtual QString nodeName( void ) const; + + virtual bool isMidiBased( void ) const + { + return true; + } + + virtual pluginView * instantiateView( QWidget * _parent ); + + +private slots: + void updateSampleRate( void ); + + +private: + QMutex m_pluginMutex; + + + friend class zynAddSubFxView; + + +signals: + void settingsChanged( void ); + +} ; + + + +class zynAddSubFxView : public instrumentView +{ + Q_OBJECT +public: + zynAddSubFxView( instrument * _instrument, QWidget * _parent ); + virtual ~zynAddSubFxView(); + +private: + void modelChanged( void ); + + int m_exit; + + QPushButton * m_toggleUIButton; + + +private slots: + void updateUI( void ); + void toggleUI( void ); + +} ; + + + +#endif