Browse Source

tags/2021-05-28
jules 18 years ago
parent
commit
94cfda5062
100 changed files with 60322 additions and 0 deletions
  1. +2194
    -0
      build/linux/JUCE.make
  2. +25
    -0
      build/linux/Makefile
  3. +138
    -0
      build/linux/juce_premake.lua
  4. +962
    -0
      build/linux/platform_specific_code/juce_linux_Audio.cpp
  5. +110
    -0
      build/linux/platform_specific_code/juce_linux_AudioCDReader.cpp
  6. +60
    -0
      build/linux/platform_specific_code/juce_linux_FileChooser.cpp
  7. +603
    -0
      build/linux/platform_specific_code/juce_linux_Files.cpp
  8. +627
    -0
      build/linux/platform_specific_code/juce_linux_Fonts.cpp
  9. +399
    -0
      build/linux/platform_specific_code/juce_linux_Messaging.cpp
  10. +453
    -0
      build/linux/platform_specific_code/juce_linux_Midi.cpp
  11. +33
    -0
      build/linux/platform_specific_code/juce_linux_NamedPipe.cpp
  12. +59
    -0
      build/linux/platform_specific_code/juce_linux_Network.cpp
  13. +402
    -0
      build/linux/platform_specific_code/juce_linux_SystemStats.cpp
  14. +457
    -0
      build/linux/platform_specific_code/juce_linux_Threads.cpp
  15. +3076
    -0
      build/linux/platform_specific_code/juce_linux_Windowing.cpp
  16. +54
    -0
      build/linux/platform_specific_code/linuxincludes.h
  17. +1
    -0
      build/linux/runpremake
  18. +3187
    -0
      build/macosx/Juce.xcodeproj/project.pbxproj
  19. +6
    -0
      build/macosx/juce.xcconfig.tortoise.removed
  20. +1165
    -0
      build/macosx/platform_specific_code/juce_mac_CoreAudio.cpp
  21. +594
    -0
      build/macosx/platform_specific_code/juce_mac_CoreMidi.cpp
  22. +299
    -0
      build/macosx/platform_specific_code/juce_mac_FileChooser.cpp
  23. +977
    -0
      build/macosx/platform_specific_code/juce_mac_Files.cpp
  24. +529
    -0
      build/macosx/platform_specific_code/juce_mac_Fonts.cpp
  25. +394
    -0
      build/macosx/platform_specific_code/juce_mac_HTTPStream.h
  26. +342
    -0
      build/macosx/platform_specific_code/juce_mac_Messaging.cpp
  27. +237
    -0
      build/macosx/platform_specific_code/juce_mac_NamedPipe.cpp
  28. +138
    -0
      build/macosx/platform_specific_code/juce_mac_Network.cpp
  29. +297
    -0
      build/macosx/platform_specific_code/juce_mac_SystemStats.cpp
  30. +364
    -0
      build/macosx/platform_specific_code/juce_mac_Threads.cpp
  31. +3061
    -0
      build/macosx/platform_specific_code/juce_mac_Windowing.cpp
  32. +979
    -0
      build/win32/devcpp/Makefile.win
  33. +6759
    -0
      build/win32/devcpp/juce.dev
  34. +1947
    -0
      build/win32/platform_specific_code/juce_win32_ASIO.cpp
  35. +2114
    -0
      build/win32/platform_specific_code/juce_win32_AudioCDReader.cpp
  36. +1754
    -0
      build/win32/platform_specific_code/juce_win32_DirectSound.cpp
  37. +57
    -0
      build/win32/platform_specific_code/juce_win32_DynamicLibraryLoader.cpp
  38. +68
    -0
      build/win32/platform_specific_code/juce_win32_DynamicLibraryLoader.h
  39. +492
    -0
      build/win32/platform_specific_code/juce_win32_FileChooser.cpp
  40. +960
    -0
      build/win32/platform_specific_code/juce_win32_Files.cpp
  41. +662
    -0
      build/win32/platform_specific_code/juce_win32_Fonts.cpp
  42. +247
    -0
      build/win32/platform_specific_code/juce_win32_Messaging.cpp
  43. +656
    -0
      build/win32/platform_specific_code/juce_win32_Midi.cpp
  44. +120
    -0
      build/win32/platform_specific_code/juce_win32_Misc.cpp
  45. +339
    -0
      build/win32/platform_specific_code/juce_win32_Network.cpp
  46. +291
    -0
      build/win32/platform_specific_code/juce_win32_PlatformUtils.cpp
  47. +605
    -0
      build/win32/platform_specific_code/juce_win32_SystemStats.cpp
  48. +390
    -0
      build/win32/platform_specific_code/juce_win32_Threads.cpp
  49. +3536
    -0
      build/win32/platform_specific_code/juce_win32_Windowing.cpp
  50. +76
    -0
      build/win32/platform_specific_code/win32_headers.h
  51. +2901
    -0
      build/win32/vc6/JUCE.dsp
  52. +6086
    -0
      build/win32/vc8/JUCE.vcproj
  53. +683
    -0
      docs/JUCE changelist.txt
  54. +273
    -0
      docs/JUCE readme.html
  55. +340
    -0
      docs/gpl.txt
  56. BIN
      docs/images/rms_logo.gif
  57. +193
    -0
      docs/rawmat.css
  58. +265
    -0
      extras/audio plugins/How to use this framework.txt
  59. +28
    -0
      extras/audio plugins/demo/build/AudioUnit/Info-JuceAU.plist
  60. +9
    -0
      extras/audio plugins/demo/build/AudioUnit/JuceAU.exp
  61. +609
    -0
      extras/audio plugins/demo/build/AudioUnit/JuceDemoAU.xcodeproj/project.pbxproj
  62. +32
    -0
      extras/audio plugins/demo/build/RTAS_Mac/Info.plist
  63. +414
    -0
      extras/audio plugins/demo/build/RTAS_Mac/juce_RTASDemo.xcodeproj/project.pbxproj
  64. +49
    -0
      extras/audio plugins/demo/build/RTAS_Win32/juce_RTAS.sln
  65. +649
    -0
      extras/audio plugins/demo/build/RTAS_Win32/juce_RTAS.vcproj
  66. +112
    -0
      extras/audio plugins/demo/build/RTAS_Win32/juce_RTASDemo.rc
  67. +14
    -0
      extras/audio plugins/demo/build/RTAS_Win32/resource.h
  68. +28
    -0
      extras/audio plugins/demo/build/VST_Mac/Info.plist
  69. +22
    -0
      extras/audio plugins/demo/build/VST_Mac/JuceVST-Info.plist
  70. +301
    -0
      extras/audio plugins/demo/build/VST_Mac/JuceVST.xcodeproj/project.pbxproj
  71. +16
    -0
      extras/audio plugins/demo/build/VST_Mac/version.plist
  72. +39
    -0
      extras/audio plugins/demo/build/VST_Win32/juce_vst.sln
  73. +288
    -0
      extras/audio plugins/demo/build/VST_Win32/juce_vst.vcproj
  74. +210
    -0
      extras/audio plugins/demo/src/DemoEditorComponent.cpp
  75. +99
    -0
      extras/audio plugins/demo/src/DemoEditorComponent.h
  76. +254
    -0
      extras/audio plugins/demo/src/DemoJuceFilter.cpp
  77. +111
    -0
      extras/audio plugins/demo/src/DemoJuceFilter.h
  78. +274
    -0
      extras/audio plugins/demo/src/JucePluginCharacteristics.h
  79. +827
    -0
      extras/audio plugins/wrapper/formats/AudioUnit/juce_AudioUnitWrapper.cpp
  80. +70
    -0
      extras/audio plugins/wrapper/formats/AudioUnit/juce_AudioUnitWrapper.r
  81. BIN
      extras/audio plugins/wrapper/formats/RTAS/DefaultResourceFile
  82. +4
    -0
      extras/audio plugins/wrapper/formats/RTAS/DummyResourceFile.r
  83. +63
    -0
      extras/audio plugins/wrapper/formats/RTAS/juce_RTASCompileFlags.h
  84. +131
    -0
      extras/audio plugins/wrapper/formats/RTAS/juce_RTASUtilities.cpp
  85. +1011
    -0
      extras/audio plugins/wrapper/formats/RTAS/juce_RTASWrapper.cpp
  86. +5
    -0
      extras/audio plugins/wrapper/formats/RTAS/juce_RTAS_dlldefs.def
  87. +44
    -0
      extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectGroup.cpp
  88. +44
    -0
      extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectGroupMIDI.cpp
  89. +44
    -0
      extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectMIDIUtils.cpp
  90. +44
    -0
      extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectProcess.cpp
  91. +44
    -0
      extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectProcessAS.cpp
  92. +44
    -0
      extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectProcessMIDI.cpp
  93. +44
    -0
      extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectType.cpp
  94. +44
    -0
      extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectTypeRTAS.cpp
  95. +44
    -0
      extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_ChunkDataParser.cpp
  96. +46
    -0
      extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_DLLMain.cpp
  97. +46
    -0
      extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_DefaultSwap.cpp
  98. +40
    -0
      extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_Dispatcher.cpp
  99. +45
    -0
      extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_Header.h
  100. +44
    -0
      extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_PlugInUtils.cpp

+ 2194
- 0
build/linux/JUCE.make
File diff suppressed because it is too large
View File


+ 25
- 0
build/linux/Makefile View File

@@ -0,0 +1,25 @@
# Makefile autogenerated by premake
# Don't edit this file! Instead edit `premake.lua` then rerun `make`
# Options:
# CONFIG=[Debug|Release]

ifndef CONFIG
CONFIG=Debug
endif

export CONFIG

.PHONY: all clean JUCE

all: JUCE

Makefile: juce_premake.lua
@echo ==== Regenerating Makefiles ====
@premake --file $^ --cc gcc --target gnu

JUCE:
@echo ==== Building JUCE ====
@$(MAKE) --no-print-directory -C . -f JUCE.make

clean:
@$(MAKE) --no-print-directory -C . -f JUCE.make clean

+ 138
- 0
build/linux/juce_premake.lua View File

@@ -0,0 +1,138 @@
project.name = "JUCE"
project.bindir = "../../bin"
project.libdir = "../../bin"
project.configs = { "Debug", "Release" }
package = newpackage()
package.name = "JUCE"
package.kind = "lib"
package.language = "c++"
package.objdir = "../../bin/intermediate_linux/"
package.config["Debug"].objdir = "../../bin/intermediate_linux/Debug"
package.config["Release"].objdir = "../../bin/intermediate_linux/Release"
package.config["Debug"].target = "juce_debug"
package.config["Release"].target = "juce"
package.config["Debug"].defines = { "LINUX=1", "DEBUG=1", "_DEBUG=1" };
package.config["Debug"].buildoptions = { "-D_DEBUG -ggdb -Wall" }
package.config["Release"].defines = { "LINUX=1", "NDEBUG=1" };
package.config["Release"].buildoptions = { "-Wall" }
package.includepaths = {
"../../",
"/usr/include",
"/usr/include/freetype2"
}
package.linkflags = { "static-runtime" }
package.files = { matchfiles (
"../../src/*.h",
"../../src/juce_core/basics/*.cpp",
"../../src/juce_core/basics/*.h",
"../../src/juce_core/cryptography/*.cpp",
"../../src/juce_core/cryptography/*.h",
"../../src/juce_core/containers/*.cpp",
"../../src/juce_core/containers/*.h",
"../../src/juce_core/io/*.cpp",
"../../src/juce_core/io/*.h",
"../../src/juce_core/io/files/*.cpp",
"../../src/juce_core/io/files/*.h",
"../../src/juce_core/io/network/*.cpp",
"../../src/juce_core/io/network/*.h",
"../../src/juce_core/io/streams/*.cpp",
"../../src/juce_core/io/streams/*.h",
"../../src/juce_core/io/streams/zlib/*.cpp",
"../../src/juce_core/io/streams/zlib/*.c",
"../../src/juce_core/io/streams/zlib/*.h",
"../../src/juce_core/misc/*.cpp",
"../../src/juce_core/misc/*.h",
"../../src/juce_core/text/*.cpp",
"../../src/juce_core/text/*.h",
"../../src/juce_core/threads/*.cpp",
"../../src/juce_core/threads/*.h",
"../../src/juce_appframework/application/*.cpp",
"../../src/juce_appframework/application/*.h",
"../../src/juce_appframework/audio/*.cpp",
"../../src/juce_appframework/audio/*.h",
"../../src/juce_appframework/audio/dsp/*.cpp",
"../../src/juce_appframework/audio/dsp/*.h",
"../../src/juce_appframework/audio/midi/*.cpp",
"../../src/juce_appframework/audio/midi/*.h",
"../../src/juce_appframework/audio/audio_file_formats/*.cpp",
"../../src/juce_appframework/audio/audio_file_formats/*.h",
"../../src/juce_appframework/audio/audio_file_formats/flac/libFLAC/*.c",
"../../src/juce_appframework/audio/audio_file_formats/flac/libFLAC/*.h",
"../../src/juce_appframework/audio/audio_file_formats/oggvorbis/*.c",
"../../src/juce_appframework/audio/audio_file_formats/oggvorbis/*.h",
"../../src/juce_appframework/audio/audio_file_formats/oggvorbis/libvorbis-1.1.2/lib/*.c",
"../../src/juce_appframework/audio/audio_file_formats/oggvorbis/libvorbis-1.1.2/lib/*.h",
"../../src/juce_appframework/audio/audio_sources/*.cpp",
"../../src/juce_appframework/audio/audio_sources/*.h",
"../../src/juce_appframework/audio/devices/*.cpp",
"../../src/juce_appframework/audio/devices/*.h",
"../../src/juce_appframework/audio/synthesisers/*.cpp",
"../../src/juce_appframework/audio/synthesisers/*.h",
"../../src/juce_appframework/documents/*.cpp",
"../../src/juce_appframework/documents/*.h",
"../../src/juce_appframework/events/*.cpp",
"../../src/juce_appframework/events/*.h",
"../../src/juce_appframework/gui/graphics/brushes/*.cpp",
"../../src/juce_appframework/gui/graphics/brushes/*.h",
"../../src/juce_appframework/gui/graphics/colour/*.cpp",
"../../src/juce_appframework/gui/graphics/colour/*.h",
"../../src/juce_appframework/gui/graphics/contexts/*.cpp",
"../../src/juce_appframework/gui/graphics/contexts/*.h",
"../../src/juce_appframework/gui/graphics/drawables/*.cpp",
"../../src/juce_appframework/gui/graphics/drawables/*.h",
"../../src/juce_appframework/gui/graphics/effects/*.cpp",
"../../src/juce_appframework/gui/graphics/effects/*.h",
"../../src/juce_appframework/gui/graphics/fonts/*.cpp",
"../../src/juce_appframework/gui/graphics/fonts/*.h",
"../../src/juce_appframework/gui/graphics/geometry/*.cpp",
"../../src/juce_appframework/gui/graphics/geometry/*.h",
"../../src/juce_appframework/gui/graphics/imaging/*.cpp",
"../../src/juce_appframework/gui/graphics/imaging/*.h",
"../../src/juce_appframework/gui/graphics/imaging/image_file_formats/*.cpp",
"../../src/juce_appframework/gui/graphics/imaging/image_file_formats/*.h",
"../../src/juce_appframework/gui/graphics/imaging/image_file_formats/jpglib/*.cpp",
"../../src/juce_appframework/gui/graphics/imaging/image_file_formats/jpglib/*.c",
"../../src/juce_appframework/gui/graphics/imaging/image_file_formats/jpglib/*.h",
"../../src/juce_appframework/gui/graphics/imaging/image_file_formats/pnglib/*.cpp",
"../../src/juce_appframework/gui/graphics/imaging/image_file_formats/pnglib/*.c",
"../../src/juce_appframework/gui/graphics/imaging/image_file_formats/pnglib/*.h",
"../../src/juce_appframework/gui/components/*.cpp",
"../../src/juce_appframework/gui/components/*.h",
"../../src/juce_appframework/gui/components/buttons/*.cpp",
"../../src/juce_appframework/gui/components/buttons/*.h",
"../../src/juce_appframework/gui/components/controls/*.cpp",
"../../src/juce_appframework/gui/components/controls/*.h",
"../../src/juce_appframework/gui/components/filebrowser/*.cpp",
"../../src/juce_appframework/gui/components/filebrowser/*.h",
"../../src/juce_appframework/gui/components/keyboard/*.cpp",
"../../src/juce_appframework/gui/components/keyboard/*.h",
"../../src/juce_appframework/gui/components/layout/*.cpp",
"../../src/juce_appframework/gui/components/layout/*.h",
"../../src/juce_appframework/gui/components/lookandfeel/*.cpp",
"../../src/juce_appframework/gui/components/lookandfeel/*.h",
"../../src/juce_appframework/gui/components/menus/*.cpp",
"../../src/juce_appframework/gui/components/menus/*.h",
"../../src/juce_appframework/gui/components/mouse/*.cpp",
"../../src/juce_appframework/gui/components/mouse/*.h",
"../../src/juce_appframework/gui/components/properties/*.cpp",
"../../src/juce_appframework/gui/components/properties/*.h",
"../../src/juce_appframework/gui/components/special/*.cpp",
"../../src/juce_appframework/gui/components/special/*.h",
"../../src/juce_appframework/gui/components/windows/*.cpp",
"../../src/juce_appframework/gui/components/windows/*.h",
"platform_specific_code/*.h",
"platform_specific_code/*.cpp"
)
}

+ 962
- 0
build/linux/platform_specific_code/juce_linux_Audio.cpp View File

@@ -0,0 +1,962 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "../../../juce_Config.h"
#if JUCE_BUILD_GUI_CLASSES
#if JUCE_ALSA
#include "linuxincludes.h"
#include <alsa/asoundlib.h>
#include "../../../src/juce_core/basics/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "../../../src/juce_appframework/audio/devices/juce_AudioIODeviceType.h"
#include "../../../src/juce_core/threads/juce_Thread.h"
#include "../../../src/juce_core/threads/juce_ScopedLock.h"
#include "../../../src/juce_core/basics/juce_Time.h"
#include "../../../src/juce_core/io/files/juce_File.h"
#include "../../../src/juce_core/io/files/juce_FileInputStream.h"
#include "../../../src/juce_core/basics/juce_Singleton.h"
#include "../../../src/juce_appframework/audio/dsp/juce_AudioDataConverters.h"
static const int maxNumChans = 64;
//==============================================================================
static void getDeviceSampleRates (snd_pcm_t* handle, Array <int>& rates)
{
const int ratesToTry[] = { 22050, 32000, 44100, 48000, 88200, 96000, 176400, 192000, 0 };
snd_pcm_hw_params_t* hwParams;
snd_pcm_hw_params_alloca (&hwParams);
for (int i = 0; ratesToTry[i] != 0; ++i)
{
if (snd_pcm_hw_params_any (handle, hwParams) >= 0
&& snd_pcm_hw_params_test_rate (handle, hwParams, ratesToTry[i], 0) == 0)
{
rates.add (ratesToTry[i]);
}
}
}
static void getDeviceNumChannels (snd_pcm_t* handle, unsigned int* minChans, unsigned int* maxChans)
{
snd_pcm_hw_params_t *params;
snd_pcm_hw_params_alloca (&params);
if (snd_pcm_hw_params_any (handle, params) >= 0)
{
snd_pcm_hw_params_get_channels_min (params, minChans);
snd_pcm_hw_params_get_channels_max (params, maxChans);
}
}
static void getDeviceProperties (const String& id,
unsigned int& minChansOut,
unsigned int& maxChansOut,
unsigned int& minChansIn,
unsigned int& maxChansIn,
Array <int>& rates)
{
snd_ctl_t* handle;
if (snd_ctl_open (&handle, id.upToLastOccurrenceOf (T(","), false, false), SND_CTL_NONBLOCK) >= 0)
{
snd_pcm_info_t* info;
snd_pcm_info_alloca (&info);
snd_pcm_info_set_stream (info, SND_PCM_STREAM_PLAYBACK);
snd_pcm_info_set_device (info, id.fromLastOccurrenceOf (T(","), false, false).getIntValue());
snd_pcm_info_set_subdevice (info, 0);
if (snd_ctl_pcm_info (handle, info) >= 0)
{
snd_pcm_t* pcmHandle;
if (snd_pcm_open (&pcmHandle, id, SND_PCM_STREAM_PLAYBACK, SND_PCM_ASYNC | SND_PCM_NONBLOCK ) >= 0)
{
getDeviceNumChannels (pcmHandle, &minChansOut, &maxChansOut);
getDeviceSampleRates (pcmHandle, rates);
snd_pcm_close (pcmHandle);
}
}
snd_pcm_info_set_stream (info, SND_PCM_STREAM_CAPTURE);
if (snd_ctl_pcm_info (handle, info) >= 0)
{
snd_pcm_t* pcmHandle;
if (snd_pcm_open (&pcmHandle, id, SND_PCM_STREAM_CAPTURE, SND_PCM_ASYNC | SND_PCM_NONBLOCK ) >= 0)
{
getDeviceNumChannels (pcmHandle, &minChansIn, &maxChansIn);
if (rates.size() == 0)
getDeviceSampleRates (pcmHandle, rates);
snd_pcm_close (pcmHandle);
}
}
snd_ctl_close (handle);
}
}
//==============================================================================
class ALSADevice
{
public:
ALSADevice (const String& deviceName,
const bool forInput)
: handle (0),
bitDepth (16),
numChannelsRunning (0),
isInput (forInput),
sampleFormat (AudioDataConverters::int16LE)
{
failed (snd_pcm_open (&handle, deviceName,
forInput ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK,
SND_PCM_ASYNC));
}
~ALSADevice()
{
if (handle != 0)
snd_pcm_close (handle);
}
bool setParameters (unsigned int sampleRate, int numChannels, int bufferSize)
{
if (handle == 0)
return false;
snd_pcm_hw_params_t* hwParams;
snd_pcm_hw_params_alloca (&hwParams);
if (failed (snd_pcm_hw_params_any (handle, hwParams)))
return false;
if (snd_pcm_hw_params_set_access (handle, hwParams, SND_PCM_ACCESS_RW_NONINTERLEAVED) >= 0)
isInterleaved = false;
else if (snd_pcm_hw_params_set_access (handle, hwParams, SND_PCM_ACCESS_RW_INTERLEAVED) >= 0)
isInterleaved = true;
else
{
jassertfalse
return false;
}
const int formatsToTry[] = { SND_PCM_FORMAT_FLOAT_LE, 32, AudioDataConverters::float32LE,
SND_PCM_FORMAT_FLOAT_BE, 32, AudioDataConverters::float32BE,
SND_PCM_FORMAT_S32_LE, 32, AudioDataConverters::int32LE,
SND_PCM_FORMAT_S32_BE, 32, AudioDataConverters::int32BE,
SND_PCM_FORMAT_S24_LE, 24, AudioDataConverters::int24LE,
SND_PCM_FORMAT_S24_BE, 24, AudioDataConverters::int24BE,
SND_PCM_FORMAT_S16_LE, 16, AudioDataConverters::int16LE,
SND_PCM_FORMAT_S16_BE, 16, AudioDataConverters::int16BE };
bitDepth = 0;
for (int i = 0; i < numElementsInArray (formatsToTry); i += 3)
{
if (snd_pcm_hw_params_set_format (handle, hwParams, (_snd_pcm_format) formatsToTry [i]) >= 0)
{
bitDepth = formatsToTry [i + 1];
sampleFormat = (AudioDataConverters::DataFormat) formatsToTry [i + 2];
break;
}
}
if (bitDepth == 0)
{
error = T("device doesn't support a compatible PCM format");
DBG (T("ALSA error: ") + error + T("\n"));
return false;
}
int dir = 0;
unsigned int periods = 4;
snd_pcm_uframes_t samplesPerPeriod = bufferSize;
if (failed (snd_pcm_hw_params_set_rate_near (handle, hwParams, &sampleRate, 0))
|| failed (snd_pcm_hw_params_set_channels (handle, hwParams, numChannels))
|| failed (snd_pcm_hw_params_set_periods_near (handle, hwParams, &periods, &dir))
|| failed (snd_pcm_hw_params_set_period_size_near (handle, hwParams, &samplesPerPeriod, &dir))
|| failed (snd_pcm_hw_params (handle, hwParams)))
{
return false;
}
snd_pcm_sw_params_t* swParams;
snd_pcm_sw_params_alloca (&swParams);
if (failed (snd_pcm_sw_params_current (handle, swParams))
|| failed (snd_pcm_sw_params_set_silence_threshold (handle, swParams, 0))
|| failed (snd_pcm_sw_params_set_silence_size (handle, swParams, INT_MAX))
|| failed (snd_pcm_sw_params_set_start_threshold (handle, swParams, samplesPerPeriod))
|| failed (snd_pcm_sw_params_set_stop_threshold (handle, swParams, INT_MAX))
|| failed (snd_pcm_sw_params (handle, swParams)))
{
return false;
}
/*
#ifdef JUCE_DEBUG
// enable this to dump the config of the devices that get opened
snd_output_t* out;
snd_output_stdio_attach (&out, stderr, 0);
snd_pcm_hw_params_dump (hwParams, out);
snd_pcm_sw_params_dump (swParams, out);
#endif
*/
numChannelsRunning = numChannels;
return true;
}
//==============================================================================
bool write (float** const data, const int numSamples)
{
if (isInterleaved)
{
scratch.ensureSize (sizeof (float) * numSamples * numChannelsRunning, false);
float* interleaved = (float*) scratch;
AudioDataConverters::interleaveSamples ((const float**) data, interleaved, numSamples, numChannelsRunning);
AudioDataConverters::convertFloatToFormat (sampleFormat, interleaved, interleaved, numSamples * numChannelsRunning);
snd_pcm_sframes_t num = snd_pcm_writei (handle, (void*) interleaved, numSamples);
if (failed (num) && num != -EPIPE && num != -ESTRPIPE)
return false;
}
else
{
for (int i = 0; i < numChannelsRunning; ++i)
if (data[i] != 0)
AudioDataConverters::convertFloatToFormat (sampleFormat, data[i], data[i], numSamples);
snd_pcm_sframes_t num = snd_pcm_writen (handle, (void**) data, numSamples);
if (failed (num))
{
if (num == -EPIPE)
{
if (failed (snd_pcm_prepare (handle)))
return false;
}
else if (num != -ESTRPIPE)
return false;
}
}
return true;
}
bool read (float** const data, const int numSamples)
{
if (isInterleaved)
{
scratch.ensureSize (sizeof (float) * numSamples * numChannelsRunning, false);
float* interleaved = (float*) scratch;
snd_pcm_sframes_t num = snd_pcm_readi (handle, (void*) interleaved, numSamples);
if (failed (num))
{
if (num == -EPIPE)
{
if (failed (snd_pcm_prepare (handle)))
return false;
}
else if (num != -ESTRPIPE)
return false;
}
AudioDataConverters::convertFormatToFloat (sampleFormat, interleaved, interleaved, numSamples * numChannelsRunning);
AudioDataConverters::deinterleaveSamples (interleaved, data, numSamples, numChannelsRunning);
}
else
{
snd_pcm_sframes_t num = snd_pcm_readn (handle, (void**) data, numSamples);
if (failed (num) && num != -EPIPE && num != -ESTRPIPE)
return false;
for (int i = 0; i < numChannelsRunning; ++i)
if (data[i] != 0)
AudioDataConverters::convertFormatToFloat (sampleFormat, data[i], data[i], numSamples);
}
return true;
}
//==============================================================================
juce_UseDebuggingNewOperator
snd_pcm_t* handle;
String error;
int bitDepth, numChannelsRunning;
//==============================================================================
private:
const bool isInput;
bool isInterleaved;
MemoryBlock scratch;
AudioDataConverters::DataFormat sampleFormat;
//==============================================================================
bool failed (const int errorNum)
{
if (errorNum >= 0)
return false;
error = snd_strerror (errorNum);
DBG (T("ALSA error: ") + error + T("\n"));
return true;
}
};
//==============================================================================
class ALSAThread : public Thread
{
public:
ALSAThread (const String& deviceName_)
: Thread (T("Juce ALSA")),
sampleRate (0),
bufferSize (0),
deviceName (deviceName_),
outputDevice (0),
inputDevice (0),
numCallbacks (0),
callback (0),
totalNumInputChannels (0),
totalNumOutputChannels (0)
{
zeromem (outputChannelData, sizeof (outputChannelData));
zeromem (outputChannelDataForCallback, sizeof (outputChannelDataForCallback));
zeromem (inputChannelData, sizeof (inputChannelData));
zeromem (inputChannelDataForCallback, sizeof (inputChannelDataForCallback));
initialiseRatesAndChannels();
}
~ALSAThread()
{
close();
}
void open (const BitArray& inputChannels,
const BitArray& outputChannels,
const double sampleRate_,
const int bufferSize_)
{
close();
error = String::empty;
sampleRate = sampleRate_;
bufferSize = bufferSize_;
numChannelsRunning = jmax (inputChannels.getHighestBit(),
outputChannels.getHighestBit()) + 1;
numChannelsRunning = jmin (maxNumChans, jlimit ((int) minChansIn,
(int) maxChansIn,
numChannelsRunning));
if (inputChannels.getHighestBit() >= 0)
{
for (int i = 0; i < numChannelsRunning; ++i)
{
inputChannelData [i] = (float*) juce_calloc (sizeof (float) * bufferSize);
if (inputChannels[i])
inputChannelDataForCallback [totalNumInputChannels++] = inputChannelData [i];
}
}
if (outputChannels.getHighestBit() >= 0)
{
for (int i = 0; i < numChannelsRunning; ++i)
{
outputChannelData [i] = (float*) juce_calloc (sizeof (float) * bufferSize);
if (outputChannels[i])
outputChannelDataForCallback [totalNumOutputChannels++] = outputChannelData [i];
}
}
if (totalNumOutputChannels > 0)
{
outputDevice = new ALSADevice (deviceName, false);
if (outputDevice->error.isNotEmpty())
{
error = outputDevice->error;
deleteAndZero (outputDevice);
return;
}
if (! outputDevice->setParameters ((unsigned int) sampleRate, numChannelsRunning, bufferSize))
{
error = outputDevice->error;
deleteAndZero (outputDevice);
return;
}
}
if (totalNumInputChannels > 0)
{
inputDevice = new ALSADevice (deviceName, true);
if (inputDevice->error.isNotEmpty())
{
error = inputDevice->error;
deleteAndZero (inputDevice);
return;
}
if (! inputDevice->setParameters ((unsigned int) sampleRate, numChannelsRunning, bufferSize))
{
error = inputDevice->error;
deleteAndZero (inputDevice);
return;
}
}
if (outputDevice == 0 && inputDevice == 0)
{
error = T("no channels");
return;
}
if (outputDevice != 0 && inputDevice != 0)
{
snd_pcm_link (outputDevice->handle, inputDevice->handle);
}
if (inputDevice != 0 && failed (snd_pcm_prepare (inputDevice->handle)))
return;
if (outputDevice != 0 && failed (snd_pcm_prepare (outputDevice->handle)))
return;
startThread (9);
int count = 1000;
while (numCallbacks == 0)
{
sleep (5);
if (--count < 0 || ! isThreadRunning())
{
error = T("device didn't start");
break;
}
}
}
void close()
{
stopThread (6000);
deleteAndZero (inputDevice);
deleteAndZero (outputDevice);
for (int i = 0; i < maxNumChans; ++i)
{
juce_free (inputChannelData [i]);
juce_free (outputChannelData [i]);
}
zeromem (outputChannelData, sizeof (outputChannelData));
zeromem (outputChannelDataForCallback, sizeof (outputChannelDataForCallback));
zeromem (inputChannelData, sizeof (inputChannelData));
zeromem (inputChannelDataForCallback, sizeof (inputChannelDataForCallback));
totalNumOutputChannels = 0;
totalNumInputChannels = 0;
numChannelsRunning = 0;
numCallbacks = 0;
}
void setCallback (AudioIODeviceCallback* const newCallback)
{
const ScopedLock sl (callbackLock);
callback = newCallback;
}
void run()
{
while (! threadShouldExit())
{
if (inputDevice != 0)
{
jassert (numChannelsRunning >= inputDevice->numChannelsRunning);
if (! inputDevice->read (inputChannelData, bufferSize))
{
DBG (T("ALSA: read failure"));
break;
}
}
if (threadShouldExit())
break;
{
const ScopedLock sl (callbackLock);
++numCallbacks;
if (callback != 0)
{
callback->audioDeviceIOCallback ((const float**) inputChannelDataForCallback,
totalNumInputChannels,
outputChannelDataForCallback,
totalNumOutputChannels,
bufferSize);
}
else
{
for (int i = 0; i < totalNumOutputChannels; ++i)
zeromem (outputChannelDataForCallback[i], sizeof (float) * bufferSize);
}
}
if (outputDevice != 0)
{
failed (snd_pcm_wait (outputDevice->handle, 2000));
if (threadShouldExit())
break;
failed (snd_pcm_avail_update (outputDevice->handle));
jassert (numChannelsRunning >= outputDevice->numChannelsRunning);
if (! outputDevice->write (outputChannelData, bufferSize))
{
DBG (T("ALSA: write failure"));
break;
}
}
}
}
int getBitDepth() const
{
if (outputDevice != 0)
return outputDevice->bitDepth;
if (inputDevice != 0)
return inputDevice->bitDepth;
return 16;
}
//==============================================================================
juce_UseDebuggingNewOperator
String error;
double sampleRate;
int bufferSize;
Array <int> sampleRates;
StringArray channelNamesOut, channelNamesIn;
private:
//==============================================================================
const String deviceName;
ALSADevice* outputDevice;
ALSADevice* inputDevice;
int numCallbacks;
AudioIODeviceCallback* callback;
CriticalSection callbackLock;
float* outputChannelData [maxNumChans];
float* outputChannelDataForCallback [maxNumChans];
int totalNumInputChannels;
float* inputChannelData [maxNumChans];
float* inputChannelDataForCallback [maxNumChans];
int totalNumOutputChannels;
int numChannelsRunning;
unsigned int minChansOut, maxChansOut;
unsigned int minChansIn, maxChansIn;
bool failed (const int errorNum)
{
if (errorNum >= 0)
return false;
error = snd_strerror (errorNum);
DBG (T("ALSA error: ") + error + T("\n"));
return true;
}
void initialiseRatesAndChannels()
{
sampleRates.clear();
channelNamesOut.clear();
channelNamesIn.clear();
minChansOut = 0;
maxChansOut = 0;
minChansIn = 0;
maxChansIn = 0;
getDeviceProperties (deviceName, minChansOut, maxChansOut, minChansIn, maxChansIn, sampleRates);
unsigned int i;
for (i = 0; i < maxChansOut; ++i)
channelNamesOut.add (T("channel ") + String ((int) i + 1));
for (i = 0; i < maxChansIn; ++i)
channelNamesIn.add (T("channel ") + String ((int) i + 1));
}
};
//==============================================================================
class ALSAAudioIODevice : public AudioIODevice
{
public:
ALSAAudioIODevice (const String& deviceName,
const String& deviceId)
: AudioIODevice (deviceName, T("ALSA")),
isOpen_ (false),
isStarted (false),
internal (0)
{
internal = new ALSAThread (deviceId);
}
~ALSAAudioIODevice()
{
delete internal;
}
const StringArray getOutputChannelNames()
{
return internal->channelNamesOut;
}
const StringArray getInputChannelNames()
{
return internal->channelNamesIn;
}
int getNumSampleRates()
{
return internal->sampleRates.size();
}
double getSampleRate (int index)
{
return internal->sampleRates [index];
}
int getNumBufferSizesAvailable()
{
return 50;
}
int getBufferSizeSamples (int index)
{
int n = 16;
for (int i = 0; i < index; ++i)
n += n < 64 ? 16
: (n < 512 ? 32
: (n < 1024 ? 64
: (n < 2048 ? 128 : 256)));
return n;
}
int getDefaultBufferSize()
{
return 512;
}
const String open (const BitArray& inputChannels,
const BitArray& outputChannels,
double sampleRate,
int bufferSizeSamples)
{
close();
if (bufferSizeSamples <= 0)
bufferSizeSamples = getDefaultBufferSize();
if (sampleRate <= 0)
{
for (int i = 0; i < getNumSampleRates(); ++i)
{
if (getSampleRate (i) >= 44100)
{
sampleRate = getSampleRate (i);
break;
}
}
}
internal->open (inputChannels, outputChannels,
sampleRate, bufferSizeSamples);
isOpen_ = internal->error.isEmpty();
return internal->error;
}
void close()
{
stop();
internal->close();
isOpen_ = false;
}
bool isOpen()
{
return isOpen_;
}
int getCurrentBufferSizeSamples()
{
return internal->bufferSize;
}
double getCurrentSampleRate()
{
return internal->sampleRate;
}
int getCurrentBitDepth()
{
return internal->getBitDepth();
}
int getOutputLatencyInSamples()
{
return 0;
}
int getInputLatencyInSamples()
{
return 0;
}
void start (AudioIODeviceCallback* callback)
{
if (! isOpen_)
callback = 0;
internal->setCallback (callback);
isStarted = (callback != 0);
}
void stop()
{
start (0);
}
bool isPlaying()
{
return isStarted && internal->error.isEmpty();
}
const String getLastError()
{
return internal->error;
}
private:
bool isOpen_, isStarted;
ALSAThread* internal;
};
//==============================================================================
class ALSAAudioIODeviceType : public AudioIODeviceType
{
public:
//==============================================================================
ALSAAudioIODeviceType()
: AudioIODeviceType (T("ALSA")),
hasScanned (false)
{
}
~ALSAAudioIODeviceType()
{
}
//==============================================================================
void scanForDevices()
{
hasScanned = true;
names.clear();
ids.clear();
snd_ctl_t* handle;
snd_ctl_card_info_t* info;
snd_ctl_card_info_alloca (&info);
int cardNum = -1;
while (ids.size() <= 24)
{
snd_card_next (&cardNum);
if (cardNum < 0)
break;
if (snd_ctl_open (&handle, T("hw:") + String (cardNum), 0) >= 0)
{
if (snd_ctl_card_info (handle, info) >= 0)
{
String cardId (snd_ctl_card_info_get_id (info));
if (cardId.removeCharacters (T("0123456789")).isEmpty())
cardId = String (cardNum);
int device = -1;
for (;;)
{
if (snd_ctl_pcm_next_device (handle, &device) < 0 || device < 0)
break;
String id, name;
id << T("hw:") << cardId << T(",") << device;
if (testDevice (id))
{
name << snd_ctl_card_info_get_name (info);
if (name.isEmpty())
name = id;
if (device > 0)
name << T(" (") << (device + 1) << T(")");
ids.add (id);
names.add (name);
}
}
}
snd_ctl_close (handle);
}
}
}
const StringArray getDeviceNames (const bool /*preferInputNames*/) const
{
jassert (hasScanned); // need to call scanForDevices() before doing this
StringArray namesCopy (names);
namesCopy.removeDuplicates (true);
return namesCopy;
}
const String getDefaultDeviceName (const bool /*preferInputNames*/) const
{
jassert (hasScanned); // need to call scanForDevices() before doing this
return names[0];
}
AudioIODevice* createDevice (const String& deviceName)
{
jassert (hasScanned); // need to call scanForDevices() before doing this
const int index = names.indexOf (deviceName);
if (index >= 0)
return new ALSAAudioIODevice (deviceName, ids [index]);
return 0;
}
//==============================================================================
juce_UseDebuggingNewOperator
private:
StringArray names, ids;
bool hasScanned;
static bool testDevice (const String& id)
{
unsigned int minChansOut = 0, maxChansOut = 0;
unsigned int minChansIn = 0, maxChansIn = 0;
Array <int> rates;
getDeviceProperties (id, minChansOut, maxChansOut, minChansIn, maxChansIn, rates);
DBG (T("ALSA device: ") + id
+ T(" outs=") + String ((int) minChansOut) + T("-") + String ((int) maxChansOut)
+ T(" ins=") + String ((int) minChansIn) + T("-") + String ((int) maxChansIn)
+ T(" rates=") + String (rates.size()));
return (maxChansOut > 0 || maxChansIn > 0) && rates.size() > 0;
}
ALSAAudioIODeviceType (const ALSAAudioIODeviceType&);
const ALSAAudioIODeviceType& operator= (const ALSAAudioIODeviceType&);
};
//==============================================================================
AudioIODeviceType* juce_createDefaultAudioIODeviceType()
{
return new ALSAAudioIODeviceType();
}
END_JUCE_NAMESPACE
//==============================================================================
#else // if ALSA is turned off..
BEGIN_JUCE_NAMESPACE
#include "../../../src/juce_appframework/audio/devices/juce_AudioIODeviceType.h"
AudioIODeviceType* juce_createDefaultAudioIODeviceType() { return 0; }
END_JUCE_NAMESPACE
#endif
#endif

+ 110
- 0
build/linux/platform_specific_code/juce_linux_AudioCDReader.cpp View File

@@ -0,0 +1,110 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "../../../src/juce_core/basics/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "../../../src/juce_appframework/audio/audio_file_formats/juce_AudioCDReader.h"
//==============================================================================
AudioCDReader::AudioCDReader()
: AudioFormatReader (0, T("CD Audio"))
{
}
const StringArray AudioCDReader::getAvailableCDNames()
{
StringArray names;
return names;
}
AudioCDReader* AudioCDReader::createReaderForCD (const int index)
{
return 0;
}
AudioCDReader::~AudioCDReader()
{
}
void AudioCDReader::refreshTrackLengths()
{
}
bool AudioCDReader::read (int** destSamples,
int64 startSampleInFile,
int numSamples)
{
return false;
}
bool AudioCDReader::isCDStillPresent() const
{
return false;
}
int AudioCDReader::getNumTracks() const
{
return 0;
}
int AudioCDReader::getPositionOfTrackStart (int trackNum) const
{
return 0;
}
bool AudioCDReader::isTrackAudio (int trackNum) const
{
return false;
}
void AudioCDReader::enableIndexScanning (bool b)
{
}
int AudioCDReader::getLastIndex() const
{
return 0;
}
const Array<int> AudioCDReader::findIndexesInTrack (const int trackNumber)
{
return Array<int>();
}
int AudioCDReader::getCDDBId()
{
return 0;
}
END_JUCE_NAMESPACE

+ 60
- 0
build/linux/platform_specific_code/juce_linux_FileChooser.cpp View File

@@ -0,0 +1,60 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "../../../juce_Config.h"
#if JUCE_BUILD_GUI_CLASSES
#include "linuxincludes.h"
#include "../../../src/juce_core/basics/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "../../../src/juce_appframework/gui/components/filebrowser/juce_FileChooser.h"
//==============================================================================
void FileChooser::showPlatformDialog (OwnedArray<File>& results,
const String& title,
const File& file,
const String& filters,
bool isDirectory,
bool isSave,
bool warnAboutOverwritingExistingFiles,
bool selectMultipleFiles,
FilePreviewComponent* previewComponent)
{
//xxx ain't got one!
jassertfalse
}
END_JUCE_NAMESPACE
#endif

+ 603
- 0
build/linux/platform_specific_code/juce_linux_Files.cpp View File

@@ -0,0 +1,603 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "linuxincludes.h"
#include "../../../src/juce_core/basics/juce_StandardHeader.h"
#include <sys/stat.h>
#include <sys/dir.h>
#include <sys/ptrace.h>
#include <sys/vfs.h> // for statfs
#include <sys/wait.h>
#include <unistd.h>
#include <fnmatch.h>
#include <utime.h>
#include <pwd.h>
#include <fcntl.h>
#define U_ISOFS_SUPER_MAGIC (short) 0x9660 // linux/iso_fs.h
#define U_MSDOS_SUPER_MAGIC (short) 0x4d44 // linux/msdos_fs.h
#define U_NFS_SUPER_MAGIC (short) 0x6969 // linux/nfs_fs.h
#define U_SMB_SUPER_MAGIC (short) 0x517B // linux/smb_fs.h
BEGIN_JUCE_NAMESPACE
#include "../../../src/juce_core/io/files/juce_FileInputStream.h"
#include "../../../src/juce_core/io/files/juce_FileOutputStream.h"
#include "../../../src/juce_core/basics/juce_SystemStats.h"
#include "../../../src/juce_core/basics/juce_Time.h"
#include "../../../src/juce_core/io/network/juce_URL.h"
#include "../../../src/juce_core/io/files/juce_NamedPipe.h"
static File executableFile;
//==============================================================================
bool juce_isDirectory (const String& fileName)
{
if (fileName.isEmpty())
return true;
struct stat info;
const int res = stat (fileName.toUTF8(), &info);
if (res == 0)
return (info.st_mode & S_IFDIR) != 0;
return false;
}
bool juce_fileExists (const String& fileName, const bool dontCountDirectories)
{
if (fileName.isEmpty())
return false;
bool exists = access (fileName.toUTF8(), F_OK) == 0;
if (exists && dontCountDirectories && juce_isDirectory (fileName))
exists = false;
return exists;
}
int64 juce_getFileSize (const String& fileName)
{
struct stat info;
const int res = stat (fileName.toUTF8(), &info);
if (res == 0)
return info.st_size;
return 0;
}
void juce_getFileTimes (const String& fileName,
int64& modificationTime,
int64& accessTime,
int64& creationTime)
{
modificationTime = 0;
accessTime = 0;
creationTime = 0;
struct stat info;
const int res = stat (fileName.toUTF8(), &info);
if (res == 0)
{
/*
* Note: On Linux the st_ctime field is defined as last change time
* rather than creation.
*/
modificationTime = (int64) info.st_mtime * 1000;
accessTime = (int64) info.st_atime * 1000;
creationTime = (int64) info.st_ctime * 1000;
}
}
bool juce_setFileTimes (const String& fileName,
int64 modificationTime,
int64 accessTime,
int64 creationTime)
{
struct utimbuf times;
times.actime = (time_t) (accessTime / 1000);
times.modtime = (time_t) (modificationTime / 1000);
return utime (fileName.toUTF8(), &times) == 0;
}
bool juce_canWriteToFile (const String& fileName)
{
return access (fileName.toUTF8(), W_OK) == 0;
}
bool juce_setFileReadOnly (const String& fileName, bool isReadOnly)
{
struct stat info;
const int res = stat (fileName.toUTF8(), &info);
if (res != 0)
return false;
info.st_mode &= 0777; // Just permissions
if( isReadOnly )
info.st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
else
// Give everybody write permission?
info.st_mode |= S_IWUSR | S_IWGRP | S_IWOTH;
return chmod (fileName.toUTF8(), info.st_mode) == 0;
}
bool juce_deleteFile (const String& fileName)
{
if (juce_isDirectory (fileName))
return rmdir (fileName.toUTF8()) == 0;
else
return remove (fileName.toUTF8()) == 0;
}
bool juce_copyFile (const String& s, const String& d)
{
const File source (s), dest (d);
FileInputStream* in = source.createInputStream();
bool ok = false;
if (in != 0)
{
if (dest.deleteFile())
{
FileOutputStream* const out = dest.createOutputStream();
if (out != 0)
{
const int bytesCopied = out->writeFromInputStream (*in, -1);
delete out;
ok = (bytesCopied == source.getSize());
if (! ok)
dest.deleteFile();
}
}
delete in;
}
return ok;
}
bool juce_moveFile (const String& source, const String& dest)
{
if (rename (source.toUTF8(), dest.toUTF8()) == 0)
return true;
if (! juce_canWriteToFile (source))
return false;
if (juce_copyFile (source, dest))
{
if (juce_deleteFile (source))
return true;
juce_deleteFile (dest);
}
return false;
}
void juce_createDirectory (const String& fileName)
{
mkdir (fileName.toUTF8(), 0777);
}
void* juce_fileOpen (const String& fileName, bool forWriting)
{
const char* mode = "rb";
if (forWriting)
{
if (juce_fileExists (fileName, false))
{
FILE* f = fopen (fileName.toUTF8(), "r+b");
if (f != 0)
fseek (f, 0, SEEK_END);
return (void*) f;
}
else
{
mode = "w+b";
}
}
return (void*)fopen (fileName.toUTF8(), mode);
}
void juce_fileClose (void* handle)
{
if (handle != 0)
fclose ((FILE*) handle);
}
int juce_fileRead (void* handle, void* buffer, int size)
{
if (handle != 0)
return fread (buffer, 1, size, (FILE*) handle);
return 0;
}
int juce_fileWrite (void* handle, const void* buffer, int size)
{
if (handle != 0)
return fwrite (buffer, 1, size, (FILE*) handle);
return 0;
}
int64 juce_fileSetPosition (void* handle, int64 pos)
{
if (handle != 0 && fseek ((FILE*) handle, (long) pos, SEEK_SET) == 0)
return pos;
return -1;
}
int64 juce_fileGetPosition (void* handle)
{
if (handle != 0)
return ftell ((FILE*) handle);
else
return -1;
}
void juce_fileFlush (void* handle)
{
if (handle != 0)
fflush ((FILE*) handle);
}
const StringArray juce_getFileSystemRoots()
{
StringArray s;
s.add (T("/"));
return s;
}
const String juce_getVolumeLabel (const String& filenameOnVolume,
int& volumeSerialNumber)
{
// There is no equivalent on Linux
volumeSerialNumber = 0;
return String::empty;
}
int64 File::getBytesFreeOnVolume() const throw()
{
struct statfs buf;
int64 free_space = 0;
if (statfs (getFullPathName().toUTF8(), &buf) == 0)
{
// Note: this returns space available to non-super user
free_space = (int64) buf.f_bsize * (int64) buf.f_bavail;
}
return free_space;
}
bool File::isOnCDRomDrive() const throw()
{
struct statfs buf;
if (statfs (getFullPathName().toUTF8(), &buf) == 0)
return (buf.f_type == U_ISOFS_SUPER_MAGIC);
// Assume not if this fails for some reason
return false;
}
bool File::isOnHardDisk() const throw()
{
struct statfs buf;
if (statfs (getFullPathName().toUTF8(), &buf) == 0)
{
switch (buf.f_type)
{
case U_ISOFS_SUPER_MAGIC: // CD-ROM
case U_MSDOS_SUPER_MAGIC: // Probably floppy (but could be mounted FAT filesystem)
case U_NFS_SUPER_MAGIC: // Network NFS
case U_SMB_SUPER_MAGIC: // Network Samba
return false;
default:
// Assume anything else is a hard-disk (but note it could
// be a RAM disk. There isn't a good way of determining
// this for sure)
return true;
}
}
// Assume so if this fails for some reason
return true;
}
//==============================================================================
const File File::getSpecialLocation (const SpecialLocationType type)
{
switch (type)
{
case userHomeDirectory:
{
const char* homeDir = getenv ("HOME");
if (homeDir == 0)
{
struct passwd* const pw = getpwuid (getuid());
if (pw != 0)
homeDir = pw->pw_dir;
}
return File (String (homeDir));
}
case userDocumentsDirectory:
return File (T("~"));
case userDesktopDirectory:
return File (T("~/Desktop"));
case userApplicationDataDirectory:
return File (T("~"));
case commonApplicationDataDirectory:
return File (T("/var"));
case globalApplicationsDirectory:
return File (T("/usr"));
case tempDirectory:
{
File tmp (T("/var/tmp"));
if (! tmp.isDirectory())
{
tmp = T("/tmp");
if (! tmp.isDirectory())
tmp = File::getCurrentWorkingDirectory();
}
return tmp;
}
case currentExecutableFile:
case currentApplicationFile:
// if this fails, it's probably because juce_setCurrentExecutableFileName()
// was never called to set the filename - this should be done by the juce
// main() function, so maybe you've hacked it to use your own custom main()?
jassert (executableFile.exists());
return executableFile;
default:
jassertfalse // unknown type?
break;
}
return File::nonexistent;
}
//==============================================================================
void juce_setCurrentExecutableFileName (const String& filename)
{
executableFile = File::getCurrentWorkingDirectory().getChildFile (filename);
}
//==============================================================================
const File File::getCurrentWorkingDirectory() throw()
{
char buf [2048];
getcwd (buf, sizeof(buf));
return File (String::fromUTF8 ((const uint8*) buf));
}
bool File::setAsCurrentWorkingDirectory() const throw()
{
return chdir (getFullPathName().toUTF8()) == 0;
}
//==============================================================================
const tchar File::separator = T('/');
const tchar* File::separatorString = T("/");
//==============================================================================
struct FindFileStruct
{
String parentDir, wildCard;
DIR* dir;
bool getNextMatch (String& result, bool* const isDir, bool* const isHidden, int64* const fileSize,
Time* const modTime, Time* const creationTime, bool* const isReadOnly)
{
const char* const wildcardUTF8 = wildCard.toUTF8();
for (;;)
{
struct dirent* const de = readdir (dir);
if (de == 0)
break;
if (fnmatch (wildcardUTF8, de->d_name, FNM_CASEFOLD) == 0)
{
result = String::fromUTF8 ((const uint8*) de->d_name);
const String path (parentDir + result);
if (isDir != 0 || fileSize != 0)
{
struct stat info;
const bool statOk = (stat (path.toUTF8(), &info) == 0);
if (isDir != 0)
*isDir = path.isEmpty() || (statOk && ((info.st_mode & S_IFDIR) != 0));
if (isHidden != 0)
*isHidden = (de->d_name[0] == '.');
if (fileSize != 0)
*fileSize = statOk ? info.st_size : 0;
}
if (modTime != 0 || creationTime != 0)
{
int64 m, a, c;
juce_getFileTimes (path, m, a, c);
if (modTime != 0)
*modTime = m;
if (creationTime != 0)
*creationTime = c;
}
if (isReadOnly != 0)
*isReadOnly = ! juce_canWriteToFile (path);
return true;
}
}
return false;
}
};
// returns 0 on failure
void* juce_findFileStart (const String& directory, const String& wildCard, String& firstResultFile,
bool* isDir, bool* isHidden, int64* fileSize, Time* modTime, Time* creationTime, bool* isReadOnly)
{
DIR* d = opendir (directory.toUTF8());
if (d != 0)
{
FindFileStruct* ff = new FindFileStruct();
ff->parentDir = directory;
if (!ff->parentDir.endsWithChar (File::separator))
ff->parentDir += File::separator;
ff->wildCard = wildCard;
if (wildCard == T("*.*"))
ff->wildCard = T("*");
ff->dir = d;
if (ff->getNextMatch (firstResultFile, isDir, isHidden, fileSize, modTime, creationTime, isReadOnly))
{
return ff;
}
else
{
firstResultFile = String::empty;
isDir = false;
isHidden = false;
closedir (d);
delete ff;
}
}
return 0;
}
bool juce_findFileNext (void* handle, String& resultFile,
bool* isDir, bool* isHidden, int64* fileSize, Time* modTime, Time* creationTime, bool* isReadOnly)
{
FindFileStruct* const ff = (FindFileStruct*) handle;
if (ff != 0)
return ff->getNextMatch (resultFile, isDir, isHidden, fileSize, modTime, creationTime, isReadOnly);
return false;
}
void juce_findFileClose (void* handle)
{
FindFileStruct* const ff = (FindFileStruct*) handle;
if (ff != 0)
{
closedir (ff->dir);
delete ff;
}
}
bool juce_launchFile (const String& fileName,
const String& parameters)
{
String cmdString (fileName);
cmdString << " " << parameters;
if (URL::isProbablyAWebsiteURL (cmdString) || URL::isProbablyAnEmailAddress (cmdString))
{
// create a command that tries to launch a bunch of likely browsers
const char* const browserNames[] = { "/etc/alternatives/x-www-browser", "firefox", "mozilla", "konqueror", "opera" };
StringArray cmdLines;
for (int i = 0; i < numElementsInArray (browserNames); ++i)
cmdLines.add (String (browserNames[i]) + T(" ") + cmdString.trim().quoted());
cmdString = cmdLines.joinIntoString (T(" || "));
}
char* const argv[4] = { "/bin/sh", "-c", (char*) cmdString.toUTF8(), 0 };
const int cpid = fork();
if (cpid == 0)
{
setsid();
// Child process
execve (argv[0], argv, environ);
exit (0);
}
return cpid >= 0;
}
END_JUCE_NAMESPACE

+ 627
- 0
build/linux/platform_specific_code/juce_linux_Fonts.cpp View File

@@ -0,0 +1,627 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "../../../juce_Config.h"
#if JUCE_BUILD_GUI_CLASSES
#include "linuxincludes.h"
#include <ft2build.h>
#include FT_FREETYPE_H
#include "../../../src/juce_core/basics/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "../../../src/juce_appframework/gui/graphics/fonts/juce_Font.h"
#include "../../../src/juce_core/io/streams/juce_MemoryInputStream.h"
#include "../../../src/juce_core/io/files/juce_DirectoryIterator.h"
#include "../../../src/juce_core/text/juce_XmlDocument.h"
#include "../../../src/juce_appframework/application/juce_DeletedAtShutdown.h"
//==============================================================================
class FreeTypeFontFace
{
public:
//==============================================================================
enum FontStyle
{
Plain = 0,
Bold = 1,
Italic = 2
};
struct FontNameIndex
{
String fileName;
int faceIndex;
};
//==============================================================================
FreeTypeFontFace (const String& familyName)
: hasSerif (false),
monospaced (false)
{
family = familyName;
}
void setFileName (const String& name,
const int faceIndex,
FontStyle style)
{
if (names[(int) style].fileName.isEmpty())
{
names[(int) style].fileName = name;
names[(int) style].faceIndex = faceIndex;
}
}
const String& getFamilyName() const throw()
{
return family;
}
const String& getFileName (int style, int* faceIndex) const throw()
{
*faceIndex = names [style].faceIndex;
return names[style].fileName;
}
void setMonospaced (bool mono) { monospaced = mono; }
bool getMonospaced () const throw() { return monospaced; }
void setSerif (const bool serif) { hasSerif = serif; }
bool getSerif () const throw() { return hasSerif; }
private:
//==============================================================================
String family;
FontNameIndex names[4];
bool hasSerif, monospaced;
};
//==============================================================================
class FreeTypeInterface : public DeletedAtShutdown
{
public:
//==============================================================================
FreeTypeInterface()
: lastFace (0),
lastBold (false),
lastItalic (false)
{
if (FT_Init_FreeType (&ftLib) != 0)
{
ftLib = 0;
DBG (T("Failed to initialize FreeType"));
}
StringArray fontDirs;
fontDirs.addTokens (String (getenv ("JUCE_FONT_PATH")), T(";,"), 0);
fontDirs.removeEmptyStrings (true);
if (fontDirs.size() == 0)
{
XmlDocument fontsConfig (File (T("/etc/fonts/fonts.conf")));
XmlElement* const fontsInfo = fontsConfig.getDocumentElement();
if (fontsInfo != 0)
{
forEachXmlChildElementWithTagName (*fontsInfo, e, T("dir"))
{
fontDirs.add (e->getAllSubText().trim());
}
delete fontsInfo;
}
}
if (fontDirs.size() == 0)
fontDirs.add (T("/usr/X11R6/lib/X11/fonts"));
for (int i = 0; i < fontDirs.size(); ++i)
enumerateFaces (fontDirs[i]);
}
~FreeTypeInterface()
{
if (lastFace != 0)
FT_Done_Face (lastFace);
if (ftLib != 0)
FT_Done_FreeType (ftLib);
}
//==============================================================================
FreeTypeFontFace* findOrCreate (const String& familyName,
const bool create = false)
{
for (int i = 0; i < faces.size(); i++)
if (faces[i]->getFamilyName() == familyName)
return faces[i];
if (! create)
return NULL;
FreeTypeFontFace* newFace = new FreeTypeFontFace (familyName);
faces.add (newFace);
return newFace;
}
// Enumerate all font faces available in a given directory
void enumerateFaces (const String& path)
{
File dirPath (path);
if (path.isEmpty() || ! dirPath.isDirectory())
return;
DirectoryIterator di (dirPath, true);
while (di.next())
{
File possible (di.getFile());
if (possible.hasFileExtension (T("ttf"))
|| possible.hasFileExtension (T("pfb"))
|| possible.hasFileExtension (T("pcf")))
{
FT_Face face;
int faceIndex = 0;
int numFaces = 0;
do
{
if (FT_New_Face (ftLib,
possible.getFullPathName(),
faceIndex,
&face) == 0)
{
if (faceIndex == 0)
numFaces = face->num_faces;
if ((face->face_flags & FT_FACE_FLAG_SCALABLE) != 0)
{
FreeTypeFontFace* const newFace = findOrCreate (face->family_name, true);
int style = (int) FreeTypeFontFace::Plain;
if ((face->style_flags & FT_STYLE_FLAG_BOLD) != 0)
style |= (int) FreeTypeFontFace::Bold;
if ((face->style_flags & FT_STYLE_FLAG_ITALIC) != 0)
style |= (int) FreeTypeFontFace::Italic;
newFace->setFileName (possible.getFullPathName(), faceIndex, (FreeTypeFontFace::FontStyle) style);
if ((face->face_flags & FT_FACE_FLAG_FIXED_WIDTH) != 0)
newFace->setMonospaced (true);
else
newFace->setMonospaced (false);
// Surely there must be a better way to do this?
if (String (face->family_name).containsIgnoreCase (T("Sans"))
|| String (face->family_name).containsIgnoreCase (T("Verdana"))
|| String (face->family_name).containsIgnoreCase (T("Arial")))
{
newFace->setSerif (false);
}
else
{
newFace->setSerif (true);
}
}
FT_Done_Face (face);
}
++faceIndex;
}
while (faceIndex < numFaces);
}
}
}
// Create a FreeType face object for a given font
FT_Face createFT_Face (const String& fontName,
const bool bold,
const bool italic)
{
FT_Face face = NULL;
if (fontName == lastFontName && bold == lastBold && italic == lastItalic)
{
face = lastFace;
}
else
{
if (lastFace)
{
FT_Done_Face (lastFace);
lastFace = NULL;
}
lastFontName = fontName;
lastBold = bold;
lastItalic = italic;
FreeTypeFontFace* const ftFace = findOrCreate (fontName);
if (ftFace != 0)
{
int style = (int) FreeTypeFontFace::Plain;
if (bold)
style |= (int) FreeTypeFontFace::Bold;
if (italic)
style |= (int) FreeTypeFontFace::Italic;
int faceIndex;
String fileName (ftFace->getFileName (style, &faceIndex));
if (fileName.isEmpty())
{
style ^= (int) FreeTypeFontFace::Bold;
fileName = ftFace->getFileName (style, &faceIndex);
if (fileName.isEmpty())
{
style ^= (int) FreeTypeFontFace::Bold;
style ^= (int) FreeTypeFontFace::Italic;
fileName = ftFace->getFileName (style, &faceIndex);
if (! fileName.length())
{
style ^= (int) FreeTypeFontFace::Bold;
fileName = ftFace->getFileName (style, &faceIndex);
}
}
}
if (! FT_New_Face (ftLib, (const char*) fileName, faceIndex, &lastFace))
{
face = lastFace;
// If there isn't a unicode charmap then select the first one.
if (FT_Select_Charmap (face, ft_encoding_unicode))
FT_Set_Charmap (face, face->charmaps[0]);
}
}
}
return face;
}
void addGlyph (FT_Face face, Typeface& dest, uint32 character)
{
const unsigned int glyphIndex = FT_Get_Char_Index (face, character);
const float height = (float) (face->ascender - face->descender);
const float scaleX = 1.0f / height;
const float scaleY = -1.0f / height;
Path destShape;
#define CONVERTX(val) (scaleX * (val).x)
#define CONVERTY(val) (scaleY * (val).y)
if (FT_Load_Glyph (face, glyphIndex, FT_LOAD_NO_SCALE
| FT_LOAD_NO_BITMAP
| FT_LOAD_IGNORE_TRANSFORM) != 0
|| face->glyph->format != ft_glyph_format_outline)
{
return;
}
const FT_Outline* const outline = &face->glyph->outline;
const short* const contours = outline->contours;
const char* const tags = outline->tags;
FT_Vector* const points = outline->points;
for (int c = 0; c < outline->n_contours; c++)
{
const int startPoint = (c == 0) ? 0 : contours [c - 1] + 1;
const int endPoint = contours[c];
for (int p = startPoint; p <= endPoint; p++)
{
const float x = CONVERTX (points[p]);
const float y = CONVERTY (points[p]);
if (p == startPoint)
{
destShape.startNewSubPath (x, y);
}
else if (FT_CURVE_TAG (tags[p]) == FT_Curve_Tag_On)
{
destShape.lineTo (x, y);
}
else if (FT_CURVE_TAG (tags[p]) == FT_Curve_Tag_Conic)
{
const int nextIndex = (p == endPoint) ? startPoint : p + 1;
float x2 = CONVERTX (points [nextIndex]);
float y2 = CONVERTY (points [nextIndex]);
if (FT_CURVE_TAG (tags [nextIndex]) == FT_Curve_Tag_Conic)
{
x2 = (x + x2) * 0.5f;
y2 = (y + y2) * 0.5f;
}
else
{
++p;
}
destShape.quadraticTo (x, y, x2, y2);
}
else if (FT_CURVE_TAG (tags[p]) == FT_Curve_Tag_Cubic)
{
if (p > endPoint-1)
return;
const int next1 = p + 1;
const int next2 = (p == (endPoint - 1)) ? startPoint : p + 2;
float x2 = CONVERTX (points [next1]);
float y2 = CONVERTY (points [next1]);
float x3 = CONVERTX (points [next2]);
float y3 = CONVERTY (points [next2]);
if (FT_CURVE_TAG(tags[next1]) != FT_Curve_Tag_Cubic)
return;
if (FT_CURVE_TAG(tags[next2]) != FT_Curve_Tag_On)
return;
destShape.cubicTo (x, y, x2, y2, x3, y3);
p += 2;
}
}
destShape.closeSubPath();
}
dest.addGlyph (character, destShape, face->glyph->metrics.horiAdvance/height);
if ((face->face_flags & FT_FACE_FLAG_KERNING) != 0)
addKerning (face, dest, character, glyphIndex);
}
void addKerning (FT_Face face, Typeface& dest, const uint32 character, const uint32 glyphIndex)
{
const float height = (float) (face->ascender - face->descender);
uint32 rightGlyphIndex;
uint32 rightCharCode = FT_Get_First_Char (face, &rightGlyphIndex);
while (rightGlyphIndex != 0)
{
FT_Vector kerning;
if (FT_Get_Kerning (face, glyphIndex, rightGlyphIndex, ft_kerning_unscaled, &kerning) == 0)
{
if (kerning.x != 0)
dest.addKerningPair (character, rightCharCode, kerning.x / height);
}
rightCharCode = FT_Get_Next_Char (face, rightCharCode, &rightGlyphIndex);
}
}
// Add a glyph to a font
bool addGlyphToFont (const uint32 character,
const tchar* fontName, bool bold, bool italic,
Typeface& dest)
{
FT_Face face = createFT_Face (fontName, bold, italic);
if (face != 0)
{
addGlyph (face, dest, character);
return true;
}
return false;
}
// Create a Typeface object for given name/style
bool createTypeface (const String& fontName,
const bool bold, const bool italic,
Typeface& dest,
const bool addAllGlyphs)
{
dest.clear();
dest.setName (fontName);
dest.setBold (bold);
dest.setItalic (italic);
FT_Face face = createFT_Face (fontName, bold, italic);
if (face == 0)
{
#ifdef JUCE_DEBUG
String msg (T("Failed to create typeface: "));
msg << fontName << " " << (bold ? 'B' : ' ') << (italic ? 'I' : ' ');
DBG (msg);
#endif
return face;
}
const float height = (float) (face->ascender - face->descender);
dest.setAscent (face->ascender / height);
dest.setDefaultCharacter (L' ');
if (addAllGlyphs)
{
uint32 glyphIndex;
uint32 charCode = FT_Get_First_Char (face, &glyphIndex);
while (glyphIndex != 0)
{
addGlyph (face, dest, charCode);
charCode = FT_Get_Next_Char (face, charCode, &glyphIndex);
}
}
return true;
}
//==============================================================================
void getFamilyNames (StringArray& familyNames) const
{
for (int i = 0; i < faces.size(); i++)
familyNames.add (faces[i]->getFamilyName());
}
void getMonospacedNames (StringArray& monoSpaced) const
{
for (int i = 0; i < faces.size(); i++)
if (faces[i]->getMonospaced())
monoSpaced.add (faces[i]->getFamilyName());
}
void getSerifNames (StringArray& serif) const
{
for (int i = 0; i < faces.size(); i++)
if (faces[i]->getSerif())
serif.add (faces[i]->getFamilyName());
}
void getSansSerifNames (StringArray& sansSerif) const
{
for (int i = 0; i < faces.size(); i++)
if (! faces[i]->getSerif())
sansSerif.add (faces[i]->getFamilyName());
}
static FreeTypeInterface* getInstance()
{
static FreeTypeInterface* instance = 0;
if (instance == 0)
instance = new FreeTypeInterface();
return instance;
}
private:
//==============================================================================
FT_Library ftLib;
FT_Face lastFace;
String lastFontName;
bool lastBold, lastItalic;
OwnedArray<FreeTypeFontFace> faces;
};
//==============================================================================
void Typeface::initialiseTypefaceCharacteristics (const String& fontName,
bool bold, bool italic,
bool addAllGlyphsToFont)
{
FreeTypeInterface::getInstance()
->createTypeface (fontName, bold, italic, *this, addAllGlyphsToFont);
}
void Typeface::findAndAddSystemGlyph (juce_wchar character)
{
FreeTypeInterface::getInstance()
->addGlyphToFont (character, getName(), isBold(), isItalic(), *this);
}
const StringArray Font::findAllTypefaceNames()
{
StringArray s;
FreeTypeInterface::getInstance()->getFamilyNames (s);
s.sort (true);
return s;
}
static const String pickBestFont (const StringArray& names,
const char* const choicesString)
{
StringArray choices;
choices.addTokens (String (choicesString), T(","), 0);
choices.trim();
choices.removeEmptyStrings();
int i, j;
for (j = 0; j < choices.size(); ++j)
if (names.contains (choices[j], true))
return choices[j];
for (j = 0; j < choices.size(); ++j)
for (i = 0; i < names.size(); i++)
if (names[i].startsWithIgnoreCase (choices[j]))
return names[i];
for (j = 0; j < choices.size(); ++j)
for (i = 0; i < names.size(); i++)
if (names[i].containsIgnoreCase (choices[j]))
return names[i];
return names[0];
}
static const String linux_getDefaultSansSerifFontName()
{
StringArray allFonts;
FreeTypeInterface::getInstance()->getSansSerifNames (allFonts);
return pickBestFont (allFonts, "Verdana, Bitstream Vera Sans, Luxi Sans, Sans");
}
static const String linux_getDefaultSerifFontName()
{
StringArray allFonts;
FreeTypeInterface::getInstance()->getSerifNames (allFonts);
return pickBestFont (allFonts, "Bitstream Vera Serif, Times, Nimbus Roman, Serif");
}
static const String linux_getDefaultMonospacedFontName()
{
StringArray allFonts;
FreeTypeInterface::getInstance()->getMonospacedNames (allFonts);
return pickBestFont (allFonts, "Bitstream Vera Sans Mono, Courier, Sans Mono, Mono");
}
void Font::getDefaultFontNames (String& defaultSans, String& defaultSerif, String& defaultFixed)
{
defaultSans = linux_getDefaultSansSerifFontName();
defaultSerif = linux_getDefaultSerifFontName();
defaultFixed = linux_getDefaultMonospacedFontName();
}
END_JUCE_NAMESPACE
#endif

+ 399
- 0
build/linux/platform_specific_code/juce_linux_Messaging.cpp View File

@@ -0,0 +1,399 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "../../../juce_Config.h"
#if JUCE_BUILD_GUI_CLASSES
#include "linuxincludes.h"
#include <stdio.h>
#include <signal.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xresource.h>
#include <X11/Xutil.h>
#include "../../../src/juce_core/basics/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "../../../src/juce_appframework/events/juce_MessageManager.h"
#include "../../../src/juce_core/threads/juce_WaitableEvent.h"
#include "../../../src/juce_core/threads/juce_Process.h"
#include "../../../src/juce_core/threads/juce_ScopedLock.h"
#ifdef JUCE_DEBUG
#define JUCE_DEBUG_XERRORS 1
#endif
Display* display = 0; // This is also referenced from WindowDriver.cpp
static Window juce_messageWindowHandle = None;
#define SpecialAtom "JUCESpecialAtom"
#define BroadcastAtom "JUCEBroadcastAtom"
#define SpecialCallbackAtom "JUCESpecialCallbackAtom"
static Atom specialId;
static Atom broadcastId;
static Atom specialCallbackId;
// This is referenced from WindowDriver.cpp
XContext improbableNumber;
// Defined in WindowDriver.cpp
extern void juce_windowMessageReceive (XEvent* event);
struct MessageThreadFuncCall
{
MessageCallbackFunction* func;
void* parameter;
void* result;
CriticalSection lock;
WaitableEvent event;
};
static bool errorCondition = false;
// (defined in another file to avoid problems including certain headers in this one)
extern bool juce_isRunningAsApplication();
// Usually happens when client-server connection is broken
static int ioErrorHandler (Display* display)
{
DBG (T("ERROR: connection to X server broken.. terminating."));
errorCondition = true;
if (! juce_isRunningAsApplication())
Process::terminate();
return 0;
}
// A protocol error has occurred
static int errorHandler (Display* display, XErrorEvent* event)
{
#ifdef JUCE_DEBUG_XERRORS
char errorStr[64] = { 0 };
char requestStr[64] = { 0 };
XGetErrorText (display, event->error_code, errorStr, 64);
XGetErrorDatabaseText (display,
"XRequest",
(const char*) String (event->request_code),
"Unknown",
requestStr,
64);
DBG (T("ERROR: X returned ") + String (errorStr) + T(" for operation ") + String (requestStr));
#endif
return 0;
}
static bool breakIn = false;
// Breakin from keyboard
static void sig_handler (int sig)
{
if (sig == SIGINT)
{
breakIn = true;
return;
}
static bool reentrant = false;
if (reentrant == false)
{
reentrant = true;
// Illegal instruction
fflush (stdout);
Logger::outputDebugString ("ERROR: Program executed illegal instruction.. terminating");
errorCondition = true;
if (juce_isRunningAsApplication())
Process::terminate();
}
else
{
if (juce_isRunningAsApplication())
exit(0);
}
}
//==============================================================================
void MessageManager::doPlatformSpecificInitialisation()
{
// This is called if the client/server connection is broken
XSetIOErrorHandler (ioErrorHandler);
// This is called if a protocol error occurs
XSetErrorHandler (errorHandler);
// Install signal handler for break-in
struct sigaction saction;
sigset_t maskSet;
sigemptyset (&maskSet);
saction.sa_handler = sig_handler;
saction.sa_mask = maskSet;
saction.sa_flags = 0;
sigaction (SIGINT, &saction, NULL);
#ifndef _DEBUG
// Setup signal handlers for various fatal errors
sigaction (SIGILL, &saction, NULL);
sigaction (SIGBUS, &saction, NULL);
sigaction (SIGFPE, &saction, NULL);
sigaction (SIGSEGV, &saction, NULL);
sigaction (SIGSYS, &saction, NULL);
#endif
// Initialise xlib for multiple thread support
if (! XInitThreads())
{
// This is fatal! Print error and closedown
Logger::outputDebugString (T("Failed to initialise xlib thread support."));
if (juce_isRunningAsApplication())
Process::terminate();
}
String displayName (getenv ("DISPLAY"));
if (displayName.isEmpty())
displayName = T(":0.0");
display = XOpenDisplay (displayName);
if (display == 0)
{
// This is fatal! Print error and closedown
Logger::outputDebugString ("Failed to open the X display.");
if (juce_isRunningAsApplication())
Process::terminate();
}
// Get defaults for various properties
int screen = DefaultScreen (display);
Window root = RootWindow (display, screen);
Visual* visual = DefaultVisual (display, screen);
// Create atoms for our ClientMessages (these cannot be deleted)
specialId = XInternAtom (display, SpecialAtom, false);
broadcastId = XInternAtom (display, BroadcastAtom, false);
specialCallbackId = XInternAtom (display, SpecialCallbackAtom, false);
// Create a context to store user data associated with Windows we
// create in WindowDriver
improbableNumber = XUniqueContext();
// We're only interested in client messages for this window
// which are always sent
XSetWindowAttributes swa;
swa.event_mask = NoEventMask;
// Create our message window (this will never be mapped)
juce_messageWindowHandle = XCreateWindow (display, root,
0, 0, 1, 1, 0, 0, InputOnly,
visual, CWEventMask, &swa);
}
void MessageManager::doPlatformSpecificShutdown()
{
if (errorCondition == false)
{
XDestroyWindow (display, juce_messageWindowHandle);
XCloseDisplay (display);
}
}
bool juce_postMessageToSystemQueue (void* message)
{
if (errorCondition)
return false;
XClientMessageEvent clientMsg;
clientMsg.display = display;
clientMsg.window = juce_messageWindowHandle;
clientMsg.type = ClientMessage;
clientMsg.format = 32;
clientMsg.message_type = specialId;
#if JUCE_64BIT
clientMsg.data.l[0] = (long) (0x00000000ffffffff & (((uint64) message) >> 32));
clientMsg.data.l[1] = (long) (0x00000000ffffffff & (long) message);
#else
clientMsg.data.l[0] = (long) message;
#endif
XSendEvent (display, juce_messageWindowHandle, false,
NoEventMask, (XEvent*) &clientMsg);
XFlush (display); // This is necessary to ensure the event is delivered
return true;
}
void MessageManager::broadcastMessage (const String& value)
{
}
void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* func,
void* parameter)
{
void* retVal = 0;
if (! errorCondition)
{
if (! isThisTheMessageThread())
{
static MessageThreadFuncCall messageFuncCallContext;
const ScopedLock sl (messageFuncCallContext.lock);
XClientMessageEvent clientMsg;
clientMsg.display = display;
clientMsg.window = juce_messageWindowHandle;
clientMsg.type = ClientMessage;
clientMsg.format = 32;
clientMsg.message_type = specialCallbackId;
#if JUCE_64BIT
clientMsg.data.l[0] = (long) (0x00000000ffffffff & (((uint64) &messageFuncCallContext) >> 32));
clientMsg.data.l[1] = (long) (0x00000000ffffffff & (uint64) &messageFuncCallContext);
#else
clientMsg.data.l[0] = (long) &messageFuncCallContext;
#endif
messageFuncCallContext.func = func;
messageFuncCallContext.parameter = parameter;
if (XSendEvent (display, juce_messageWindowHandle, false, NoEventMask, (XEvent*) &clientMsg) == 0)
return 0;
XFlush (display); // This is necessary to ensure the event is delivered
// Wait for it to complete before continuing
messageFuncCallContext.event.wait();
retVal = messageFuncCallContext.result;
}
else
{
// Just call the function directly
retVal = func (parameter);
}
}
return retVal;
}
bool juce_dispatchNextMessageOnSystemQueue (bool returnIfNoPendingMessages)
{
if (errorCondition)
return false;
if (breakIn)
{
errorCondition = true;
if (juce_isRunningAsApplication())
Process::terminate();
}
if (returnIfNoPendingMessages && ! XPending (display))
return false;
XEvent evt;
XNextEvent (display, &evt);
if (evt.type == ClientMessage && evt.xany.window == juce_messageWindowHandle)
{
XClientMessageEvent* const clientMsg = (XClientMessageEvent*) &evt;
if (clientMsg->format != 32)
{
jassertfalse
DBG ("Error: juce_dispatchNextMessageOnSystemQueue received malformed client message.");
}
else
{
JUCE_TRY
{
#if JUCE_64BIT
void* const messagePtr
= (void*) ((0xffffffff00000000 & (((uint64) clientMsg->data.l[0]) << 32))
| (clientMsg->data.l[1] & 0x00000000ffffffff));
#else
void* const messagePtr = (void*) (clientMsg->data.l[0]);
#endif
if (clientMsg->message_type == specialId)
{
MessageManager::getInstance()->deliverMessage (messagePtr);
}
else if (clientMsg->message_type == specialCallbackId)
{
MessageThreadFuncCall* const call = (MessageThreadFuncCall*) messagePtr;
MessageCallbackFunction* func = call->func;
call->result = (*func) (call->parameter);
call->event.signal();
}
else if (clientMsg->message_type == broadcastId)
{
#if 0
TCHAR buffer[8192];
zeromem (buffer, sizeof (buffer));
if (GlobalGetAtomName ((ATOM) lParam, buffer, 8192) != 0)
mq->deliverBroadcastMessage (String (buffer));
#endif
}
else
{
DBG ("Error: juce_dispatchNextMessageOnSystemQueue received unknown client message.");
}
}
JUCE_CATCH_ALL
}
}
else if (evt.xany.window != juce_messageWindowHandle)
{
juce_windowMessageReceive (&evt);
}
return true;
}
END_JUCE_NAMESPACE
#endif

+ 453
- 0
build/linux/platform_specific_code/juce_linux_Midi.cpp View File

@@ -0,0 +1,453 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "../../../juce_Config.h"
#if JUCE_BUILD_GUI_CLASSES
#if JUCE_ALSA
#include "../../../src/juce_core/basics/juce_StandardHeader.h"
#include <alsa/asoundlib.h>
BEGIN_JUCE_NAMESPACE
#include "../../../src/juce_appframework/audio/devices/juce_MidiOutput.h"
#include "../../../src/juce_appframework/audio/devices/juce_MidiInput.h"
#include "../../../src/juce_core/threads/juce_Thread.h"
#include "../../../src/juce_core/basics/juce_Time.h"
//==============================================================================
static snd_seq_t* iterateDevices (const bool forInput,
StringArray& deviceNamesFound,
const int deviceIndexToOpen)
{
snd_seq_t* returnedHandle = 0;
snd_seq_t* seqHandle;
if (snd_seq_open (&seqHandle, "default", forInput ? SND_SEQ_OPEN_INPUT
: SND_SEQ_OPEN_OUTPUT, 0) == 0)
{
snd_seq_system_info_t* systemInfo;
snd_seq_client_info_t* clientInfo;
if (snd_seq_system_info_malloc (&systemInfo) == 0)
{
if (snd_seq_system_info (seqHandle, systemInfo) == 0
&& snd_seq_client_info_malloc (&clientInfo) == 0)
{
int numClients = snd_seq_system_info_get_cur_clients (systemInfo);
while (--numClients >= 0 && returnedHandle == 0)
{
if (snd_seq_query_next_client (seqHandle, clientInfo) == 0)
{
snd_seq_port_info_t* portInfo;
if (snd_seq_port_info_malloc (&portInfo) == 0)
{
int numPorts = snd_seq_client_info_get_num_ports (clientInfo);
const int client = snd_seq_client_info_get_client (clientInfo);
snd_seq_port_info_set_client (portInfo, client);
snd_seq_port_info_set_port (portInfo, -1);
while (--numPorts >= 0)
{
if (snd_seq_query_next_port (seqHandle, portInfo) == 0
&& (snd_seq_port_info_get_capability (portInfo)
& (forInput ? SND_SEQ_PORT_CAP_READ
: SND_SEQ_PORT_CAP_WRITE)) != 0)
{
deviceNamesFound.add (snd_seq_client_info_get_name (clientInfo));
if (deviceNamesFound.size() == deviceIndexToOpen + 1)
{
const int sourcePort = snd_seq_port_info_get_port (portInfo);
const int sourceClient = snd_seq_client_info_get_client (clientInfo);
if (sourcePort != -1)
{
snd_seq_set_client_name (seqHandle,
forInput ? "Juce Midi Input"
: "Juce Midi Output");
const int portId
= snd_seq_create_simple_port (seqHandle,
forInput ? "Juce Midi In Port"
: "Juce Midi Out Port",
forInput ? (SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE)
: (SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ),
SND_SEQ_PORT_TYPE_MIDI_GENERIC);
snd_seq_connect_from (seqHandle, portId, sourceClient, sourcePort);
returnedHandle = seqHandle;
break;
}
}
}
}
snd_seq_port_info_free (portInfo);
}
}
}
snd_seq_client_info_free (clientInfo);
}
snd_seq_system_info_free (systemInfo);
}
if (returnedHandle == 0)
snd_seq_close (seqHandle);
}
return returnedHandle;
}
static snd_seq_t* createDevice (const bool forInput,
const String& deviceNameToOpen)
{
snd_seq_t* seqHandle = 0;
if (snd_seq_open (&seqHandle, "default", forInput ? SND_SEQ_OPEN_INPUT
: SND_SEQ_OPEN_OUTPUT, 0) == 0)
{
snd_seq_set_client_name (seqHandle,
(const char*) (forInput ? (deviceNameToOpen + T(" Input"))
: (deviceNameToOpen + T(" Output"))));
const int portId
= snd_seq_create_simple_port (seqHandle,
forInput ? "in"
: "out",
forInput ? (SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE)
: (SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ),
forInput ? SND_SEQ_PORT_TYPE_APPLICATION
: SND_SEQ_PORT_TYPE_MIDI_GENERIC);
if (portId < 0)
{
snd_seq_close (seqHandle);
seqHandle = 0;
}
}
return seqHandle;
}
//==============================================================================
class MidiOutputDevice
{
public:
MidiOutputDevice (MidiOutput* const midiOutput_,
snd_seq_t* const seqHandle_)
:
midiOutput (midiOutput_),
seqHandle (seqHandle_),
maxEventSize (16 * 1024)
{
jassert (seqHandle != 0 && midiOutput != 0);
snd_midi_event_new (maxEventSize, &midiParser);
}
~MidiOutputDevice()
{
snd_midi_event_free (midiParser);
snd_seq_close (seqHandle);
}
void sendMessageNow (const MidiMessage& message)
{
if (message.getRawDataSize() > maxEventSize)
{
maxEventSize = message.getRawDataSize();
snd_midi_event_free (midiParser);
snd_midi_event_new (maxEventSize, &midiParser);
}
snd_seq_event_t event;
snd_seq_ev_clear (&event);
snd_midi_event_encode (midiParser,
message.getRawData(),
message.getRawDataSize(),
&event);
snd_midi_event_reset_encode (midiParser);
snd_seq_ev_set_source (&event, 0);
snd_seq_ev_set_subs (&event);
snd_seq_ev_set_direct (&event);
snd_seq_event_output_direct (seqHandle, &event);
}
juce_UseDebuggingNewOperator
private:
MidiOutput* const midiOutput;
snd_seq_t* const seqHandle;
snd_midi_event_t* midiParser;
int maxEventSize;
};
const StringArray MidiOutput::getDevices()
{
StringArray devices;
iterateDevices (false, devices, -1);
return devices;
}
int MidiOutput::getDefaultDeviceIndex()
{
return 0;
}
MidiOutput* MidiOutput::openDevice (int deviceIndex)
{
MidiOutput* newDevice = 0;
StringArray devices;
snd_seq_t* const handle = iterateDevices (false, devices, deviceIndex);
if (handle != 0)
{
newDevice = new MidiOutput();
newDevice->internal = new MidiOutputDevice (newDevice, handle);
}
return newDevice;
}
MidiOutput* MidiOutput::createNewDevice (const String& deviceName)
{
MidiOutput* newDevice = 0;
snd_seq_t* const handle = createDevice (false, deviceName);
if (handle != 0)
{
newDevice = new MidiOutput();
newDevice->internal = new MidiOutputDevice (newDevice, handle);
}
return newDevice;
}
MidiOutput::MidiOutput()
: internal (0)
{
}
MidiOutput::~MidiOutput()
{
MidiOutputDevice* const device = (MidiOutputDevice*) internal;
delete device;
}
void MidiOutput::reset()
{
}
bool MidiOutput::getVolume (float& leftVol, float& rightVol)
{
return false;
}
void MidiOutput::setVolume (float leftVol, float rightVol)
{
}
void MidiOutput::sendMessageNow (const MidiMessage& message)
{
((MidiOutputDevice*) internal)->sendMessageNow (message);
}
//==============================================================================
class MidiInputThread : public Thread
{
public:
MidiInputThread (MidiInput* const midiInput_,
snd_seq_t* const seqHandle_,
MidiInputCallback* const callback_)
: Thread (T("Juce MIDI Input")),
midiInput (midiInput_),
seqHandle (seqHandle_),
callback (callback_)
{
jassert (seqHandle != 0 && callback != 0 && midiInput != 0);
}
~MidiInputThread()
{
snd_seq_close (seqHandle);
}
void run()
{
const int maxEventSize = 16 * 1024;
snd_midi_event_t* midiParser;
if (snd_midi_event_new (maxEventSize, &midiParser) >= 0)
{
uint8* const buffer = (uint8*) juce_malloc (maxEventSize);
const int numPfds = snd_seq_poll_descriptors_count (seqHandle, POLLIN);
struct pollfd* const pfd = (struct pollfd*) alloca (numPfds * sizeof (struct pollfd));
snd_seq_poll_descriptors (seqHandle, pfd, numPfds, POLLIN);
while (! threadShouldExit())
{
if (poll (pfd, numPfds, 100000) > 0)
{
snd_seq_event_t* inputEvent = 0;
snd_seq_nonblock (seqHandle, 1);
do
{
if (snd_seq_event_input (seqHandle, &inputEvent) >= 0)
{
// xxx what about SYSEXes that are too big for the buffer?
const int numBytes = snd_midi_event_decode (midiParser, buffer, maxEventSize, inputEvent);
snd_midi_event_reset_decode (midiParser);
if (numBytes > 0)
{
const MidiMessage message ((const uint8*) buffer,
numBytes,
Time::getMillisecondCounter() * 0.001);
callback->handleIncomingMidiMessage (midiInput, message);
}
snd_seq_free_event (inputEvent);
}
}
while (snd_seq_event_input_pending (seqHandle, 0) > 0);
snd_seq_free_event (inputEvent);
}
}
snd_midi_event_free (midiParser);
juce_free (buffer);
}
};
juce_UseDebuggingNewOperator
private:
MidiInput* const midiInput;
snd_seq_t* const seqHandle;
MidiInputCallback* const callback;
};
//==============================================================================
MidiInput::MidiInput (const String& name_)
: name (name_),
internal (0)
{
}
MidiInput::~MidiInput()
{
stop();
MidiInputThread* const thread = (MidiInputThread*) internal;
delete thread;
}
void MidiInput::start()
{
((MidiInputThread*) internal)->startThread();
}
void MidiInput::stop()
{
((MidiInputThread*) internal)->stopThread (2000);
}
int MidiInput::getDefaultDeviceIndex()
{
return 0;
}
const StringArray MidiInput::getDevices()
{
StringArray devices;
iterateDevices (true, devices, -1);
return devices;
}
MidiInput* MidiInput::openDevice (int deviceIndex, MidiInputCallback* callback)
{
MidiInput* newDevice = 0;
StringArray devices;
snd_seq_t* const handle = iterateDevices (true, devices, deviceIndex);
if (handle != 0)
{
newDevice = new MidiInput (devices [deviceIndex]);
newDevice->internal = new MidiInputThread (newDevice, handle, callback);
}
return newDevice;
}
MidiInput* MidiInput::createNewDevice (const String& deviceName, MidiInputCallback* callback)
{
MidiInput* newDevice = 0;
snd_seq_t* const handle = createDevice (true, deviceName);
if (handle != 0)
{
newDevice = new MidiInput (deviceName);
newDevice->internal = new MidiInputThread (newDevice, handle, callback);
}
return newDevice;
}
END_JUCE_NAMESPACE
#endif
#endif

+ 33
- 0
build/linux/platform_specific_code/juce_linux_NamedPipe.cpp View File

@@ -0,0 +1,33 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "../../macosx/platform_specific_code/juce_mac_NamedPipe.cpp"

+ 59
- 0
build/linux/platform_specific_code/juce_linux_Network.cpp View File

@@ -0,0 +1,59 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "linuxincludes.h"
#include <netdb.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include "../../../src/juce_core/basics/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "../../../src/juce_core/text/juce_StringArray.h"
#include "../../../src/juce_core/basics/juce_SystemStats.h"
#include "../../../src/juce_core/containers/juce_MemoryBlock.h"
// we'll borrow the mac's socket-based http streaming code..
#include "../../macosx/platform_specific_code/juce_mac_HTTPStream.h"
//==============================================================================
int SystemStats::getMACAddresses (int64* addresses, int maxNum)
{
// xxx todo
return 0;
}
END_JUCE_NAMESPACE

+ 402
- 0
build/linux/platform_specific_code/juce_linux_SystemStats.cpp View File

@@ -0,0 +1,402 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "linuxincludes.h"
#include "../../../src/juce_core/basics/juce_StandardHeader.h"
#include <sys/sysinfo.h>
#include <dlfcn.h>
#ifndef CPU_ISSET
#undef SUPPORT_AFFINITIES
#endif
BEGIN_JUCE_NAMESPACE
#include "../../../src/juce_core/io/files/juce_File.h"
#include "../../../src/juce_core/basics/juce_SystemStats.h"
#include "../../../src/juce_core/threads/juce_Process.h"
#include "../../../src/juce_appframework/events/juce_Timer.h"
#include "../../../src/juce_core/misc/juce_PlatformUtilities.h"
static struct _LogicalCpuInfo
{
bool htSupported;
bool htAvailable;
int numPackages;
int numLogicalPerPackage;
uint32 physicalAffinityMask;
} logicalCpuInfo;
//==============================================================================
static juce_noinline unsigned int getCPUIDWord (int* familyModel, int* extFeatures)
{
unsigned int cpu = 0;
unsigned int ext = 0;
unsigned int family = 0;
unsigned int dummy = 0;
__asm__ ("push %%ebx; cpuid; mov %%ebx, %%edi; pop %%ebx"
: "=a" (family), "=D" (ext), "=c" (dummy),"=d" (cpu)
: "a" (1));
if (familyModel != 0)
*familyModel = family;
if (extFeatures != 0)
*extFeatures = ext;
return cpu;
}
void juce_initLogicalCpuInfo()
{
int familyModelWord, extFeaturesWord;
int featuresWord = getCPUIDWord (&familyModelWord, &extFeaturesWord);
logicalCpuInfo.htSupported = false;
logicalCpuInfo.htAvailable = false;
logicalCpuInfo.numLogicalPerPackage = 1;
logicalCpuInfo.numPackages = 0;
logicalCpuInfo.physicalAffinityMask = 0;
#if SUPPORT_AFFINITIES
cpu_set_t processAffinity;
/*
N.B. If this line causes a compile error, then you've probably not got the latest
version of glibc installed.
If you don't want to update your copy of glibc and don't care about cpu affinities,
then you can just disable all this stuff by removing the SUPPORT_AFFINITIES macro
from the linuxincludes.h file.
*/
if (sched_getaffinity (getpid(),
sizeof (cpu_set_t),
&processAffinity) != sizeof (cpu_set_t))
{
return;
}
// Checks: CPUID supported, model >= Pentium 4, Hyperthreading bit set, logical CPUs per package > 1
if (featuresWord == 0
|| ((familyModelWord >> 8) & 0xf) < 15
|| (featuresWord & (1 << 28)) == 0
|| ((extFeaturesWord >> 16) & 0xff) < 2)
{
for (int i = 0; i < 64; ++i)
if (CPU_ISSET (i, &processAffinity))
logicalCpuInfo.physicalAffinityMask |= (1 << i);
return;
}
logicalCpuInfo.htSupported = true;
logicalCpuInfo.numLogicalPerPackage = (extFeaturesWord >> 16) & 0xff;
cpu_set_t affinityMask;
cpu_set_t physAff;
CPU_ZERO (&physAff);
unsigned char i = 1;
unsigned char physIdMask = 0xFF;
unsigned char physIdShift = 0;
//unsigned char apicId, logId, physId;
while (i < logicalCpuInfo.numLogicalPerPackage)
{
i *= 2;
physIdMask <<= 1;
physIdShift++;
}
CPU_SET (0, &affinityMask);
logicalCpuInfo.numPackages = 0;
//xxx revisit this at some point..
/* while ((affinityMask != 0) && (affinityMask <= processAffinity))
{
int ret;
if (! sched_setaffinity (getpid(), sizeof (cpu_set_t), &affinityMask))
{
sched_yield(); // schedule onto correct CPU
featuresWord = getCPUIDWord(&familyModelWord, &extFeaturesWord);
apicId = (unsigned char)(extFeaturesWord >> 24);
logId = (unsigned char)(apicId & ~physIdMask);
physId = (unsigned char)(apicId >> physIdShift);
if (logId != 0)
logicalCpuInfo.htAvailable = true;
if ((((int)logId) % logicalCpuInfo.numLogicalPerPackage) == 0)
{
// This is a physical CPU
physAff |= affinityMask;
logicalCpuInfo.numPackages++;
}
}
affinityMask = affinityMask << 1;
}
sched_setaffinity (getpid(), sizeof(unsigned long), &processAffinity);
*/
logicalCpuInfo.physicalAffinityMask = 0;
for (int i = 0; i < 64; ++i)
if (CPU_ISSET (i, &physAff))
logicalCpuInfo.physicalAffinityMask |= (1 << i);
#endif
}
//==============================================================================
void Logger::outputDebugString (const String& text)
{
fprintf (stdout, text.toUTF8());
fprintf (stdout, "\n");
}
void Logger::outputDebugPrintf (const tchar* format, ...)
{
String text;
va_list args;
va_start (args, format);
text.vprintf(format, args);
outputDebugString(text);
}
SystemStats::OperatingSystemType SystemStats::getOperatingSystemType()
{
return Linux;
}
const String SystemStats::getOperatingSystemName()
{
return T("Linux");
}
static const String getCpuInfo (const char* key, bool lastOne = false)
{
String info;
char buf [256];
FILE* f = fopen ("/proc/cpuinfo", "r");
while (f != 0 && fgets (buf, sizeof(buf), f))
{
if (strncmp (buf, key, strlen (key)) == 0)
{
char* p = buf;
while (*p && *p != '\n')
++p;
if (*p != 0)
*p = 0;
p = buf;
while (*p != 0 && *p != ':')
++p;
if (*p != 0 && *(p + 1) != 0)
info = p + 2;
if (! lastOne)
break;
}
}
fclose (f);
return info;
}
bool SystemStats::hasMMX()
{
return getCpuInfo ("flags").contains (T("mmx"));
}
bool SystemStats::hasSSE()
{
return getCpuInfo ("flags").contains (T("sse"));
}
bool SystemStats::hasSSE2()
{
return getCpuInfo ("flags").contains (T("sse2"));
}
bool SystemStats::has3DNow()
{
return getCpuInfo ("flags").contains (T("3dnow"));
}
const String SystemStats::getCpuVendor()
{
return getCpuInfo ("vendor_id");
}
int SystemStats::getCpuSpeedInMegaherz()
{
const String speed (getCpuInfo ("cpu MHz"));
return (int) (speed.getFloatValue() + 0.5f);
}
bool SystemStats::hasHyperThreading()
{
return logicalCpuInfo.htAvailable;
}
int SystemStats::getMemorySizeInMegabytes()
{
struct sysinfo sysi;
if (sysinfo (&sysi) == 0)
return (sysi.totalram * sysi.mem_unit / (1024 * 1024));
return 0;
}
uint32 juce_millisecondsSinceStartup() throw()
{
static unsigned int calibrate = 0;
static bool calibrated = false;
timeval t;
unsigned int ret = 0;
if (! gettimeofday (&t, 0))
{
if (! calibrated)
{
struct sysinfo sysi;
if (sysinfo (&sysi) == 0)
// Safe to assume system was not brought up earlier than 1970!
calibrate = t.tv_sec - sysi.uptime;
calibrated = true;
}
ret = 1000 * (t.tv_sec - calibrate) + (t.tv_usec / 1000);
}
return ret;
}
double Time::getMillisecondCounterHiRes() throw()
{
return getHighResolutionTicks() * (1.0 / 1000000.0);
}
int64 Time::getHighResolutionTicks() throw()
{
timeval t;
if (gettimeofday (&t,NULL))
return 0;
return ((int64) t.tv_sec * (int64) 1000000) + (int64) t.tv_usec;
}
int64 Time::getHighResolutionTicksPerSecond() throw()
{
// Microseconds
return 1000000;
}
bool Time::setSystemTimeToThisTime() const
{
timeval t;
t.tv_sec = millisSinceEpoch % 1000000;
t.tv_usec = millisSinceEpoch - t.tv_sec;
return settimeofday (&t, NULL) ? false : true;
}
int SystemStats::getPageSize()
{
static int systemPageSize = 0;
if (systemPageSize == 0)
systemPageSize = sysconf (_SC_PAGESIZE);
return systemPageSize;
}
int SystemStats::getNumPhysicalCpus()
{
if (logicalCpuInfo.numPackages)
return logicalCpuInfo.numPackages;
return getNumLogicalCpus();
}
int SystemStats::getNumLogicalCpus()
{
const int lastCpu = getCpuInfo ("processor", true).getIntValue();
return lastCpu + 1;
}
uint32 SystemStats::getPhysicalAffinityMask()
{
#if SUPPORT_AFFINITIES
return logicalCpuInfo.physicalAffinityMask;
#else
/* affinities aren't supported because either the appropriate header files weren't found,
or the SUPPORT_AFFINITIES macro was turned off in linuxheaders.h
*/
jassertfalse
return 0;
#endif
}
//==============================================================================
void SystemStats::initialiseStats()
{
// Process starts off as root when running suid
Process::lowerPrivilege();
String s (SystemStats::getJUCEVersion());
juce_initLogicalCpuInfo();
}
void PlatformUtilities::fpuReset()
{
}
END_JUCE_NAMESPACE

+ 457
- 0
build/linux/platform_specific_code/juce_linux_Threads.cpp View File

@@ -0,0 +1,457 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "linuxincludes.h"
#include <dlfcn.h>
#include <sys/file.h>
#include "../../../src/juce_core/basics/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "../../../src/juce_core/threads/juce_CriticalSection.h"
#include "../../../src/juce_core/threads/juce_WaitableEvent.h"
#include "../../../src/juce_core/threads/juce_InterProcessLock.h"
#include "../../../src/juce_core/threads/juce_Thread.h"
#include "../../../src/juce_core/threads/juce_Process.h"
#include "../../../src/juce_core/io/files/juce_File.h"
#include "../../../src/juce_core/basics/juce_SystemStats.h"
#ifndef CPU_ISSET
#undef SUPPORT_AFFINITIES
#endif
//==============================================================================
void JUCE_API juce_threadEntryPoint (void*);
void* threadEntryProc (void* value)
{
// New threads start off as root when running suid
Process::lowerPrivilege();
juce_threadEntryPoint (value);
return 0;
}
void* juce_createThread (void* userData)
{
pthread_t handle = 0;
if (pthread_create (&handle, 0, threadEntryProc, userData) == 0)
{
pthread_detach (handle);
return (void*)handle;
}
return 0;
}
void juce_killThread (void* handle)
{
if (handle != 0)
pthread_cancel ((pthread_t)handle);
}
void juce_setCurrentThreadName (const String& /*name*/)
{
}
int Thread::getCurrentThreadId()
{
return (int) pthread_self();
}
/*
* This is all a bit non-ideal... the trouble is that on Linux you
* need to call setpriority to affect the dynamic priority for
* non-realtime processes, but this requires the pid, which is not
* accessible from the pthread_t. We could get it by calling getpid
* once each thread has started, but then we would need a list of
* running threads etc etc.
* Also there is no such thing as IDLE priority on Linux.
* For the moment, map idle, low and normal process priorities to
* SCHED_OTHER, with the thread priority ignored for these classes.
* Map high priority processes to the lower half of the SCHED_RR
* range, and realtime to the upper half
*/
// priority 1 to 10 where 5=normal, 1=low. If the handle is 0, sets the
// priority of the current thread
void juce_setThreadPriority (void* handle, int priority)
{
struct sched_param param;
int policy, maxp, minp, pri;
if (handle == 0)
handle = (void*) pthread_self();
if (pthread_getschedparam ((pthread_t) handle, &policy, &param) == 0
&& policy != SCHED_OTHER)
{
minp = sched_get_priority_min(policy);
maxp = sched_get_priority_max(policy);
pri = ((maxp - minp) / 2) * (priority - 1) / 9;
if (param.__sched_priority >= (minp + (maxp - minp) / 2))
// Realtime process priority
param.__sched_priority = minp + ((maxp - minp) / 2) + pri;
else
// High process priority
param.__sched_priority = minp + pri;
param.sched_priority = jlimit (1, 127, 1 + (priority * 126) / 11);
pthread_setschedparam ((pthread_t) handle, policy, &param);
}
}
void Thread::setCurrentThreadAffinityMask (const uint32 affinityMask)
{
#if SUPPORT_AFFINITIES
cpu_set_t affinity;
CPU_ZERO (&affinity);
for (int i = 0; i < 32; ++i)
if ((affinityMask & (1 << i)) != 0)
CPU_SET (i, &affinity);
/*
N.B. If this line causes a compile error, then you've probably not got the latest
version of glibc installed.
If you don't want to update your copy of glibc and don't care about cpu affinities,
then you can just disable all this stuff by removing the SUPPORT_AFFINITIES macro
from the linuxincludes.h file.
*/
sched_setaffinity (getpid(), sizeof (cpu_set_t), &affinity);
sched_yield();
#else
/* affinities aren't supported because either the appropriate header files weren't found,
or the SUPPORT_AFFINITIES macro was turned off in linuxheaders.h
*/
jassertfalse
#endif
}
void Thread::yield()
{
sched_yield();
}
void Thread::sleep (int millisecs)
{
struct timespec time;
time.tv_sec = millisecs / 1000;
time.tv_nsec = (millisecs % 1000) * 1000000;
nanosleep (&time, 0);
}
//==============================================================================
CriticalSection::CriticalSection() throw()
{
pthread_mutexattr_t atts;
pthread_mutexattr_init (&atts);
pthread_mutexattr_settype (&atts, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init (&internal, &atts);
}
CriticalSection::~CriticalSection() throw()
{
pthread_mutex_destroy (&internal);
}
void CriticalSection::enter() const throw()
{
pthread_mutex_lock (&internal);
}
bool CriticalSection::tryEnter() const throw()
{
return pthread_mutex_trylock (&internal) == 0;
}
void CriticalSection::exit() const throw()
{
pthread_mutex_unlock (&internal);
}
//==============================================================================
struct EventStruct
{
pthread_cond_t condition;
pthread_mutex_t mutex;
bool triggered;
};
WaitableEvent::WaitableEvent() throw()
{
EventStruct* const es = new EventStruct();
es->triggered = false;
pthread_cond_init (&es->condition, 0);
pthread_mutex_init (&es->mutex, 0);
internal = es;
}
WaitableEvent::~WaitableEvent() throw()
{
EventStruct* const es = (EventStruct*)internal;
pthread_cond_destroy (&es->condition);
pthread_mutex_destroy (&es->mutex);
delete es;
}
bool WaitableEvent::wait (const int timeOutMillisecs) const throw()
{
EventStruct* const es = (EventStruct*)internal;
bool ok = true;
pthread_mutex_lock (&es->mutex);
if (!es->triggered)
{
if (timeOutMillisecs < 0)
{
pthread_cond_wait (&es->condition, &es->mutex);
}
else
{
struct timespec time;
struct timeval t;
int timeout = 0;
gettimeofday(&t,NULL);
time.tv_sec = t.tv_sec + (timeOutMillisecs / 1000);
time.tv_nsec = (t.tv_usec + ((timeOutMillisecs % 1000)*1000)) * 1000;
while( time.tv_nsec >= 1000000000 )
{
time.tv_nsec -= 1000000000;
time.tv_sec++;
}
while( !timeout )
{
timeout = pthread_cond_timedwait (&es->condition, &es->mutex, &time);
if( !timeout )
// Success
break;
if( timeout == EINTR )
// Go round again
timeout = 0;
}
}
ok = es->triggered;
}
es->triggered = false;
pthread_mutex_unlock (&es->mutex);
return ok;
}
void WaitableEvent::signal() const throw()
{
EventStruct* const es = (EventStruct*)internal;
pthread_mutex_lock (&es->mutex);
es->triggered = true;
pthread_cond_signal (&es->condition);
pthread_mutex_unlock (&es->mutex);
}
void WaitableEvent::reset() const throw()
{
EventStruct* const es = (EventStruct*)internal;
pthread_mutex_lock (&es->mutex);
es->triggered = false;
pthread_mutex_unlock (&es->mutex);
}
//==============================================================================
// sets the process to 0=low priority, 1=normal, 2=high, 3=realtime
void Process::setPriority (ProcessPriority prior)
{
struct sched_param param;
int policy, maxp, minp;
const int p = (int) prior;
if (p <= 1)
policy = SCHED_OTHER;
else
policy = SCHED_RR;
minp = sched_get_priority_min (policy);
maxp = sched_get_priority_max (policy);
if (p < 2)
param.__sched_priority = 0;
else if (p == 2 )
// Set to middle of lower realtime priority range
param.__sched_priority = minp + (maxp - minp) / 4;
else
// Set to middle of higher realtime priority range
param.__sched_priority = minp + (3 * (maxp - minp) / 4);
pthread_setschedparam (pthread_self(), policy, &param);
}
void Process::terminate()
{
exit (0);
}
void Process::raisePrivilege()
{
// If running suid root, change effective user
// to root
if (geteuid() != 0 && getuid() == 0)
{
setreuid (geteuid(), getuid());
setregid (getegid(), getgid());
}
}
void Process::lowerPrivilege()
{
// If runing suid root, change effective user
// back to real user
if (geteuid() == 0 && getuid() != 0)
{
setreuid (geteuid(), getuid());
setregid (getegid(), getgid());
}
}
#if JUCE_BUILD_GUI_CLASSES
void* Process::loadDynamicLibrary (const String& name)
{
return dlopen ((const char*) name.toUTF8(), RTLD_LOCAL | RTLD_NOW);
}
void Process::freeDynamicLibrary (void* handle)
{
dlclose(handle);
}
void* Process::getProcedureEntryPoint (void* libraryHandle, const String& procedureName)
{
return dlsym (libraryHandle, (const char*) procedureName);
}
#endif
//==============================================================================
InterProcessLock::InterProcessLock (const String& name_)
: internal (0),
name (name_),
reentrancyLevel (0)
{
const File tempDir (File::getSpecialLocation (File::tempDirectory));
const File temp (tempDir.getChildFile (name));
temp.create();
internal = (void*) open (temp.getFullPathName().toUTF8(), 'a');
}
InterProcessLock::~InterProcessLock()
{
while (reentrancyLevel > 0)
this->exit();
#if JUCE_64BIT
close ((long long) internal);
#else
close ((int) internal);
#endif
}
bool InterProcessLock::enter (int timeOutMillisecs)
{
if (internal == 0)
return false;
if (reentrancyLevel != 0)
return true;
if (timeOutMillisecs <= 0)
{
if (flock ((long) internal,
timeOutMillisecs < 0 ? LOCK_EX
: (LOCK_EX | LOCK_NB)) == 0)
{
++reentrancyLevel;
return true;
}
}
else
{
const int64 endTime = Time::currentTimeMillis() + timeOutMillisecs;
for (;;)
{
if (flock ((long) internal, LOCK_EX | LOCK_NB) == 0)
{
++reentrancyLevel;
return true;
}
if (Time::currentTimeMillis() >= endTime)
break;
Thread::sleep (10);
}
}
return false;
}
void InterProcessLock::exit()
{
if (reentrancyLevel > 0 && internal != 0)
{
--reentrancyLevel;
const int result = flock ((long) internal, LOCK_UN);
(void) result;
jassert (result == 0);
}
}
END_JUCE_NAMESPACE

+ 3076
- 0
build/linux/platform_specific_code/juce_linux_Windowing.cpp
File diff suppressed because it is too large
View File


+ 54
- 0
build/linux/platform_specific_code/linuxincludes.h View File

@@ -0,0 +1,54 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#ifndef __LINUXINCLUDES_JUCEHEADER__
#define __LINUXINCLUDES_JUCEHEADER__
// Linux Header Files:
#include <unistd.h>
#include <stdlib.h>
#include <sched.h>
#include <pthread.h>
#include <sys/time.h>
#include <errno.h>
#include "../../../juce_Config.h"
/* Remove this macro if you're having problems compiling the cpu affinity
calls (the API for these has changed about quite a bit in various Linux
versions, and a lot of distros seem to ship with obsolete versions)
*/
#ifndef SUPPORT_AFFINITIES
#define SUPPORT_AFFINITIES 1
#endif
#endif // __LINUXINCLUDES_JUCEHEADER__

+ 1
- 0
build/linux/runpremake View File

@@ -0,0 +1 @@
premake --file juce_premake.lua --cc gcc --target gnu

+ 3187
- 0
build/macosx/Juce.xcodeproj/project.pbxproj
File diff suppressed because it is too large
View File


+ 6
- 0
build/macosx/juce.xcconfig.tortoise.removed View File

@@ -0,0 +1,6 @@
ARCHS = ppc i386
SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk
GCC_VERSION_ppc = 3.3
MACOSX_DEPLOYMENT_TARGET_ppc = 10.2
OTHER_LD_FLAGS_ppc = /Developer/SDKs/MacOSX10.2.8.sdk/usr/lib/gcc/darwin/3.3/libstdc++.a
SDKROOT_ppc = /Developer/SDKs/MacOSX10.2.8.sdk

+ 1165
- 0
build/macosx/platform_specific_code/juce_mac_CoreAudio.cpp
File diff suppressed because it is too large
View File


+ 594
- 0
build/macosx/platform_specific_code/juce_mac_CoreMidi.cpp View File

@@ -0,0 +1,594 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include <CoreMIDI/MIDIServices.h>
#include "../../../src/juce_core/basics/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "../../../src/juce_appframework/audio/devices/juce_MidiOutput.h"
#include "../../../src/juce_appframework/audio/devices/juce_MidiInput.h"
#include "../../../src/juce_appframework/application/juce_Application.h"
#include "../../../src/juce_core/basics/juce_Time.h"
#include "../../../src/juce_core/containers/juce_MemoryBlock.h"
#include "../../../src/juce_core/misc/juce_PlatformUtilities.h"
#include "../../../src/juce_core/threads/juce_ScopedLock.h"
//==============================================================================
#define log(a) Logger::writeToLog(a)
static bool logAnyErrors (const OSStatus err, const int lineNum)
{
if (err == noErr)
return true;
log (T("CoreMidi error: ") + String (lineNum) + T(" - ") + String::toHexString ((int)err));
jassertfalse
return false;
}
#define OK(a) logAnyErrors(a, __LINE__)
//==============================================================================
static const String getEndpointName (MIDIEndpointRef endpoint, bool isExternal)
{
String result;
CFStringRef str = 0;
MIDIObjectGetStringProperty (endpoint, kMIDIPropertyName, &str);
if (str != 0)
{
result = PlatformUtilities::cfStringToJuceString (str);
CFRelease (str);
str = 0;
}
MIDIEntityRef entity = 0;
MIDIEndpointGetEntity (endpoint, &entity);
if (entity == 0)
return result; // probably virtual
if (result.isEmpty())
{
// endpoint name has zero length - try the entity
MIDIObjectGetStringProperty (entity, kMIDIPropertyName, &str);
if (str != 0)
{
result += PlatformUtilities::cfStringToJuceString (str);
CFRelease (str);
str = 0;
}
}
// now consider the device's name
MIDIDeviceRef device = 0;
MIDIEntityGetDevice (entity, &device);
if (device == 0)
return result;
MIDIObjectGetStringProperty (device, kMIDIPropertyName, &str);
if (str != 0)
{
const String s (PlatformUtilities::cfStringToJuceString (str));
CFRelease (str);
// if an external device has only one entity, throw away
// the endpoint name and just use the device name
if (isExternal && MIDIDeviceGetNumberOfEntities (device) < 2)
{
result = s;
}
else if (! result.startsWithIgnoreCase (s))
{
// prepend the device name to the entity name
result = (s + T(" ") + result).trimEnd();
}
}
return result;
}
static const String getConnectedEndpointName (MIDIEndpointRef endpoint)
{
String result;
// Does the endpoint have connections?
CFDataRef connections = 0;
int numConnections = 0;
MIDIObjectGetDataProperty (endpoint, kMIDIPropertyConnectionUniqueID, &connections);
if (connections != 0)
{
numConnections = CFDataGetLength (connections) / sizeof (MIDIUniqueID);
if (numConnections > 0)
{
const SInt32* pid = reinterpret_cast <const SInt32*> (CFDataGetBytePtr (connections));
for (int i = 0; i < numConnections; ++i, ++pid)
{
MIDIUniqueID id = EndianS32_BtoN (*pid);
MIDIObjectRef connObject;
MIDIObjectType connObjectType;
OSStatus err = MIDIObjectFindByUniqueID (id, &connObject, &connObjectType);
if (err == noErr)
{
String s;
if (connObjectType == kMIDIObjectType_ExternalSource
|| connObjectType == kMIDIObjectType_ExternalDestination)
{
// Connected to an external device's endpoint (10.3 and later).
s = getEndpointName (static_cast <MIDIEndpointRef> (connObject), true);
}
else
{
// Connected to an external device (10.2) (or something else, catch-all)
CFStringRef str = 0;
MIDIObjectGetStringProperty (connObject, kMIDIPropertyName, &str);
if (str != 0)
{
s = PlatformUtilities::cfStringToJuceString (str);
CFRelease (str);
}
}
if (s.isNotEmpty())
{
if (result.isNotEmpty())
result += (", ");
result += s;
}
}
}
}
CFRelease (connections);
}
if (result.isNotEmpty())
return result;
// Here, either the endpoint had no connections, or we failed to obtain names for any of them.
return getEndpointName (endpoint, false);
}
//==============================================================================
const StringArray MidiOutput::getDevices()
{
StringArray s;
const ItemCount num = MIDIGetNumberOfDestinations();
for (ItemCount i = 0; i < num; ++i)
{
MIDIEndpointRef dest = MIDIGetDestination (i);
if (dest != 0)
{
String name (getConnectedEndpointName (dest));
if (name.isEmpty())
name = T("<error>");
s.add (name);
}
else
{
s.add (T("<error>"));
}
}
return s;
}
int MidiOutput::getDefaultDeviceIndex()
{
return 0;
}
static MIDIClientRef globalMidiClient;
static bool hasGlobalClientBeenCreated = false;
static bool makeSureClientExists()
{
if (! hasGlobalClientBeenCreated)
{
String name (T("JUCE"));
if (JUCEApplication::getInstance() != 0)
name = JUCEApplication::getInstance()->getApplicationName();
CFStringRef appName = PlatformUtilities::juceStringToCFString (name);
hasGlobalClientBeenCreated = OK (MIDIClientCreate (appName, 0, 0, &globalMidiClient));
CFRelease (appName);
}
return hasGlobalClientBeenCreated;
}
struct MidiPortAndEndpoint
{
MIDIPortRef port;
MIDIEndpointRef endPoint;
};
MidiOutput* MidiOutput::openDevice (int index)
{
MidiOutput* mo = 0;
if (index >= 0 && index < (int) MIDIGetNumberOfDestinations())
{
MIDIEndpointRef endPoint = MIDIGetDestination (index);
CFStringRef pname;
if (OK (MIDIObjectGetStringProperty (endPoint, kMIDIPropertyName, &pname)))
{
log (T("CoreMidi - opening out: ") + PlatformUtilities::cfStringToJuceString (pname));
if (makeSureClientExists())
{
MIDIPortRef port;
if (OK (MIDIOutputPortCreate (globalMidiClient, pname, &port)))
{
MidiPortAndEndpoint* mpe = new MidiPortAndEndpoint();
mpe->port = port;
mpe->endPoint = endPoint;
mo = new MidiOutput();
mo->internal = (void*)mpe;
}
}
CFRelease (pname);
}
}
return mo;
}
MidiOutput::MidiOutput()
{
}
MidiOutput::~MidiOutput()
{
MidiPortAndEndpoint* const mpe = (MidiPortAndEndpoint*)internal;
MIDIPortDispose (mpe->port);
delete mpe;
}
void MidiOutput::reset()
{
}
bool MidiOutput::getVolume (float& leftVol, float& rightVol)
{
return false;
}
void MidiOutput::setVolume (float leftVol, float rightVol)
{
}
void MidiOutput::sendMessageNow (const MidiMessage& message)
{
MidiPortAndEndpoint* const mpe = (MidiPortAndEndpoint*)internal;
if (message.isSysEx())
{
MIDIPacketList* const packets = (MIDIPacketList*) juce_malloc (32 + message.getRawDataSize());
packets->numPackets = 1;
packets->packet[0].timeStamp = 0;
packets->packet[0].length = message.getRawDataSize();
memcpy (packets->packet[0].data, message.getRawData(), message.getRawDataSize());
MIDISend (mpe->port, mpe->endPoint, packets);
juce_free (packets);
}
else
{
MIDIPacketList packets;
packets.numPackets = 1;
packets.packet[0].timeStamp = 0;
packets.packet[0].length = message.getRawDataSize();
*(int*) (packets.packet[0].data) = *(const int*) message.getRawData();
MIDISend (mpe->port, mpe->endPoint, &packets);
}
}
//==============================================================================
const StringArray MidiInput::getDevices()
{
StringArray s;
const ItemCount num = MIDIGetNumberOfSources();
for (ItemCount i = 0; i < num; ++i)
{
MIDIEndpointRef source = MIDIGetSource (i);
if (source != 0)
{
String name (getConnectedEndpointName (source));
if (name.isEmpty())
name = T("<error>");
s.add (name);
}
else
{
s.add (T("<error>"));
}
}
return s;
}
int MidiInput::getDefaultDeviceIndex()
{
return 0;
}
//==============================================================================
struct MidiPortAndCallback
{
MidiInput* input;
MIDIPortRef port;
MIDIEndpointRef endPoint;
MidiInputCallback* callback;
MemoryBlock pendingData;
int pendingBytes;
double pendingDataTime;
bool active;
};
static CriticalSection callbackLock;
static VoidArray activeCallbacks;
static void processSysex (MidiPortAndCallback* const mpe, const uint8*& d, int& size, const double time)
{
if (*d == 0xf0)
{
mpe->pendingBytes = 0;
mpe->pendingDataTime = time;
}
mpe->pendingData.ensureSize (mpe->pendingBytes + size, false);
uint8* totalMessage = (uint8*) mpe->pendingData.getData();
uint8* dest = totalMessage + mpe->pendingBytes;
while (size > 0)
{
if (mpe->pendingBytes > 0 && *d >= 0x80)
{
if (*d >= 0xfa || *d == 0xf8)
{
mpe->callback->handleIncomingMidiMessage (mpe->input, MidiMessage (*d, time));
++d;
--size;
}
else
{
if (*d == 0xf7)
{
*dest++ = *d++;
mpe->pendingBytes++;
--size;
}
break;
}
}
else
{
*dest++ = *d++;
mpe->pendingBytes++;
--size;
}
}
if (totalMessage [mpe->pendingBytes - 1] == 0xf7)
{
mpe->callback->handleIncomingMidiMessage (mpe->input, MidiMessage (totalMessage,
mpe->pendingBytes,
mpe->pendingDataTime));
mpe->pendingBytes = 0;
}
else
{
mpe->callback->handlePartialSysexMessage (mpe->input,
totalMessage,
mpe->pendingBytes,
mpe->pendingDataTime);
}
}
static void midiInputProc (const MIDIPacketList* pktlist,
void* readProcRefCon,
void* srcConnRefCon)
{
double time = Time::getMillisecondCounterHiRes() * 0.001;
const double originalTime = time;
MidiPortAndCallback* const mpe = (MidiPortAndCallback*) readProcRefCon;
const ScopedLock sl (callbackLock);
if (activeCallbacks.contains (mpe) && mpe->active)
{
const MIDIPacket* packet = &pktlist->packet[0];
for (unsigned int i = 0; i < pktlist->numPackets; ++i)
{
const uint8* d = (const uint8*) (packet->data);
int size = packet->length;
while (size > 0)
{
time = originalTime;
if (mpe->pendingBytes > 0 || d[0] == 0xf0)
{
processSysex (mpe, d, size, time);
}
else
{
int used = 0;
const MidiMessage m (d, size, used, 0, time);
if (used <= 0)
{
jassertfalse // malformed midi message
break;
}
else
{
mpe->callback->handleIncomingMidiMessage (mpe->input, m);
}
size -= used;
d += used;
}
}
packet = MIDIPacketNext (packet);
}
}
}
MidiInput* MidiInput::openDevice (int index, MidiInputCallback* callback)
{
MidiInput* mi = 0;
if (index >= 0 && index < (int) MIDIGetNumberOfSources())
{
MIDIEndpointRef endPoint = MIDIGetSource (index);
if (endPoint != 0)
{
CFStringRef pname;
if (OK (MIDIObjectGetStringProperty (endPoint, kMIDIPropertyName, &pname)))
{
log (T("CoreMidi - opening inp: ") + PlatformUtilities::cfStringToJuceString (pname));
if (makeSureClientExists())
{
MIDIPortRef port;
MidiPortAndCallback* const mpe = new MidiPortAndCallback();
mpe->active = false;
if (OK (MIDIInputPortCreate (globalMidiClient, pname, midiInputProc, mpe, &port)))
{
if (OK (MIDIPortConnectSource (port, endPoint, 0)))
{
mpe->port = port;
mpe->endPoint = endPoint;
mpe->callback = callback;
mpe->pendingBytes = 0;
mpe->pendingData.ensureSize (128);
mi = new MidiInput (getDevices() [index]);
mpe->input = mi;
mi->internal = (void*) mpe;
const ScopedLock sl (callbackLock);
activeCallbacks.add (mpe);
}
else
{
OK (MIDIPortDispose (port));
delete mpe;
}
}
else
{
delete mpe;
}
}
}
CFRelease (pname);
}
}
return mi;
}
MidiInput::MidiInput (const String& name_)
: name (name_)
{
}
MidiInput::~MidiInput()
{
MidiPortAndCallback* const mpe = (MidiPortAndCallback*) internal;
mpe->active = false;
callbackLock.enter();
activeCallbacks.removeValue (mpe);
callbackLock.exit();
OK (MIDIPortDisconnectSource (mpe->port, mpe->endPoint));
OK (MIDIPortDispose (mpe->port));
delete mpe;
activeCallbacks.minimiseStorageOverheads();
}
void MidiInput::start()
{
MidiPortAndCallback* const mpe = (MidiPortAndCallback*) internal;
const ScopedLock sl (callbackLock);
mpe->active = true;
}
void MidiInput::stop()
{
MidiPortAndCallback* const mpe = (MidiPortAndCallback*) internal;
const ScopedLock sl (callbackLock);
mpe->active = false;
}
END_JUCE_NAMESPACE

+ 299
- 0
build/macosx/platform_specific_code/juce_mac_FileChooser.cpp View File

@@ -0,0 +1,299 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include <Carbon/Carbon.h>
#include <fnmatch.h>
#include "../../../src/juce_core/basics/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "../../../src/juce_appframework/gui/components/filebrowser/juce_FileChooser.h"
#include "../../../src/juce_appframework/gui/components/juce_Desktop.h"
#include "../../../src/juce_appframework/application/juce_Application.h"
#include "../../../src/juce_appframework/events/juce_MessageManager.h"
#include "../../../src/juce_core/misc/juce_PlatformUtilities.h"
#include "../../../src/juce_core/text/juce_LocalisedStrings.h"
//==============================================================================
struct JuceNavInfo
{
StringArray filters;
AEDesc defaultLocation;
bool defaultLocationValid;
};
static void pascal juceNavEventProc (NavEventCallbackMessage callbackSelector,
NavCBRecPtr callbackParms,
void *callBackUD)
{
if (callbackSelector == kNavCBStart)
{
if (((JuceNavInfo*) callBackUD)->defaultLocationValid)
{
NavCustomControl (callbackParms->context,
kNavCtlSetLocation,
(void*) &((JuceNavInfo*) callBackUD)->defaultLocation);
}
for (int i = Desktop::getInstance().getNumComponents(); --i >= 0;)
{
Component* const c = Desktop::getInstance().getComponent (i);
if (c != 0 && c->isAlwaysOnTop() && c->isVisible())
{
SetWindowGroup (callbackParms->window,
GetWindowGroup ((WindowRef) c->getWindowHandle()));
break;
}
}
BringToFront (callbackParms->window);
SelectWindow (callbackParms->window);
SetUserFocusWindow (callbackParms->window);
}
}
static Boolean pascal juceNavFilterProc (AEDesc* theItem,
void*,
void* callBackUD,
NavFilterModes filterMode)
{
// must return true if we don't understand the object
bool result = true;
if (filterMode == kNavFilteringBrowserList)
{
AEDesc desc;
if (AECoerceDesc (theItem, typeFSRef, &desc) == noErr)
{
Size size = AEGetDescDataSize (&desc);
if (size > 0)
{
void* data = juce_calloc (size);
if (AEGetDescData (&desc, data, size) == noErr)
{
const String path (PlatformUtilities::makePathFromFSRef ((FSRef*) data));
if (path.isNotEmpty())
{
const File file (path);
if ((! file.isDirectory()) || PlatformUtilities::isBundle (path))
{
const String filename (file.getFileName().toLowerCase());
const char* const filenameUTF8 = filename.toUTF8();
const JuceNavInfo* const info = (const JuceNavInfo*) callBackUD;
if (info != 0)
{
result = false;
for (int i = info->filters.size(); --i >= 0;)
{
const String wildcard (info->filters[i].toLowerCase());
if (fnmatch (wildcard.toUTF8(), filenameUTF8, 0) == 0)
{
result = true;
break;
}
}
}
}
}
}
juce_free (data);
}
AEDisposeDesc (&desc);
}
}
return result;
}
void FileChooser::showPlatformDialog (OwnedArray<File>& results,
const String& title,
const File& currentFileOrDirectory,
const String& filter,
bool selectsDirectory,
bool isSaveDialogue,
bool warnAboutOverwritingExistingFiles,
bool selectMultipleFiles,
FilePreviewComponent* extraInfoComponent)
{
JuceNavInfo userInfo;
userInfo.filters.addTokens (filter.replaceCharacters (T(",:"), T(";;")), T(";"), 0);
userInfo.filters.trim();
userInfo.filters.removeEmptyStrings();
userInfo.defaultLocationValid = false;
void* const userInfoPtr = (void*) &userInfo;
const int oldTimeBeforeWaitCursor = MessageManager::getInstance()->getTimeBeforeShowingWaitCursor();
MessageManager::getInstance()->setTimeBeforeShowingWaitCursor (0);
NavEventUPP eventProc = NewNavEventUPP (juceNavEventProc);
NavObjectFilterUPP filterProc = NewNavObjectFilterUPP (juceNavFilterProc);
FSRef defaultRef;
if ((currentFileOrDirectory.isOnHardDisk()
&& PlatformUtilities::makeFSRefFromPath (&defaultRef,
currentFileOrDirectory.getFullPathName()))
|| (currentFileOrDirectory.getParentDirectory().isOnHardDisk()
&& PlatformUtilities::makeFSRefFromPath (&defaultRef,
currentFileOrDirectory.getParentDirectory().getFullPathName())))
{
if (AECreateDesc (typeFSRef, &defaultRef, sizeof (defaultRef), &userInfo.defaultLocation) == noErr)
{
userInfo.defaultLocationValid = true;
}
}
WindowRef lastFocused = GetUserFocusWindow();
NavDialogCreationOptions options;
if (NavGetDefaultDialogCreationOptions (&options) == noErr)
{
options.optionFlags |= kNavSelectDefaultLocation
| kNavSupportPackages
| kNavAllowPreviews;
if (! warnAboutOverwritingExistingFiles)
options.optionFlags |= kNavDontConfirmReplacement;
if (selectMultipleFiles)
options.optionFlags |= kNavAllowMultipleFiles;
const String name (selectsDirectory ? TRANS("Choose folder")
: TRANS("Choose file"));
options.clientName = PlatformUtilities::juceStringToCFString (name);
CFStringRef message = PlatformUtilities::juceStringToCFString (title);
// nasty layout bug if the message text is set for a directory browser..
if (selectsDirectory)
options.windowTitle = message;
else
options.message = message;
NavDialogRef dialog = 0;
bool ok = false;
if (selectsDirectory)
{
ok = (NavCreateChooseFolderDialog (&options, eventProc, 0, userInfoPtr, &dialog) == noErr);
}
else if (isSaveDialogue)
{
ok = (NavCreatePutFileDialog (&options, 0, 0, eventProc, userInfoPtr, &dialog) == noErr);
}
else
{
ok = (NavCreateGetFileDialog (&options, 0, eventProc, 0, filterProc, userInfoPtr, &dialog) == noErr);
}
if (ok && (NavDialogRun (dialog) == noErr))
{
NavReplyRecord reply;
if (NavDialogGetReply (dialog, &reply) == noErr)
{
if (reply.validRecord)
{
long count;
if (AECountItems (&(reply.selection), &count) == noErr
&& count > 0)
{
AEKeyword theKeyword;
DescType actualType;
Size actualSize;
FSRef file;
for (int i = 1; i <= count; ++i)
{
// Get a pointer to selected file
if (AEGetNthPtr (&(reply.selection),
i,
typeFSRef,
&theKeyword,
&actualType,
&file,
sizeof (file),
&actualSize) == noErr)
{
String result (PlatformUtilities::makePathFromFSRef (&file));
if (result.isNotEmpty() && isSaveDialogue && ! selectsDirectory)
{
CFStringRef saveName = NavDialogGetSaveFileName (dialog);
result = File (result)
.getChildFile (PlatformUtilities::convertToPrecomposedUnicode (PlatformUtilities::cfStringToJuceString (saveName)))
.getFullPathName();
}
results.add (new File (result));
}
}
}
}
NavDisposeReply (&reply);
}
}
if (dialog != 0)
NavDialogDispose (dialog);
CFRelease (message);
CFRelease (options.clientName);
}
if (userInfo.defaultLocationValid)
AEDisposeDesc (&userInfo.defaultLocation);
DisposeNavEventUPP (eventProc);
DisposeNavObjectFilterUPP (filterProc);
MessageManager::getInstance()->setTimeBeforeShowingWaitCursor (oldTimeBeforeWaitCursor);
SetUserFocusWindow (lastFocused);
}
END_JUCE_NAMESPACE

+ 977
- 0
build/macosx/platform_specific_code/juce_mac_Files.cpp View File

@@ -0,0 +1,977 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "../../../src/juce_core/basics/juce_StandardHeader.h"
#include <sys/stat.h>
#include <sys/dir.h>
#include <sys/param.h>
#include <sys/mount.h>
#include <unistd.h>
#include <fnmatch.h>
#include <utime.h>
#include <pwd.h>
#include <fcntl.h>
#include <Carbon/Carbon.h>
BEGIN_JUCE_NAMESPACE
#include "../../../src/juce_core/io/files/juce_FileInputStream.h"
#include "../../../src/juce_core/io/files/juce_FileOutputStream.h"
#include "../../../src/juce_core/io/network/juce_URL.h"
#include "../../../src/juce_core/basics/juce_SystemStats.h"
#include "../../../src/juce_core/misc/juce_PlatformUtilities.h"
#include "../../../src/juce_core/io/files/juce_NamedPipe.h"
//==============================================================================
const tchar File::separator = T('/');
const tchar* File::separatorString = T("/");
static File executableFile;
//==============================================================================
void PlatformUtilities::copyToStr255 (Str255& d, const String& s)
{
unsigned char* t = (unsigned char*) d;
t[0] = jmin (254, s.length());
s.copyToBuffer ((char*) t + 1, 254);
}
void PlatformUtilities::copyToStr63 (Str63& d, const String& s)
{
unsigned char* t = (unsigned char*) d;
t[0] = jmin (62, s.length());
s.copyToBuffer ((char*) t + 1, 62);
}
const String PlatformUtilities::cfStringToJuceString (CFStringRef cfString)
{
String result;
if (cfString != 0)
{
#if JUCE_STRINGS_ARE_UNICODE
CFRange range = { 0, CFStringGetLength (cfString) };
UniChar* const u = (UniChar*) juce_malloc (sizeof (UniChar) * (range.length + 1));
CFStringGetCharacters (cfString, range, u);
u[range.length] = 0;
result = convertUTF16ToString (u);
juce_free (u);
#else
const int len = CFStringGetLength (cfString);
char* buffer = (char*) juce_malloc (len + 1);
CFStringGetCString (cfString, buffer, len + 1, CFStringGetSystemEncoding());
result = buffer;
juce_free (buffer);
#endif
}
return result;
}
CFStringRef PlatformUtilities::juceStringToCFString (const String& s)
{
#if JUCE_STRINGS_ARE_UNICODE
const int len = s.length();
const juce_wchar* t = (const juce_wchar*) s;
UniChar* temp = (UniChar*) juce_malloc (sizeof (UniChar) * len + 4);
for (int i = 0; i <= len; ++i)
temp[i] = t[i];
CFStringRef result = CFStringCreateWithCharacters (kCFAllocatorDefault, temp, len);
juce_free (temp);
return result;
#else
return CFStringCreateWithCString (kCFAllocatorDefault,
(const char*) s,
CFStringGetSystemEncoding());
#endif
}
const String PlatformUtilities::convertUTF16ToString (const UniChar* utf16)
{
String s;
while (*utf16 != 0)
s += (juce_wchar) *utf16++;
return s;
}
const String PlatformUtilities::convertToPrecomposedUnicode (const String& s)
{
UnicodeMapping map;
map.unicodeEncoding = CreateTextEncoding (kTextEncodingUnicodeDefault,
kUnicodeNoSubset,
kTextEncodingDefaultFormat);
map.otherEncoding = CreateTextEncoding (kTextEncodingUnicodeDefault,
kUnicodeCanonicalCompVariant,
kTextEncodingDefaultFormat);
map.mappingVersion = kUnicodeUseLatestMapping;
UnicodeToTextInfo conversionInfo = 0;
String result;
if (CreateUnicodeToTextInfo (&map, &conversionInfo) == noErr)
{
const int len = s.length();
UniChar* const tempIn = (UniChar*) juce_calloc (sizeof (UniChar) * len + 4);
UniChar* const tempOut = (UniChar*) juce_calloc (sizeof (UniChar) * len + 4);
for (int i = 0; i <= len; ++i)
tempIn[i] = s[i];
ByteCount bytesRead = 0;
ByteCount outputBufferSize = 0;
if (ConvertFromUnicodeToText (conversionInfo,
len * sizeof (UniChar), tempIn,
kUnicodeDefaultDirectionMask,
0, 0, 0, 0,
len * sizeof (UniChar), &bytesRead,
&outputBufferSize, tempOut) == noErr)
{
result.preallocateStorage (bytesRead / sizeof (UniChar) + 2);
tchar* t = const_cast <tchar*> ((const tchar*) result);
int i;
for (i = 0; i < bytesRead / sizeof (UniChar); ++i)
t[i] = (tchar) tempOut[i];
t[i] = 0;
}
juce_free (tempIn);
juce_free (tempOut);
DisposeUnicodeToTextInfo (&conversionInfo);
}
return result;
}
//==============================================================================
static bool juce_stat (const String& fileName, struct stat& info)
{
return fileName.isNotEmpty()
&& (stat (fileName.toUTF8(), &info) == 0);
}
//==============================================================================
bool juce_isDirectory (const String& fileName)
{
if (fileName.isEmpty())
return true;
struct stat info;
return juce_stat (fileName, info)
&& ((info.st_mode & S_IFDIR) != 0);
}
bool juce_fileExists (const String& fileName, const bool dontCountDirectories)
{
if (fileName.isEmpty())
return false;
const char* const fileNameUTF8 = fileName.toUTF8();
bool exists = access (fileNameUTF8, F_OK) == 0;
if (exists && dontCountDirectories)
{
struct stat info;
const int res = stat (fileNameUTF8, &info);
if (res == 0 && (info.st_mode & S_IFDIR) != 0)
exists = false;
}
return exists;
}
int64 juce_getFileSize (const String& fileName)
{
struct stat info;
if (juce_stat (fileName, info))
return info.st_size;
return 0;
}
const unsigned int macTimeToUnixTimeDiff = 0x7c25be90;
static uint64 utcDateTimeToUnixTime (const UTCDateTime& d)
{
if (d.highSeconds == 0 && d.lowSeconds == 0 && d.fraction == 0)
return 0;
return (((((uint64) d.highSeconds) << 32) | (uint64) d.lowSeconds) * 1000)
+ ((d.fraction * 1000) >> 16)
- 2082844800000ll;
}
static void unixTimeToUtcDateTime (uint64 t, UTCDateTime& d)
{
if (t != 0)
t += 2082844800000ll;
d.highSeconds = (t / 1000) >> 32;
d.lowSeconds = (t / 1000) & (uint64) 0xffffffff;
d.fraction = ((t % 1000) << 16) / 1000;
}
void juce_getFileTimes (const String& fileName,
int64& modificationTime,
int64& accessTime,
int64& creationTime)
{
modificationTime = 0;
accessTime = 0;
creationTime = 0;
FSRef fileRef;
if (PlatformUtilities::makeFSRefFromPath (&fileRef, fileName))
{
FSRefParam info;
zerostruct (info);
info.ref = &fileRef;
info.whichInfo = kFSCatInfoAllDates;
FSCatalogInfo catInfo;
info.catInfo = &catInfo;
if (PBGetCatalogInfoSync (&info) == noErr)
{
creationTime = utcDateTimeToUnixTime (catInfo.createDate);
accessTime = utcDateTimeToUnixTime (catInfo.accessDate);
modificationTime = utcDateTimeToUnixTime (catInfo.contentModDate);
}
}
}
bool juce_setFileTimes (const String& fileName,
int64 modificationTime,
int64 accessTime,
int64 creationTime)
{
FSRef fileRef;
if (PlatformUtilities::makeFSRefFromPath (&fileRef, fileName))
{
FSRefParam info;
zerostruct (info);
info.ref = &fileRef;
info.whichInfo = kFSCatInfoAllDates;
FSCatalogInfo catInfo;
info.catInfo = &catInfo;
if (PBGetCatalogInfoSync (&info) == noErr)
{
if (creationTime != 0)
unixTimeToUtcDateTime (creationTime, catInfo.createDate);
if (modificationTime != 0)
unixTimeToUtcDateTime (modificationTime, catInfo.contentModDate);
if (accessTime != 0)
unixTimeToUtcDateTime (accessTime, catInfo.accessDate);
return PBSetCatalogInfoSync (&info) == noErr;
}
}
return false;
}
bool juce_canWriteToFile (const String& fileName)
{
return access (fileName.toUTF8(), W_OK) == 0;
}
bool juce_setFileReadOnly (const String& fileName, bool isReadOnly)
{
const char* const fileNameUTF8 = fileName.toUTF8();
struct stat info;
const int res = stat (fileNameUTF8, &info);
bool ok = false;
if (res == 0)
{
info.st_mode &= 0777; // Just permissions
if (isReadOnly)
info.st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
else
// Give everybody write permission?
info.st_mode |= S_IWUSR | S_IWGRP | S_IWOTH;
ok = chmod (fileNameUTF8, info.st_mode) == 0;
}
return ok;
}
bool juce_deleteFile (const String& fileName)
{
const char* const fileNameUTF8 = fileName.toUTF8();
if (juce_isDirectory (fileName))
return rmdir (fileNameUTF8) == 0;
else
return remove (fileNameUTF8) == 0;
}
bool juce_copyFile (const String& src, const String& dst)
{
const File destFile (dst);
if (! destFile.create())
return false;
FSRef srcRef, dstRef;
if (! (PlatformUtilities::makeFSRefFromPath (&srcRef, src)
&& PlatformUtilities::makeFSRefFromPath (&dstRef, dst)))
{
return false;
}
int okForks = 0;
CatPositionRec iter;
iter.initialize = 0;
HFSUniStr255 forkName;
// can't just copy the data because this is a bloody Mac, so we need to copy each
// fork separately...
while (FSIterateForks (&srcRef, &iter, &forkName, 0, 0) == noErr)
{
SInt16 srcForkNum = 0, dstForkNum = 0;
OSErr err = FSOpenFork (&srcRef, forkName.length, forkName.unicode, fsRdPerm, &srcForkNum);
if (err == noErr)
{
err = FSOpenFork (&dstRef, forkName.length, forkName.unicode, fsRdWrPerm, &dstForkNum);
if (err == noErr)
{
MemoryBlock buf (32768);
SInt64 pos = 0;
for (;;)
{
ByteCount bytesRead = 0;
err = FSReadFork (srcForkNum, fsFromStart, pos, buf.getSize(), (char*) buf, &bytesRead);
if (bytesRead > 0)
{
err = FSWriteFork (dstForkNum, fsFromStart, pos, bytesRead, (const char*) buf, &bytesRead);
pos += bytesRead;
}
if (err != noErr)
{
if (err == eofErr)
++okForks;
break;
}
}
FSFlushFork (dstForkNum);
FSCloseFork (dstForkNum);
}
FSCloseFork (srcForkNum);
}
}
if (okForks > 0) // some files seem to be ok even if not all their forks get copied..
{
// copy permissions..
struct stat info;
if (juce_stat (src, info))
chmod (dst.toUTF8(), info.st_mode & 0777);
return true;
}
return false;
}
bool juce_moveFile (const String& source, const String& dest)
{
if (rename (source.toUTF8(), dest.toUTF8()) == 0)
return true;
if (juce_canWriteToFile (source)
&& juce_copyFile (source, dest))
{
if (juce_deleteFile (source))
return true;
juce_deleteFile (dest);
}
return false;
}
void juce_createDirectory (const String& fileName)
{
mkdir (fileName.toUTF8(), 0777);
}
void* juce_fileOpen (const String& fileName, bool forWriting)
{
const char* const fileNameUTF8 = fileName.toUTF8();
const char* mode = "rb";
if (forWriting)
{
if (juce_fileExists (fileName, false))
{
FILE* const f = fopen (fileNameUTF8, "r+b");
if (f != 0)
fseek (f, 0, SEEK_END);
return (void*) f;
}
else
{
mode = "w+b";
}
}
return (void*) fopen (fileNameUTF8, mode);
}
void juce_fileClose (void* handle)
{
if (handle != 0)
fclose ((FILE*) handle);
}
int juce_fileRead (void* handle, void* buffer, int size)
{
if (handle != 0)
return fread (buffer, 1, size, (FILE*) handle);
return 0;
}
int juce_fileWrite (void* handle, const void* buffer, int size)
{
if (handle != 0)
return fwrite (buffer, 1, size, (FILE*) handle);
return 0;
}
int64 juce_fileSetPosition (void* handle, int64 pos)
{
if (handle != 0 && fseek ((FILE*) handle, pos, SEEK_SET) == 0)
return pos;
return -1;
}
int64 juce_fileGetPosition (void* handle)
{
if (handle != 0)
return ftell ((FILE*) handle);
else
return -1;
}
void juce_fileFlush (void* handle)
{
if (handle != 0)
fflush ((FILE*) handle);
}
const StringArray juce_getFileSystemRoots()
{
StringArray s;
s.add (T("/"));
return s;
}
const String juce_getVolumeLabel (const String& filenameOnVolume, int& volumeSerialNumber)
{
volumeSerialNumber = 0;
return String::empty;
}
// if this file doesn't exist, find a parent of it that does..
static bool doStatFS (const File* file, struct statfs& result)
{
File f (*file);
for (int i = 5; --i >= 0;)
{
if (f.exists())
break;
f = f.getParentDirectory();
}
return statfs (f.getFullPathName().toUTF8(), &result) == 0;
}
int64 File::getBytesFreeOnVolume() const throw()
{
int64 free_space = 0;
struct statfs buf;
if (doStatFS (this, buf))
// Note: this returns space available to non-super user
free_space = (int64) buf.f_bsize * (int64) buf.f_bavail;
return free_space;
}
//==============================================================================
static bool isFileOnDriveType (const File* const f, const char** types)
{
struct statfs buf;
if (doStatFS (f, buf))
{
const String type (buf.f_fstypename);
while (*types != 0)
if (type.equalsIgnoreCase (*types++))
return true;
}
return false;
}
bool File::isOnCDRomDrive() const throw()
{
static const char* const cdTypes[] = { "cd9660", "cdfs", "cddafs", "udf", 0 };
return isFileOnDriveType (this, (const char**) cdTypes);
}
bool File::isOnHardDisk() const throw()
{
static const char* const nonHDTypes[] = { "nfs", "smbfs", "ramfs", 0 };
return ! (isOnCDRomDrive() || isFileOnDriveType (this, (const char**) nonHDTypes));
}
//==============================================================================
const File File::getSpecialLocation (const SpecialLocationType type)
{
switch (type)
{
case userHomeDirectory:
{
const char* homeDir = getenv ("HOME");
if (homeDir == 0)
{
struct passwd* const pw = getpwuid (getuid());
if (pw != 0)
homeDir = pw->pw_dir;
}
return File (PlatformUtilities::convertToPrecomposedUnicode (homeDir));
}
case userDocumentsDirectory:
return File (T("~/Documents"));
case userDesktopDirectory:
return File (T("~/Desktop"));
case userApplicationDataDirectory:
return File (T("~/Library"));
case commonApplicationDataDirectory:
return File (T("/Library"));
case globalApplicationsDirectory:
return File (T("/Applications"));
case tempDirectory:
{
File tmp (T("~/Library/Caches/") + executableFile.getFileNameWithoutExtension());
tmp.createDirectory();
return tmp.getFullPathName();
}
case currentExecutableFile:
return executableFile;
case currentApplicationFile:
{
const File parent (executableFile.getParentDirectory());
return parent.getFullPathName().endsWithIgnoreCase (T("Contents/MacOS"))
? parent.getParentDirectory().getParentDirectory()
: executableFile;
}
default:
jassertfalse // unknown type?
break;
}
return File::nonexistent;
}
void juce_setCurrentExecutableFileName (const String& filename)
{
executableFile = File::getCurrentWorkingDirectory()
.getChildFile (PlatformUtilities::convertToPrecomposedUnicode (filename));
}
void juce_setCurrentExecutableFileNameFromBundleId (const String& bundleId)
{
CFStringRef bundleIdStringRef = PlatformUtilities::juceStringToCFString (bundleId);
CFBundleRef bundleRef = CFBundleGetBundleWithIdentifier (bundleIdStringRef);
CFRelease (bundleIdStringRef);
if (bundleRef != 0)
{
CFURLRef exeURLRef = CFBundleCopyExecutableURL (bundleRef);
if (exeURLRef != 0)
{
CFStringRef pathStringRef = CFURLCopyFileSystemPath (exeURLRef, kCFURLPOSIXPathStyle);
CFRelease (exeURLRef);
if (pathStringRef != 0)
{
juce_setCurrentExecutableFileName (PlatformUtilities::cfStringToJuceString (pathStringRef));
CFRelease (pathStringRef);
}
}
}
}
//==============================================================================
const File File::getCurrentWorkingDirectory() throw()
{
char buf [2048];
getcwd (buf, sizeof(buf));
return File (PlatformUtilities::convertToPrecomposedUnicode (buf));
}
bool File::setAsCurrentWorkingDirectory() const throw()
{
return chdir (getFullPathName().toUTF8()) == 0;
}
//==============================================================================
struct FindFileStruct
{
String parentDir, wildCard;
DIR* dir;
bool getNextMatch (String& result, bool* const isDir, bool* const isHidden, int64* const fileSize,
Time* const modTime, Time* const creationTime, bool* const isReadOnly)
{
const char* const wildCardUTF8 = wildCard.toUTF8();
for (;;)
{
struct dirent* const de = readdir (dir);
if (de == 0)
break;
if (fnmatch (wildCardUTF8, de->d_name, 0) == 0)
{
result = PlatformUtilities::convertToPrecomposedUnicode (String::fromUTF8 ((const uint8*) de->d_name));
const String path (parentDir + result);
if (isDir != 0 || fileSize != 0)
{
struct stat info;
const bool statOk = juce_stat (path, info);
if (isDir != 0)
*isDir = path.isEmpty() || (statOk && ((info.st_mode & S_IFDIR) != 0));
if (isHidden != 0)
*isHidden = (de->d_name[0] == '.');
if (fileSize != 0)
*fileSize = statOk ? info.st_size : 0;
}
if (modTime != 0 || creationTime != 0)
{
int64 m, a, c;
juce_getFileTimes (path, m, a, c);
if (modTime != 0)
*modTime = m;
if (creationTime != 0)
*creationTime = c;
}
if (isReadOnly != 0)
*isReadOnly = ! juce_canWriteToFile (path);
return true;
}
}
return false;
}
};
// returns 0 on failure
void* juce_findFileStart (const String& directory, const String& wildCard, String& firstResultFile,
bool* isDir, bool* isHidden, int64* fileSize, Time* modTime, Time* creationTime, bool* isReadOnly)
{
DIR* const d = opendir (directory.toUTF8());
if (d != 0)
{
FindFileStruct* const ff = new FindFileStruct();
ff->parentDir = directory;
if (!ff->parentDir.endsWithChar (File::separator))
ff->parentDir += File::separator;
ff->wildCard = wildCard;
ff->dir = d;
if (ff->getNextMatch (firstResultFile, isDir, isHidden, fileSize, modTime, creationTime, isReadOnly))
{
return ff;
}
else
{
firstResultFile = String::empty;
isDir = false;
closedir (d);
delete ff;
}
}
return 0;
}
bool juce_findFileNext (void* handle, String& resultFile,
bool* isDir, bool* isHidden, int64* fileSize, Time* modTime, Time* creationTime, bool* isReadOnly)
{
FindFileStruct* const ff = (FindFileStruct*) handle;
if (ff != 0)
return ff->getNextMatch (resultFile, isDir, isHidden, fileSize, modTime, creationTime, isReadOnly);
return false;
}
void juce_findFileClose (void* handle)
{
FindFileStruct* const ff = (FindFileStruct*)handle;
if (ff != 0)
{
closedir (ff->dir);
delete ff;
}
}
//==============================================================================
bool juce_launchExecutable (const String& pathAndArguments)
{
char* const argv[4] = { "/bin/sh", "-c", (char*) (const char*) pathAndArguments, 0 };
const int cpid = fork();
if (cpid == 0)
{
// Child process
if (execve (argv[0], argv, 0) < 0)
exit (0);
}
else
{
if (cpid < 0)
return false;
}
return true;
}
bool juce_launchFile (const String& fileName,
const String& parameters)
{
bool ok = false;
if (fileName.startsWithIgnoreCase (T("http:")))
{
CFStringRef urlString = PlatformUtilities::juceStringToCFString (fileName);
if (urlString != 0)
{
CFURLRef url = CFURLCreateWithString (kCFAllocatorDefault,
urlString, 0);
CFRelease (urlString);
if (url != 0)
{
ok = (LSOpenCFURLRef (url, 0) == noErr);
CFRelease (url);
}
}
}
else
{
FSRef ref;
if (PlatformUtilities::makeFSRefFromPath (&ref, fileName))
{
if (juce_isDirectory (fileName) && parameters.isNotEmpty())
{
// if we're launching a bundled app with a document..
StringArray docs;
docs.addTokens (parameters, true);
FSRef* docRefs = new FSRef [docs.size()];
for (int i = 0; i < docs.size(); ++i)
PlatformUtilities::makeFSRefFromPath (docRefs + i, docs[i]);
LSLaunchFSRefSpec ors;
ors.appRef = &ref;
ors.numDocs = docs.size();
ors.itemRefs = docRefs;
ors.passThruParams = 0;
ors.launchFlags = kLSLaunchDefaults;
ors.asyncRefCon = 0;
FSRef actual;
ok = (LSOpenFromRefSpec (&ors, &actual) == noErr);
delete docRefs;
}
else
{
if (parameters.isNotEmpty())
ok = juce_launchExecutable (T("\"") + fileName + T("\" ") + parameters);
else
ok = (LSOpenFSRef (&ref, 0) == noErr);
}
}
}
return ok;
}
//==============================================================================
bool PlatformUtilities::makeFSSpecFromPath (FSSpec* fs, const String& path)
{
FSRef ref;
return makeFSRefFromPath (&ref, path)
&& FSGetCatalogInfo (&ref, kFSCatInfoNone, 0, 0, fs, 0) == noErr;
}
bool PlatformUtilities::makeFSRefFromPath (FSRef* destFSRef, const String& path)
{
return FSPathMakeRef ((const UInt8*) path.toUTF8(), destFSRef, 0) == noErr;
}
const String PlatformUtilities::makePathFromFSRef (FSRef* file)
{
uint8 path [2048];
zeromem (path, sizeof (path));
String result;
if (FSRefMakePath (file, (UInt8*) path, sizeof (path) - 1) == noErr)
result = String::fromUTF8 (path);
return PlatformUtilities::convertToPrecomposedUnicode (result);
}
//==============================================================================
OSType PlatformUtilities::getTypeOfFile (const String& filename)
{
FSRef fs;
if (makeFSRefFromPath (&fs, filename))
{
LSItemInfoRecord info;
if (LSCopyItemInfoForRef (&fs, kLSRequestTypeCreator, &info) == noErr)
return info.filetype;
}
return 0;
}
bool PlatformUtilities::isBundle (const String& filename)
{
FSRef fs;
if (makeFSRefFromPath (&fs, filename))
{
LSItemInfoRecord info;
if (LSCopyItemInfoForRef (&fs, kLSItemInfoIsPackage, &info) == noErr)
return (info.flags & kLSItemInfoIsPackage) != 0;
}
return false;
}
END_JUCE_NAMESPACE

+ 529
- 0
build/macosx/platform_specific_code/juce_mac_Fonts.cpp View File

@@ -0,0 +1,529 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "../../../src/juce_core/basics/juce_StandardHeader.h"
#include <ApplicationServices/ApplicationServices.h>
BEGIN_JUCE_NAMESPACE
#include "../../../src/juce_appframework/gui/graphics/fonts/juce_Font.h"
#include "../../../src/juce_appframework/events/juce_Timer.h"
#include "../../../src/juce_appframework/application/juce_DeletedAtShutdown.h"
#include "../../../src/juce_core/basics/juce_Singleton.h"
#include "../../../src/juce_core/misc/juce_PlatformUtilities.h"
//==============================================================================
static OSStatus pascal CubicMoveTo (const Float32Point *pt,
void* callBackDataPtr)
{
Path* const p = (Path*) callBackDataPtr;
p->startNewSubPath (pt->x, pt->y);
return noErr;
}
static OSStatus pascal CubicLineTo (const Float32Point *pt,
void* callBackDataPtr)
{
Path* const p = (Path*) callBackDataPtr;
p->lineTo (pt->x, pt->y);
return noErr;
}
static OSStatus pascal CubicCurveTo (const Float32Point *pt1,
const Float32Point *pt2,
const Float32Point *pt3,
void* callBackDataPtr)
{
Path* const p = (Path*) callBackDataPtr;
p->cubicTo (pt1->x, pt1->y,
pt2->x, pt2->y,
pt3->x, pt3->y);
return noErr;
}
static OSStatus pascal CubicClosePath (void* callBackDataPtr)
{
Path* const p = (Path*) callBackDataPtr;
p->closeSubPath();
return noErr;
}
//==============================================================================
class ATSFontHelper
{
ATSUFontID fontId;
ATSUStyle style;
ATSCubicMoveToUPP moveToProc;
ATSCubicLineToUPP lineToProc;
ATSCubicCurveToUPP curveToProc;
ATSCubicClosePathUPP closePathProc;
float totalSize, ascent;
TextToUnicodeInfo encodingInfo;
public:
String name;
bool isBold, isItalic;
float fontSize;
int refCount;
ATSFontHelper (const String& name_,
const bool bold_,
const bool italic_,
const float size_)
: fontId (0),
name (name_),
isBold (bold_),
isItalic (italic_),
fontSize (size_),
refCount (1)
{
const char* const nameUtf8 = name_.toUTF8();
ATSUFindFontFromName (const_cast <char*> (nameUtf8),
strlen (nameUtf8),
kFontFullName,
kFontNoPlatformCode,
kFontNoScriptCode,
kFontNoLanguageCode,
&fontId);
ATSUCreateStyle (&style);
ATSUAttributeTag attTypes[] = { kATSUFontTag,
kATSUQDBoldfaceTag,
kATSUQDItalicTag,
kATSUSizeTag };
ByteCount attSizes[] = { sizeof (ATSUFontID),
sizeof (Boolean),
sizeof (Boolean),
sizeof (Fixed) };
Boolean bold = bold_, italic = italic_;
Fixed size = X2Fix (size_);
ATSUAttributeValuePtr attValues[] = { &fontId,
&bold,
&italic,
&size };
ATSUSetAttributes (style, 4, attTypes, attSizes, attValues);
moveToProc = NewATSCubicMoveToUPP (CubicMoveTo);
lineToProc = NewATSCubicLineToUPP (CubicLineTo);
curveToProc = NewATSCubicCurveToUPP (CubicCurveTo);
closePathProc = NewATSCubicClosePathUPP (CubicClosePath);
ascent = 0.0f;
float kern, descent = 0.0f;
getPathAndKerning (T('N'), T('O'), 0, kern, &ascent, &descent);
totalSize = ascent + descent;
}
~ATSFontHelper()
{
ATSUDisposeStyle (style);
DisposeATSCubicMoveToUPP (moveToProc);
DisposeATSCubicLineToUPP (lineToProc);
DisposeATSCubicCurveToUPP (curveToProc);
DisposeATSCubicClosePathUPP (closePathProc);
}
bool getPathAndKerning (const juce_wchar char1,
const juce_wchar char2,
Path* path,
float& kerning,
float* ascent,
float* descent)
{
bool ok = false;
UniChar buffer[4];
buffer[0] = T(' ');
buffer[1] = char1;
buffer[2] = char2;
buffer[3] = 0;
UniCharCount count = kATSUToTextEnd;
ATSUTextLayout layout;
OSStatus err = ATSUCreateTextLayoutWithTextPtr (buffer,
0,
2,
2,
1,
&count,
&style,
&layout);
if (err == noErr)
{
ATSUSetTransientFontMatching (layout, true);
ATSLayoutRecord* layoutRecords;
ItemCount numRecords;
Fixed* deltaYs;
ItemCount numDeltaYs;
ATSUDirectGetLayoutDataArrayPtrFromTextLayout (layout,
0,
kATSUDirectDataLayoutRecordATSLayoutRecordCurrent,
(void**) &layoutRecords,
&numRecords);
ATSUDirectGetLayoutDataArrayPtrFromTextLayout (layout,
0,
kATSUDirectDataBaselineDeltaFixedArray,
(void**) &deltaYs,
&numDeltaYs);
if (numRecords > 2)
{
kerning = (float) (Fix2X (layoutRecords[2].realPos)
- Fix2X (layoutRecords[1].realPos));
if (ascent != 0)
{
ATSUTextMeasurement asc;
ByteCount actualSize;
ATSUGetLineControl (layout,
0,
kATSULineAscentTag,
sizeof (ATSUTextMeasurement),
&asc,
&actualSize);
*ascent = (float) Fix2X (asc);
}
if (descent != 0)
{
ATSUTextMeasurement desc;
ByteCount actualSize;
ATSUGetLineControl (layout,
0,
kATSULineDescentTag,
sizeof (ATSUTextMeasurement),
&desc,
&actualSize);
*descent = (float) Fix2X (desc);
}
if (path != 0)
{
OSStatus callbackResult;
ok = (ATSUGlyphGetCubicPaths (style,
layoutRecords[1].glyphID,
moveToProc,
lineToProc,
curveToProc,
closePathProc,
(void*) path,
&callbackResult) == noErr);
if (numDeltaYs > 0 && ok)
{
const float dy = (float) Fix2X (deltaYs[1]);
path->applyTransform (AffineTransform::translation (0.0f, dy));
}
}
else
{
ok = true;
}
}
if (deltaYs != 0)
ATSUDirectReleaseLayoutDataArrayPtr (0, kATSUDirectDataBaselineDeltaFixedArray,
(void**) &deltaYs);
if (layoutRecords != 0)
ATSUDirectReleaseLayoutDataArrayPtr (0, kATSUDirectDataLayoutRecordATSLayoutRecordCurrent,
(void**) &layoutRecords);
ATSUDisposeTextLayout (layout);
}
return kerning;
}
float getAscent()
{
return ascent;
}
float getTotalHeight()
{
return totalSize;
}
juce_wchar getDefaultChar()
{
return 0;
}
};
//==============================================================================
class ATSFontHelperCache : public Timer,
public DeletedAtShutdown
{
VoidArray cache;
public:
ATSFontHelperCache()
{
}
~ATSFontHelperCache()
{
for (int i = cache.size(); --i >= 0;)
{
ATSFontHelper* const f = (ATSFontHelper*) cache[i];
delete f;
}
clearSingletonInstance();
}
ATSFontHelper* getFont (const String& name,
const bool bold,
const bool italic,
const float size = 1024)
{
for (int i = cache.size(); --i >= 0;)
{
ATSFontHelper* const f = (ATSFontHelper*) cache.getUnchecked(i);
if (f->name == name
&& f->isBold == bold
&& f->isItalic == italic
&& f->fontSize == size)
{
f->refCount++;
return f;
}
}
ATSFontHelper* const f = new ATSFontHelper (name, bold, italic, size);
cache.add (f);
return f;
}
void releaseFont (ATSFontHelper* f)
{
for (int i = cache.size(); --i >= 0;)
{
ATSFontHelper* const f2 = (ATSFontHelper*) cache[i];
if (f == f2)
{
f->refCount--;
if (f->refCount == 0)
startTimer (5000);
break;
}
}
}
void timerCallback()
{
for (int i = cache.size(); --i >= 0;)
{
ATSFontHelper* const f = (ATSFontHelper*) cache[i];
if (f->refCount > 0)
{
stopTimer();
return;
}
}
delete this;
}
juce_DeclareSingleton_SingleThreaded (ATSFontHelperCache, false)
};
juce_ImplementSingleton_SingleThreaded (ATSFontHelperCache)
//==============================================================================
void Typeface::initialiseTypefaceCharacteristics (const String& fontName,
bool bold,
bool italic,
bool addAllGlyphsToFont)
{
ATSFontHelper* const helper = ATSFontHelperCache::getInstance()
->getFont (fontName, bold, italic);
clear();
setAscent (helper->getAscent() / helper->getTotalHeight());
setName (fontName);
setDefaultCharacter (helper->getDefaultChar());
setBold (bold);
setItalic (italic);
if (addAllGlyphsToFont)
{
//xxx
jassertfalse
}
ATSFontHelperCache::getInstance()->releaseFont (helper);
}
void Typeface::findAndAddSystemGlyph (juce_wchar character)
{
ATSFontHelper* const helper = ATSFontHelperCache::getInstance()
->getFont (getName(), isBold(), isItalic());
Path path;
float width;
if (helper->getPathAndKerning (character, T('I'), &path, width, 0, 0))
{
path.applyTransform (AffineTransform::scale (1.0f / helper->getTotalHeight(),
1.0f / helper->getTotalHeight()));
addGlyph (character, path, width / helper->getTotalHeight());
for (int i = 0; i < glyphs.size(); ++i)
{
const TypefaceGlyphInfo* const g = (const TypefaceGlyphInfo*) glyphs.getUnchecked(i);
float kerning;
if (helper->getPathAndKerning (character, g->getCharacter(), 0, kerning, 0, 0))
{
kerning = (kerning - width) / helper->getTotalHeight();
if (kerning != 0)
addKerningPair (character, g->getCharacter(), kerning);
}
if (helper->getPathAndKerning (g->getCharacter(), character, 0, kerning, 0, 0))
{
kerning = kerning / helper->getTotalHeight() - g->width;
if (kerning != 0)
addKerningPair (g->getCharacter(), character, kerning);
}
}
}
ATSFontHelperCache::getInstance()->releaseFont (helper);
}
const StringArray Font::findAllTypefaceNames()
{
StringArray names;
ATSFontIterator iter;
if (ATSFontIteratorCreate (kATSFontContextGlobal,
0,
0,
kATSOptionFlagsRestrictedScope,
&iter) == noErr)
{
ATSFontRef font;
while (ATSFontIteratorNext (iter, &font) == noErr)
{
CFStringRef name;
if (ATSFontGetName (font,
kATSOptionFlagsDefault,
&name) == noErr)
{
const String nm (PlatformUtilities::cfStringToJuceString (name));
if (nm.isNotEmpty())
names.add (nm);
CFRelease (name);
}
}
ATSFontIteratorRelease (&iter);
}
// Use some totuous logic to eliminate bold/italic versions of fonts that we've already got
// a plain version of. This is only necessary because of Carbon's total lack of support
// for dealing with font families...
for (int j = names.size(); --j >= 0;)
{
const char* const endings[] = { " bold", " italic", " bold italic", " bolditalic",
" oblque", " bold oblique", " boldoblique" };
for (int i = 0; i < numElementsInArray (endings); ++i)
{
const String ending (endings[i]);
if (names[j].endsWithIgnoreCase (ending))
{
const String root (names[j].dropLastCharacters (ending.length()).trimEnd());
if (names.contains (root)
|| names.contains (root + T(" plain"), true))
{
names.remove (j);
break;
}
}
}
}
names.sort (true);
return names;
}
void Font::getDefaultFontNames (String& defaultSans, String& defaultSerif, String& defaultFixed)
{
defaultSans = T("Lucida Grande");
defaultSerif = T("Times New Roman");
defaultFixed = T("Monaco");
}
END_JUCE_NAMESPACE

+ 394
- 0
build/macosx/platform_specific_code/juce_mac_HTTPStream.h View File

@@ -0,0 +1,394 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#ifndef __JUCE_MAC_HTTPSTREAM_JUCEHEADER__
#define __JUCE_MAC_HTTPSTREAM_JUCEHEADER__
// (This file gets included by the mac + linux networking code)
//==============================================================================
/** A HTTP input stream that uses sockets.
*/
class JUCE_HTTPSocketStream
{
public:
//==============================================================================
JUCE_HTTPSocketStream()
: statusCode (0),
readPosition (0),
socketHandle (-1),
levelsOfRedirection (0),
timeoutSeconds (15)
{
}
~JUCE_HTTPSocketStream()
{
closeSocket();
}
//==============================================================================
bool open (const String& url,
const String& optionalPostText,
const bool isPost)
{
closeSocket();
String hostName, hostPath;
int hostPort;
if (! decomposeURL (url, hostName, hostPath, hostPort))
return false;
struct hostent* const host
= gethostbyname ((const char*) hostName.toUTF8());
if (host == 0)
return false;
struct sockaddr_in address;
zerostruct (address);
memcpy ((void*) &address.sin_addr, (const void*) host->h_addr, host->h_length);
address.sin_family = host->h_addrtype;
address.sin_port = htons (hostPort);
socketHandle = socket (host->h_addrtype, SOCK_STREAM, 0);
if (socketHandle == -1)
return false;
int receiveBufferSize = 16384;
setsockopt (socketHandle, SOL_SOCKET, SO_RCVBUF, (char*) &receiveBufferSize, sizeof (receiveBufferSize));
setsockopt (socketHandle, SOL_SOCKET, SO_KEEPALIVE, 0, 0);
if (connect (socketHandle, (struct sockaddr*) &address, sizeof (address)) == -1)
{
closeSocket();
return false;
}
String proxyURL (getenv ("http_proxy"));
if (! proxyURL.startsWithIgnoreCase (T("http://")))
proxyURL = String::empty;
const String requestHeader (createRequestHeader (hostName, hostPath,
proxyURL, url,
hostPort, optionalPostText,
isPost));
const char* const utf8Header = (const char*) requestHeader.toUTF8();
const int headerLen = strlen (utf8Header);
if (! send (socketHandle, utf8Header, headerLen, 0) == headerLen)
{
closeSocket();
return false;
}
const String responseHeader (readResponse());
if (responseHeader.isNotEmpty())
{
//DBG (responseHeader);
StringArray lines;
lines.addLines (responseHeader);
statusCode = responseHeader.fromFirstOccurrenceOf (T(" "), false, false)
.substring (4).getIntValue();
//int contentLength = findHeaderItem (lines, T("Content-Length:")).getIntValue();
//bool isChunked = findHeaderItem (lines, T("Transfer-Encoding:")).equalsIgnoreCase ("chunked");
String location (findHeaderItem (lines, T("Location:")));
if (statusCode >= 300 && statusCode < 400
&& location.isNotEmpty())
{
if (! location.startsWithIgnoreCase (T("http://")))
location = T("http://") + location;
if (levelsOfRedirection++ < 3)
return open (location, optionalPostText, isPost);
}
else
{
levelsOfRedirection = 0;
return true;
}
}
closeSocket();
return false;
}
//==============================================================================
int read (void* buffer, int bytesToRead)
{
fd_set readbits;
FD_ZERO (&readbits);
FD_SET (socketHandle, &readbits);
struct timeval tv;
tv.tv_sec = timeoutSeconds;
tv.tv_usec = 0;
if (select (socketHandle + 1, &readbits, 0, 0, &tv) <= 0)
return 0; // (timeout)
const int bytesRead = jmax (0, recv (socketHandle, buffer, bytesToRead, MSG_WAITALL));
readPosition += bytesRead;
return bytesRead;
}
//==============================================================================
int statusCode, readPosition;
//==============================================================================
juce_UseDebuggingNewOperator
private:
int socketHandle, levelsOfRedirection;
const int timeoutSeconds;
//==============================================================================
void closeSocket()
{
if (socketHandle >= 0)
close (socketHandle);
socketHandle = -1;
}
const String createRequestHeader (const String& hostName,
const String& hostPath,
const String& proxyURL,
const String& originalURL,
const int hostPort,
const String& optionalPostText,
const bool isPost)
{
String header (isPost ? T("POST ") : T("GET "));
if (proxyURL.isEmpty())
{
header << hostPath << T(" HTTP/1.1\r\nHost: ")
<< hostName << ":" << hostPort;
}
else
{
String proxyName, proxyPath;
int proxyPort;
if (! decomposeURL (proxyURL, proxyName, proxyPath, proxyPort))
return String::empty;
header << originalURL << T(" HTTP/1.1\r\nHost: ")
<< proxyName << T(":") << proxyPort;
/* xxx needs finishing
const char* proxyAuth = getenv ("http_proxy_auth");
if (proxyAuth != 0)
header << T("\r\nProxy-Authorization: ") << Base64Encode (proxyAuth);
*/
}
header << T("\r\nUser-Agent: JUCE/")
<< JUCE_MAJOR_VERSION << T('.') << JUCE_MINOR_VERSION
<< T("\r\nConnection: Close\r\n");
if (isPost && optionalPostText.isNotEmpty())
{
const char* const postTextUTF8 = (const char*) optionalPostText.toUTF8();
header << T("Content-type: application/x-www-form-urlencoded\r\nContent-length: ")
<< (int) strlen (postTextUTF8) << T("\r\n\r\n")
<< optionalPostText;
}
header << T("\r\n");
//DBG (header);
return header;
}
const String readResponse()
{
int bytesRead = 0, numConsecutiveLFs = 0;
MemoryBlock buffer (1024, true);
while (numConsecutiveLFs < 2 && bytesRead < 32768)
{
fd_set readbits;
FD_ZERO (&readbits);
FD_SET (socketHandle, &readbits);
struct timeval tv;
tv.tv_sec = timeoutSeconds;
tv.tv_usec = 0;
if (select (socketHandle + 1, &readbits, 0, 0, &tv) <= 0)
return String::empty; // (timeout)
buffer.ensureSize (bytesRead + 8, true);
char* const dest = (char*) buffer.getData() + bytesRead;
if (recv (socketHandle, dest, 1, 0) == -1)
return String::empty;
const char lastByte = *dest;
++bytesRead;
if (lastByte == '\n')
++numConsecutiveLFs;
else if (lastByte != '\r')
numConsecutiveLFs = 0;
}
const String header (String::fromUTF8 ((const uint8*) buffer.getData()));
if (header.startsWithIgnoreCase (T("HTTP/")))
return header.trimEnd();
return String::empty;
}
//==============================================================================
static bool decomposeURL (const String& url,
String& host, String& path, int& port)
{
if (! url.startsWithIgnoreCase (T("http://")))
return false;
const int nextSlash = url.indexOfChar (7, '/');
int nextColon = url.indexOfChar (7, ':');
if (nextColon > nextSlash && nextSlash > 0)
nextColon = -1;
if (nextColon >= 0)
{
host = url.substring (7, nextColon);
if (nextSlash >= 0)
port = url.substring (nextColon + 1, nextSlash).getIntValue();
else
port = url.substring (nextColon + 1).getIntValue();
}
else
{
port = 80;
if (nextSlash >= 0)
host = url.substring (7, nextSlash);
else
host = url.substring (7);
}
if (nextSlash >= 0)
path = url.substring (nextSlash);
else
path = T("/");
return true;
}
//==============================================================================
static const String findHeaderItem (const StringArray& lines, const String& itemName)
{
for (int i = 0; i < lines.size(); ++i)
if (lines[i].startsWithIgnoreCase (itemName))
return lines[i].substring (itemName.length()).trim();
return String::empty;
}
};
//==============================================================================
bool juce_isOnLine()
{
return true;
}
void* juce_openInternetFile (const String& url,
const String& optionalPostText,
const bool isPost)
{
JUCE_HTTPSocketStream* const s = new JUCE_HTTPSocketStream();
if (s->open (url, optionalPostText, isPost))
return s;
delete s;
return 0;
}
void juce_closeInternetFile (void* handle)
{
JUCE_HTTPSocketStream* const s = (JUCE_HTTPSocketStream*) handle;
if (s != 0)
delete s;
}
int juce_getStatusCodeFor (void* handle)
{
JUCE_HTTPSocketStream* const s = (JUCE_HTTPSocketStream*) handle;
if (s != 0)
return s->statusCode;
return 0;
}
int juce_readFromInternetFile (void* handle, void* buffer, int bytesToRead)
{
JUCE_HTTPSocketStream* const s = (JUCE_HTTPSocketStream*) handle;
if (s != 0)
return s->read (buffer, bytesToRead);
return 0;
}
int juce_seekInInternetFile (void* handle, int newPosition)
{
JUCE_HTTPSocketStream* const s = (JUCE_HTTPSocketStream*) handle;
if (s != 0)
return s->readPosition;
return 0;
}
#endif // __JUCE_MAC_HTTPSTREAM_JUCEHEADER__

+ 342
- 0
build/macosx/platform_specific_code/juce_mac_Messaging.cpp View File

@@ -0,0 +1,342 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "../../../src/juce_core/basics/juce_StandardHeader.h"
#include <Carbon/Carbon.h>
BEGIN_JUCE_NAMESPACE
#include "../../../src/juce_appframework/events/juce_MessageManager.h"
#include "../../../src/juce_appframework/application/juce_Application.h"
#include "../../../src/juce_appframework/gui/components/juce_Desktop.h"
#include "../../../src/juce_core/text/juce_StringArray.h"
#include "../../../src/juce_core/threads/juce_Thread.h"
#include "../../../src/juce_core/misc/juce_PlatformUtilities.h"
#undef Point
static int kJUCEClass = FOUR_CHAR_CODE ('JUCE');
const int kJUCEKind = 1;
const int kCallbackKind = 2;
extern void juce_HandleProcessFocusChange();
extern void juce_maximiseAllMinimisedWindows();
extern void juce_InvokeMainMenuCommand (const HICommand& command);
extern void juce_MainMenuAboutToBeUsed();
static pascal OSStatus EventHandlerProc (EventHandlerCallRef, EventRef theEvent, void* userData)
{
void* event = 0;
GetEventParameter (theEvent, 'mess', typeVoidPtr, 0, sizeof (void*), 0, &event);
if (event != 0)
MessageManager::getInstance()->deliverMessage (event);
return noErr;
}
struct CallbackMessagePayload
{
MessageCallbackFunction* function;
void* parameter;
void* volatile result;
bool volatile hasBeenExecuted;
};
static pascal OSStatus CallbackHandlerProc (EventHandlerCallRef, EventRef theEvent, void* userData)
{
CallbackMessagePayload* pl = 0;
GetEventParameter (theEvent, 'mess', typeVoidPtr, 0, sizeof(pl), 0, &pl);
if (pl != 0)
{
pl->result = (*pl->function) (pl->parameter);
pl->hasBeenExecuted = true;
}
return noErr;
}
static pascal OSStatus MouseClickHandlerProc (EventHandlerCallRef, EventRef theEvent, void* userData)
{
::Point where;
GetEventParameter (theEvent, kEventParamMouseLocation, typeQDPoint, 0, sizeof(::Point), 0, &where);
WindowRef window;
if (FindWindow (where, &window) == inMenuBar)
{
// turn off the wait cursor before going in here..
const int oldTimeBeforeWaitCursor = MessageManager::getInstance()->getTimeBeforeShowingWaitCursor();
MessageManager::getInstance()->setTimeBeforeShowingWaitCursor (0);
if (Component::getCurrentlyModalComponent() != 0)
Component::getCurrentlyModalComponent()->inputAttemptWhenModal();
juce_MainMenuAboutToBeUsed();
MenuSelect (where);
HiliteMenu (0);
MessageManager::getInstance()->setTimeBeforeShowingWaitCursor (oldTimeBeforeWaitCursor);
return noErr;
}
return eventNotHandledErr;
}
static pascal OSErr QuitAppleEventHandler (const AppleEvent *appleEvt, AppleEvent* reply, long refcon)
{
if (JUCEApplication::getInstance() != 0)
JUCEApplication::getInstance()->systemRequestedQuit();
return noErr;
}
static pascal OSErr OpenDocEventHandler (const AppleEvent *appleEvt, AppleEvent* reply, long refcon)
{
AEDescList docs;
StringArray files;
if (AEGetParamDesc (appleEvt, keyDirectObject, typeAEList, &docs) == noErr)
{
long num;
if (AECountItems (&docs, &num) == noErr)
{
for (int i = 1; i <= num; ++i)
{
FSRef file;
AEKeyword keyword;
DescType type;
Size size;
if (AEGetNthPtr (&docs, i, typeFSRef, &keyword, &type,
&file, sizeof (file), &size) == noErr)
{
const String path (PlatformUtilities::makePathFromFSRef (&file));
if (path.isNotEmpty())
files.add (path.quoted());
}
}
if (files.size() > 0
&& JUCEApplication::getInstance() != 0)
{
JUCE_TRY
{
JUCEApplication::getInstance()
->anotherInstanceStarted (files.joinIntoString (T(" ")));
}
JUCE_CATCH_ALL
}
}
AEDisposeDesc (&docs);
};
return noErr;
}
static pascal OSStatus AppEventHandlerProc (EventHandlerCallRef, EventRef theEvent, void* userData)
{
const UInt32 eventClass = GetEventClass (theEvent);
if (eventClass == kEventClassCommand)
{
HICommand command;
if (GetEventParameter (theEvent, kEventParamHICommand, typeHICommand, 0, sizeof (command), 0, &command) == noErr
|| GetEventParameter (theEvent, kEventParamDirectObject, typeHICommand, 0, sizeof (command), 0, &command) == noErr)
{
if (command.commandID == kHICommandQuit)
{
if (JUCEApplication::getInstance() != 0)
JUCEApplication::getInstance()->systemRequestedQuit();
return noErr;
}
else if (command.commandID == kHICommandMaximizeAll
|| command.commandID == kHICommandMaximizeWindow
|| command.commandID == kHICommandBringAllToFront)
{
juce_maximiseAllMinimisedWindows();
return noErr;
}
else
{
juce_InvokeMainMenuCommand (command);
}
}
}
else if (eventClass == kEventClassApplication)
{
if (GetEventKind (theEvent) == kEventAppFrontSwitched)
{
juce_HandleProcessFocusChange();
}
else if (GetEventKind (theEvent) == kEventAppShown)
{
// this seems to blank the windows, so we need to do a repaint..
for (int i = Desktop::getInstance().getNumComponents(); --i >= 0;)
{
Component* const c = Desktop::getInstance().getComponent (i);
if (c != 0)
c->repaint();
}
}
}
return eventNotHandledErr;
}
static EventQueueRef mainQueue;
static EventHandlerRef juceEventHandler = 0;
static EventHandlerRef callbackEventHandler = 0;
//==============================================================================
void MessageManager::doPlatformSpecificInitialisation()
{
static bool initialised = false;
if (! initialised)
{
initialised = true;
// work-around for a bug in MacOS 10.2..
ProcessSerialNumber junkPSN;
(void) GetCurrentProcess (&junkPSN);
mainQueue = GetMainEventQueue();
// if we're linking a Juce app to one or more dynamic libraries, we'll need different values
// for this so each module doesn't interfere with the others.
UnsignedWide t;
Microseconds (&t);
kJUCEClass ^= t.lo;
}
const EventTypeSpec type1 = { kJUCEClass, kJUCEKind };
InstallApplicationEventHandler (NewEventHandlerUPP (EventHandlerProc), 1, &type1, 0, &juceEventHandler);
const EventTypeSpec type2 = { kJUCEClass, kCallbackKind };
InstallApplicationEventHandler (NewEventHandlerUPP (CallbackHandlerProc), 1, &type2, 0, &callbackEventHandler);
// only do this stuff if we're running as an application rather than a library..
if (JUCEApplication::getInstance() != 0)
{
const EventTypeSpec type3 = { kEventClassMouse, kEventMouseDown };
InstallApplicationEventHandler (NewEventHandlerUPP (MouseClickHandlerProc), 1, &type3, 0, 0);
const EventTypeSpec type4[] = { { kEventClassApplication, kEventAppShown },
{ kEventClassApplication, kEventAppFrontSwitched },
{ kEventClassCommand, kEventProcessCommand } };
InstallApplicationEventHandler (NewEventHandlerUPP (AppEventHandlerProc), 3, type4, 0, 0);
AEInstallEventHandler (kCoreEventClass, kAEQuitApplication,
NewAEEventHandlerUPP (QuitAppleEventHandler), 0, false);
AEInstallEventHandler (kCoreEventClass, kAEOpenDocuments,
NewAEEventHandlerUPP (OpenDocEventHandler), 0, false);
}
}
void MessageManager::doPlatformSpecificShutdown()
{
if (juceEventHandler != 0)
{
RemoveEventHandler (juceEventHandler);
juceEventHandler = 0;
}
if (callbackEventHandler != 0)
{
RemoveEventHandler (callbackEventHandler);
callbackEventHandler = 0;
}
}
bool juce_postMessageToSystemQueue (void* message)
{
jassert (mainQueue == GetMainEventQueue());
EventRef event;
if (CreateEvent (0, kJUCEClass, kJUCEKind, 0, kEventAttributeUserEvent, &event) == noErr)
{
SetEventParameter (event, 'mess', typeVoidPtr, sizeof (void*), &message);
const bool ok = PostEventToQueue (mainQueue, event, kEventPriorityStandard) == noErr;
ReleaseEvent (event);
return ok;
}
return false;
}
void MessageManager::broadcastMessage (const String& value)
{
}
void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* callback,
void* data)
{
if (isThisTheMessageThread())
{
return (*callback) (data);
}
else
{
jassert (mainQueue == GetMainEventQueue());
CallbackMessagePayload cmp;
cmp.function = callback;
cmp.parameter = data;
cmp.result = 0;
cmp.hasBeenExecuted = false;
EventRef event;
if (CreateEvent (0, kJUCEClass, kCallbackKind, 0, kEventAttributeUserEvent, &event) == noErr)
{
void* v = &cmp;
SetEventParameter (event, 'mess', typeVoidPtr, sizeof (void*), &v);
if (PostEventToQueue (mainQueue, event, kEventPriorityStandard) == noErr)
{
while (! cmp.hasBeenExecuted)
Thread::yield();
return cmp.result;
}
}
return 0;
}
}
END_JUCE_NAMESPACE

+ 237
- 0
build/macosx/platform_specific_code/juce_mac_NamedPipe.cpp View File

@@ -0,0 +1,237 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "../../../src/juce_core/basics/juce_StandardHeader.h"
#include <sys/stat.h>
#include <sys/dir.h>
#include <fcntl.h>
// As well as being for the mac, this file is included by the linux build.
#ifdef JUCE_MAC
#include <Carbon/Carbon.h>
#else
#include <sys/wait.h>
#include <errno.h>
#include <unistd.h>
#endif
BEGIN_JUCE_NAMESPACE
#include "../../../src/juce_core/io/files/juce_File.h"
#include "../../../src/juce_core/io/files/juce_NamedPipe.h"
//==============================================================================
struct NamedPipeInternal
{
String pipeInName, pipeOutName;
int pipeIn, pipeOut;
bool volatile createdPipe, blocked, stopReadOperation;
static void signalHandler (int) {}
};
void NamedPipe::cancelPendingReads()
{
while (internal != 0 && ((NamedPipeInternal*) internal)->blocked)
{
NamedPipeInternal* const intern = (NamedPipeInternal*) internal;
intern->stopReadOperation = true;
char buffer [1] = { 0 };
::write (intern->pipeIn, buffer, 1);
int timeout = 2000;
while (intern->blocked && --timeout >= 0)
sleep (2);
intern->stopReadOperation = false;
}
}
void NamedPipe::close()
{
NamedPipeInternal* const intern = (NamedPipeInternal*) internal;
if (intern != 0)
{
internal = 0;
if (intern->pipeIn != -1)
::close (intern->pipeIn);
if (intern->pipeOut != -1)
::close (intern->pipeOut);
if (intern->createdPipe)
{
unlink (intern->pipeInName);
unlink (intern->pipeOutName);
}
delete intern;
}
}
bool NamedPipe::openInternal (const String& pipeName, const bool createPipe)
{
close();
NamedPipeInternal* const intern = new NamedPipeInternal();
internal = intern;
intern->createdPipe = createPipe;
intern->blocked = false;
intern->stopReadOperation = false;
signal (SIGPIPE, NamedPipeInternal::signalHandler);
siginterrupt (SIGPIPE, 1);
const String pipePath (T("/tmp/") + File::createLegalFileName (pipeName));
intern->pipeInName = pipePath + T("_in");
intern->pipeOutName = pipePath + T("_out");
intern->pipeIn = -1;
intern->pipeOut = -1;
if (createPipe)
{
if ((mkfifo (intern->pipeInName, 0666) && errno != EEXIST)
|| (mkfifo (intern->pipeOutName, 0666) && errno != EEXIST))
{
delete intern;
internal = 0;
return false;
}
}
return true;
}
int NamedPipe::read (void* destBuffer, int maxBytesToRead, int /*timeOutMilliseconds*/)
{
int bytesRead = -1;
NamedPipeInternal* const intern = (NamedPipeInternal*) internal;
if (intern != 0)
{
intern->blocked = true;
if (intern->pipeIn == -1)
{
if (intern->createdPipe)
intern->pipeIn = ::open (intern->pipeInName, O_RDWR);
else
intern->pipeIn = ::open (intern->pipeOutName, O_RDWR);
if (intern->pipeIn == -1)
{
intern->blocked = false;
return -1;
}
}
bytesRead = 0;
char* p = (char*) destBuffer;
while (bytesRead < maxBytesToRead)
{
const int bytesThisTime = maxBytesToRead - bytesRead;
const int numRead = ::read (intern->pipeIn, p, bytesThisTime);
if (numRead <= 0 || intern->stopReadOperation)
{
bytesRead = -1;
break;
}
bytesRead += numRead;
p += bytesRead;
}
intern->blocked = false;
}
return bytesRead;
}
int NamedPipe::write (const void* sourceBuffer, int numBytesToWrite, int timeOutMilliseconds)
{
int bytesWritten = -1;
NamedPipeInternal* const intern = (NamedPipeInternal*) internal;
if (intern != 0)
{
if (intern->pipeOut == -1)
{
if (intern->createdPipe)
intern->pipeOut = ::open (intern->pipeOutName, O_WRONLY);
else
intern->pipeOut = ::open (intern->pipeInName, O_WRONLY);
if (intern->pipeOut == -1)
{
return -1;
}
}
const char* p = (const char*) sourceBuffer;
bytesWritten = 0;
const uint32 timeOutTime = Time::getMillisecondCounter() + timeOutMilliseconds;
while (bytesWritten < numBytesToWrite
&& (timeOutMilliseconds < 0 || Time::getMillisecondCounter() < timeOutTime))
{
const int bytesThisTime = numBytesToWrite - bytesWritten;
const int numWritten = ::write (intern->pipeOut, p, bytesThisTime);
if (numWritten <= 0)
{
bytesWritten = -1;
break;
}
bytesWritten += numWritten;
p += bytesWritten;
}
}
return bytesWritten;
}
END_JUCE_NAMESPACE

+ 138
- 0
build/macosx/platform_specific_code/juce_mac_Network.cpp View File

@@ -0,0 +1,138 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "../../../src/juce_core/basics/juce_StandardHeader.h"
#include <IOKit/IOKitLib.h>
#include <IOKit/network/IOEthernetInterface.h>
#include <IOKit/network/IONetworkInterface.h>
#include <IOKit/network/IOEthernetController.h>
#include <Carbon/Carbon.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
BEGIN_JUCE_NAMESPACE
#include "../../../src/juce_core/text/juce_String.h"
#include "../../../src/juce_core/basics/juce_Time.h"
#include "../../../src/juce_core/basics/juce_SystemStats.h"
#include "../../../src/juce_core/containers/juce_MemoryBlock.h"
#include "../../../src/juce_core/text/juce_StringArray.h"
#include "juce_mac_HTTPStream.h"
//==============================================================================
static bool GetEthernetIterator (io_iterator_t* matchingServices)
{
mach_port_t masterPort;
if (IOMasterPort (MACH_PORT_NULL, &masterPort) == KERN_SUCCESS)
{
CFMutableDictionaryRef dict = IOServiceMatching (kIOEthernetInterfaceClass);
if (dict != 0)
{
CFMutableDictionaryRef propDict = CFDictionaryCreateMutable (kCFAllocatorDefault,
0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
if (propDict != 0)
{
CFDictionarySetValue (propDict, CFSTR (kIOPrimaryInterface), kCFBooleanTrue);
CFDictionarySetValue (dict, CFSTR (kIOPropertyMatchKey), propDict);
CFRelease (propDict);
}
}
return IOServiceGetMatchingServices (masterPort, dict, matchingServices) == KERN_SUCCESS;
}
return false;
}
int SystemStats::getMACAddresses (int64* addresses, int maxNum)
{
int numResults = 0;
io_iterator_t it;
if (GetEthernetIterator (&it))
{
io_object_t i;
while ((i = IOIteratorNext (it)) != 0)
{
io_object_t controller;
if (IORegistryEntryGetParentEntry (i, kIOServicePlane, &controller) == KERN_SUCCESS)
{
CFTypeRef data = IORegistryEntryCreateCFProperty (controller,
CFSTR (kIOMACAddress),
kCFAllocatorDefault,
0);
if (data != 0)
{
UInt8 addr [kIOEthernetAddressSize];
zeromem (addr, sizeof (addr));
CFDataGetBytes ((CFDataRef)data, CFRangeMake (0, sizeof (addr)), addr);
CFRelease (data);
int64 a = 0;
for (int i = 6; --i >= 0;)
a = (a << 8) | addr[i];
if (numResults < maxNum)
{
*addresses++ = a;
++numResults;
}
}
IOObjectRelease (controller);
}
IOObjectRelease (i);
}
IOObjectRelease (it);
}
return numResults;
}
END_JUCE_NAMESPACE

+ 297
- 0
build/macosx/platform_specific_code/juce_mac_SystemStats.cpp View File

@@ -0,0 +1,297 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "../../../src/juce_core/basics/juce_StandardHeader.h"
#include <Carbon/Carbon.h>
#include <CoreAudio/HostTime.h>
#include <ctime>
#include <sys/resource.h>
BEGIN_JUCE_NAMESPACE
#include "../../../src/juce_appframework/application/juce_Application.h"
#include "../../../src/juce_core/basics/juce_SystemStats.h"
#include "../../../src/juce_core/basics/juce_Time.h"
#include "../../../src/juce_core/misc/juce_PlatformUtilities.h"
static int64 highResTimerFrequency;
#if JUCE_INTEL
static void juce_getCpuVendor (char* const v)
{
int vendor[4];
zerostruct (vendor);
int dummy = 0;
asm ("mov %%ebx, %%esi \n\t"
"cpuid \n\t"
"xchg %%esi, %%ebx"
: "=a" (dummy), "=S" (vendor[0]), "=c" (vendor[2]), "=d" (vendor[1]) : "a" (0));
memcpy (v, vendor, 16);
}
static unsigned int getCPUIDWord (unsigned int& familyModel, unsigned int& extFeatures)
{
unsigned int cpu = 0;
unsigned int ext = 0;
unsigned int family = 0;
unsigned int dummy = 0;
asm ("mov %%ebx, %%esi \n\t"
"cpuid \n\t"
"xchg %%esi, %%ebx"
: "=a" (family), "=S" (ext), "=c" (dummy), "=d" (cpu) : "a" (1));
familyModel = family;
extFeatures = ext;
return cpu;
}
struct CPUFlags
{
bool hasMMX : 1;
bool hasSSE : 1;
bool hasSSE2 : 1;
bool has3DNow : 1;
bool hasHT : 1;
};
static CPUFlags cpuFlags;
#endif
//==============================================================================
void Logger::outputDebugString (const String& text)
{
String withLineFeed (text + T("\n"));
const char* const utf8 = withLineFeed.toUTF8();
fwrite (utf8, strlen (utf8), 1, stdout);
}
void Logger::outputDebugPrintf (const tchar* format, ...)
{
String text;
va_list args;
va_start (args, format);
text.vprintf(format, args);
outputDebugString (text);
}
int SystemStats::getMemorySizeInMegabytes()
{
long bytes;
if (Gestalt (gestaltPhysicalRAMSize, &bytes) == noErr)
return (int) (((unsigned long) bytes) / (1024 * 1024));
return 0;
}
//==============================================================================
SystemStats::OperatingSystemType SystemStats::getOperatingSystemType()
{
return MacOSX;
}
const String SystemStats::getOperatingSystemName()
{
return T("Mac OS X");
}
//==============================================================================
void SystemStats::initialiseStats()
{
static bool initialised = false;
if (! initialised)
{
initialised = true;
#if JUCE_INTEL
{
unsigned int familyModel, extFeatures;
const unsigned int features = getCPUIDWord (familyModel, extFeatures);
cpuFlags.hasMMX = ((features & (1 << 23)) != 0);
cpuFlags.hasSSE = ((features & (1 << 25)) != 0);
cpuFlags.hasSSE2 = ((features & (1 << 26)) != 0);
cpuFlags.has3DNow = ((extFeatures & (1 << 31)) != 0);
cpuFlags.hasHT = ((features & (1 << 28)) != 0);
}
#endif
highResTimerFrequency = (int64) AudioGetHostClockFrequency();
if (JUCEApplication::getInstance() != 0)
RegisterAppearanceClient();
TXNInitTextension (0, 0, kTXNWantMoviesMask | kTXNWantGraphicsMask);
String s (SystemStats::getJUCEVersion());
rlimit lim;
getrlimit (RLIMIT_NOFILE, &lim);
lim.rlim_cur = lim.rlim_max = RLIM_INFINITY;
setrlimit (RLIMIT_NOFILE, &lim);
}
}
bool SystemStats::hasMMX()
{
#if JUCE_INTEL
return cpuFlags.hasMMX;
#else
return false;
#endif
}
bool SystemStats::hasSSE()
{
#if JUCE_INTEL
return cpuFlags.hasSSE;
#else
return false;
#endif
}
bool SystemStats::hasSSE2()
{
#if JUCE_INTEL
return cpuFlags.hasSSE2;
#else
return false;
#endif
}
bool SystemStats::has3DNow()
{
#if JUCE_INTEL
return cpuFlags.has3DNow;
#else
return false;
#endif
}
bool SystemStats::hasHyperThreading()
{
#if JUCE_INTEL
return cpuFlags.hasHT;
#else
return false;
#endif
}
const String SystemStats::getCpuVendor()
{
#if JUCE_INTEL
char v [16];
juce_getCpuVendor (v);
return String (v, 16);
#else
return String::empty;
#endif
}
int SystemStats::getCpuSpeedInMegaherz()
{
return GetCPUSpeed();
}
int SystemStats::getNumPhysicalCpus()
{
return MPProcessors();
}
int SystemStats::getNumLogicalCpus()
{
return getNumPhysicalCpus();
}
uint32 SystemStats::getPhysicalAffinityMask()
{
jassertfalse
return 0;
}
//==============================================================================
static int64 juce_getMicroseconds() throw()
{
UnsignedWide t;
Microseconds (&t);
return (((int64) t.hi) << 32) | t.lo;
}
uint32 juce_millisecondsSinceStartup() throw()
{
return (uint32) (juce_getMicroseconds() / 1000);
}
double Time::getMillisecondCounterHiRes() throw()
{
// xxx might be more accurate to use a scaled AudioGetCurrentHostTime?
return juce_getMicroseconds() * 0.001;
}
int64 Time::getHighResolutionTicks() throw()
{
return (int64) AudioGetCurrentHostTime();
}
int64 Time::getHighResolutionTicksPerSecond() throw()
{
return highResTimerFrequency;
}
int64 SystemStats::getClockCycleCounter()
{
jassertfalse
return 0;
}
bool Time::setSystemTimeToThisTime() const
{
jassertfalse
return false;
}
//==============================================================================
int SystemStats::getPageSize()
{
jassertfalse
return 512; //xxx
}
void PlatformUtilities::fpuReset()
{
}
END_JUCE_NAMESPACE

+ 364
- 0
build/macosx/platform_specific_code/juce_mac_Threads.cpp View File

@@ -0,0 +1,364 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "../../../src/juce_core/basics/juce_StandardHeader.h"
#include <pthread.h>
#include <sched.h>
#include <sys/file.h>
#include <Carbon/Carbon.h>
BEGIN_JUCE_NAMESPACE
#include "../../../src/juce_core/threads/juce_CriticalSection.h"
#include "../../../src/juce_core/threads/juce_WaitableEvent.h"
#include "../../../src/juce_core/threads/juce_Thread.h"
#include "../../../src/juce_core/threads/juce_Process.h"
#include "../../../src/juce_core/threads/juce_InterProcessLock.h"
#include "../../../src/juce_core/misc/juce_PlatformUtilities.h"
#include "../../../src/juce_core/io/files/juce_File.h"
//==============================================================================
CriticalSection::CriticalSection() throw()
{
pthread_mutexattr_t atts;
pthread_mutexattr_init (&atts);
pthread_mutexattr_settype (&atts, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init (&internal, &atts);
}
CriticalSection::~CriticalSection() throw()
{
pthread_mutex_destroy (&internal);
}
void CriticalSection::enter() const throw()
{
pthread_mutex_lock (&internal);
}
bool CriticalSection::tryEnter() const throw()
{
return pthread_mutex_trylock (&internal) == 0;
}
void CriticalSection::exit() const throw()
{
pthread_mutex_unlock (&internal);
}
//==============================================================================
struct EventStruct
{
pthread_cond_t condition;
pthread_mutex_t mutex;
bool triggered;
};
WaitableEvent::WaitableEvent() throw()
{
EventStruct* const es = new EventStruct();
es->triggered = false;
pthread_cond_init (&es->condition, 0);
pthread_mutex_init (&es->mutex, 0);
internal = es;
}
WaitableEvent::~WaitableEvent() throw()
{
EventStruct* const es = (EventStruct*) internal;
pthread_cond_destroy (&es->condition);
pthread_mutex_destroy (&es->mutex);
delete es;
}
bool WaitableEvent::wait (const int timeOutMillisecs) const throw()
{
EventStruct* const es = (EventStruct*) internal;
bool ok = true;
pthread_mutex_lock (&es->mutex);
if (!es->triggered)
{
if (timeOutMillisecs < 0)
{
pthread_cond_wait (&es->condition, &es->mutex);
}
else
{
struct timespec time;
time.tv_sec = timeOutMillisecs / 1000;
time.tv_nsec = (timeOutMillisecs % 1000) * 1000000;
pthread_cond_timedwait_relative_np (&es->condition, &es->mutex, &time);
}
ok = es->triggered;
}
es->triggered = false;
pthread_mutex_unlock (&es->mutex);
return ok;
}
void WaitableEvent::signal() const throw()
{
EventStruct* const es = (EventStruct*) internal;
pthread_mutex_lock (&es->mutex);
es->triggered = true;
pthread_cond_signal (&es->condition);
pthread_mutex_unlock (&es->mutex);
}
void WaitableEvent::reset() const throw()
{
EventStruct* const es = (EventStruct*) internal;
pthread_mutex_lock (&es->mutex);
es->triggered = false;
pthread_mutex_unlock (&es->mutex);
}
//==============================================================================
void JUCE_API juce_threadEntryPoint (void*);
void* threadEntryProc (void* userData)
{
juce_threadEntryPoint (userData);
return 0;
}
void* juce_createThread (void* userData)
{
pthread_t handle = 0;
if (pthread_create (&handle, 0, threadEntryProc, userData) == 0)
{
pthread_detach (handle);
return (void*) handle;
}
return 0;
}
void juce_killThread (void* handle)
{
if (handle != 0)
pthread_cancel ((pthread_t) handle);
}
void juce_setCurrentThreadName (const String& /*name*/)
{
}
int Thread::getCurrentThreadId()
{
return (int) pthread_self();
}
void juce_setThreadPriority (void* handle, int priority)
{
if (handle == 0)
handle = (void*) pthread_self();
struct sched_param param;
int policy;
pthread_getschedparam ((pthread_t) handle, &policy, &param);
param.sched_priority = jlimit (1, 127, 1 + (priority * 126) / 11);
pthread_setschedparam ((pthread_t) handle, policy, &param);
}
void Thread::yield()
{
sched_yield();
}
void Thread::setCurrentThreadAffinityMask (const uint32 affinityMask)
{
// xxx
jassertfalse
}
void Thread::sleep (int millisecs)
{
struct timespec time;
time.tv_sec = millisecs / 1000;
time.tv_nsec = (millisecs % 1000) * 1000000;
nanosleep (&time, 0);
}
//==============================================================================
void Process::raisePrivilege()
{
jassertfalse
}
void Process::lowerPrivilege()
{
jassertfalse
}
void Process::terminate()
{
ExitToShell();
}
void Process::setPriority (ProcessPriority p)
{
// xxx
}
void* Process::loadDynamicLibrary (const String& name)
{
// xxx needs to use bundles
FSSpec fs;
if (PlatformUtilities::makeFSSpecFromPath (&fs, name))
{
CFragConnectionID connID;
Ptr mainPtr;
Str255 errorMessage;
Str63 nm;
PlatformUtilities::copyToStr63 (nm, name);
const OSErr err = GetDiskFragment (&fs, 0, kCFragGoesToEOF, nm, kReferenceCFrag, &connID, &mainPtr, errorMessage);
if (err == noErr)
return (void*)connID;
}
return 0;
}
void Process::freeDynamicLibrary (void* handle)
{
if (handle != 0)
CloseConnection ((CFragConnectionID*)&handle);
}
void* Process::getProcedureEntryPoint (void* h, const String& procedureName)
{
if (h != 0)
{
CFragSymbolClass cl;
Ptr ptr;
Str255 name;
PlatformUtilities::copyToStr255 (name, procedureName);
if (FindSymbol ((CFragConnectionID) h, name, &ptr, &cl) == noErr)
{
return ptr;
}
}
return 0;
}
//==============================================================================
InterProcessLock::InterProcessLock (const String& name_)
: internal (0),
name (name_),
reentrancyLevel (0)
{
const File tempDir (File::getSpecialLocation (File::tempDirectory));
const File temp (tempDir.getChildFile (name));
temp.create();
internal = (void*) open (temp.getFullPathName().toUTF8(), O_NONBLOCK | O_RDONLY);
}
InterProcessLock::~InterProcessLock()
{
while (reentrancyLevel > 0)
this->exit();
close ((int) internal);
}
bool InterProcessLock::enter (int timeOutMillisecs)
{
if (internal == 0)
return false;
if (reentrancyLevel != 0)
return true;
if (timeOutMillisecs <= 0)
{
if (flock ((int) internal,
timeOutMillisecs < 0 ? LOCK_EX
: (LOCK_EX | LOCK_NB)) == 0)
{
++reentrancyLevel;
return true;
}
}
else
{
const int64 endTime = Time::currentTimeMillis() + timeOutMillisecs;
for (;;)
{
if (flock ((int) internal, LOCK_EX | LOCK_NB) == 0)
{
++reentrancyLevel;
return true;
}
if (Time::currentTimeMillis() >= endTime)
break;
Thread::sleep (10);
}
}
return false;
}
void InterProcessLock::exit()
{
if (reentrancyLevel > 0 && internal != 0)
{
--reentrancyLevel;
const int result = flock ((int) internal, LOCK_UN);
(void) result;
jassert (result == 0);
}
}
END_JUCE_NAMESPACE

+ 3061
- 0
build/macosx/platform_specific_code/juce_mac_Windowing.cpp
File diff suppressed because it is too large
View File


+ 979
- 0
build/win32/devcpp/Makefile.win
File diff suppressed because it is too large
View File


+ 6759
- 0
build/win32/devcpp/juce.dev
File diff suppressed because it is too large
View File


+ 1947
- 0
build/win32/platform_specific_code/juce_win32_ASIO.cpp
File diff suppressed because it is too large
View File


+ 2114
- 0
build/win32/platform_specific_code/juce_win32_AudioCDReader.cpp
File diff suppressed because it is too large
View File


+ 1754
- 0
build/win32/platform_specific_code/juce_win32_DirectSound.cpp
File diff suppressed because it is too large
View File


+ 57
- 0
build/win32/platform_specific_code/juce_win32_DynamicLibraryLoader.cpp View File

@@ -0,0 +1,57 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "win32_headers.h"
#include "../../../src/juce_core/basics/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "../../../src/juce_core/text/juce_String.h"
#include "juce_win32_DynamicLibraryLoader.h"
//==============================================================================
DynamicLibraryLoader::DynamicLibraryLoader (const String& name)
{
libHandle = LoadLibrary (name);
}
DynamicLibraryLoader::~DynamicLibraryLoader()
{
FreeLibrary ((HMODULE) libHandle);
}
void* DynamicLibraryLoader::findProcAddress (const String& functionName)
{
return (void*) GetProcAddress ((HMODULE) libHandle, functionName);
}
END_JUCE_NAMESPACE

+ 68
- 0
build/win32/platform_specific_code/juce_win32_DynamicLibraryLoader.h View File

@@ -0,0 +1,68 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#ifndef __JUCE_WIN32_DYNAMICLIBRARYLOADER_JUCEHEADER__
#define __JUCE_WIN32_DYNAMICLIBRARYLOADER_JUCEHEADER__
#ifndef DOXYGEN
//==============================================================================
// use with DynamicLibraryLoader to simplify importing functions
//
// functionName: function to import
// localFunctionName: name you want to use to actually call it (must be different)
// returnType: the return type
// object: the DynamicLibraryLoader to use
// params: list of params (bracketed)
//
#define DynamicLibraryImport(functionName, localFunctionName, returnType, object, params) \
typedef returnType (WINAPI *type##localFunctionName) params; \
type##localFunctionName localFunctionName \
= (type##localFunctionName)object.findProcAddress (#functionName);
//==============================================================================
// loads and unloads a DLL automatically
class JUCE_API DynamicLibraryLoader
{
public:
DynamicLibraryLoader (const String& name);
~DynamicLibraryLoader();
void* findProcAddress (const String& functionName);
private:
void* libHandle;
};
#endif
#endif // __JUCE_WIN32_DYNAMICLIBRARYLOADER_JUCEHEADER__

+ 492
- 0
build/win32/platform_specific_code/juce_win32_FileChooser.cpp View File

@@ -0,0 +1,492 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#ifdef _MSC_VER
#pragma warning (disable: 4514)
#pragma warning (push)
#endif
#include "win32_headers.h"
#include <shlobj.h>
#include "../../../src/juce_core/basics/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "../../../src/juce_appframework/gui/components/filebrowser/juce_FileChooser.h"
#include "../../../src/juce_appframework/gui/components/juce_Desktop.h"
#include "../../../src/juce_core/basics/juce_SystemStats.h"
#ifdef _MSC_VER
#pragma warning (pop)
#endif
//==============================================================================
UNICODE_FUNCTION (SHBrowseForFolderW, LPITEMIDLIST, (LPBROWSEINFOW))
UNICODE_FUNCTION (SHGetPathFromIDListW, BOOL, (LPCITEMIDLIST, LPWSTR))
UNICODE_FUNCTION (GetSaveFileNameW, BOOL, (LPOPENFILENAMEW))
UNICODE_FUNCTION (GetOpenFileNameW, BOOL, (LPOPENFILENAMEW))
static void juce_initialiseUnicodeFileBrowserFunctions()
{
static bool initialised = false;
if (! initialised)
{
initialised = true;
HMODULE h = LoadLibraryA ("shell32.dll");
UNICODE_FUNCTION_LOAD (SHBrowseForFolderW)
UNICODE_FUNCTION_LOAD (SHGetPathFromIDListW)
h = LoadLibraryA ("comdlg32.dll");
UNICODE_FUNCTION_LOAD (GetSaveFileNameW)
UNICODE_FUNCTION_LOAD (GetOpenFileNameW)
}
}
//==============================================================================
static const void* defaultDirPath = 0;
static String returnedString; // need this to get non-existent pathnames from the directory chooser
static Component* currentExtraFileWin = 0;
static bool areThereAnyAlwaysOnTopWindows()
{
for (int i = Desktop::getInstance().getNumComponents(); --i >= 0;)
{
Component* c = Desktop::getInstance().getComponent (i);
if (c != 0 && c->isAlwaysOnTop() && c->isShowing())
return true;
}
return false;
}
static int CALLBACK browseCallbackProc (HWND hWnd, UINT msg, LPARAM lParam, LPARAM /*lpData*/)
{
if (msg == BFFM_INITIALIZED)
{
SendMessage (hWnd, (wSHBrowseForFolderW != 0) ? BFFM_SETSELECTIONW
: BFFM_SETSELECTIONA,
TRUE, (LPARAM) defaultDirPath);
}
else if (msg == BFFM_VALIDATEFAILEDW)
{
returnedString = (LPCWSTR) lParam;
}
else if (msg == BFFM_VALIDATEFAILEDA)
{
returnedString = (const char*) lParam;
}
return 0;
}
void juce_setWindowStyleBit (HWND h, int styleType, int feature, bool bitIsSet);
static UINT_PTR CALLBACK openCallback (HWND hdlg, UINT uiMsg, WPARAM /*wParam*/, LPARAM lParam)
{
if (currentExtraFileWin != 0)
{
if (uiMsg == WM_INITDIALOG)
{
HWND dialogH = GetParent (hdlg);
jassert (dialogH != 0);
if (dialogH == 0)
dialogH = hdlg;
RECT r, cr;
GetWindowRect (dialogH, &r);
GetClientRect (dialogH, &cr);
SetWindowPos (dialogH, 0,
r.left, r.top,
currentExtraFileWin->getWidth() + jmax (150, r.right - r.left),
jmax (150, r.bottom - r.top),
SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER);
currentExtraFileWin->setBounds (cr.right, cr.top, currentExtraFileWin->getWidth(), cr.bottom - cr.top);
currentExtraFileWin->getChildComponent(0)->setBounds (0, 0, currentExtraFileWin->getWidth(), currentExtraFileWin->getHeight());
SetParent ((HWND) currentExtraFileWin->getWindowHandle(), (HWND) dialogH);
juce_setWindowStyleBit ((HWND)currentExtraFileWin->getWindowHandle(), GWL_STYLE, WS_CHILD, (dialogH != 0));
juce_setWindowStyleBit ((HWND)currentExtraFileWin->getWindowHandle(), GWL_STYLE, WS_POPUP, (dialogH == 0));
}
else if (uiMsg == WM_NOTIFY)
{
LPOFNOTIFY ofn = (LPOFNOTIFY) lParam;
if (ofn->hdr.code == CDN_SELCHANGE)
{
FilePreviewComponent* comp = (FilePreviewComponent*) currentExtraFileWin->getChildComponent(0);
if (comp != 0)
{
TCHAR path [MAX_PATH * 2];
path[0] = 0;
CommDlg_OpenSave_GetFilePath (GetParent (hdlg), (LPARAM) &path, MAX_PATH);
String fn;
if (wGetOpenFileNameW != 0)
fn = (const WCHAR*) path;
else
fn = path;
comp->selectedFileChanged (File (fn));
}
}
}
}
return 0;
}
class FPComponentHolder : public Component
{
public:
FPComponentHolder()
{
setVisible (true);
setOpaque (true);
}
~FPComponentHolder()
{
}
void paint (Graphics& g)
{
g.fillAll (Colours::lightgrey);
}
private:
FPComponentHolder (const FPComponentHolder&);
const FPComponentHolder& operator= (const FPComponentHolder&);
};
//==============================================================================
void FileChooser::showPlatformDialog (OwnedArray<File>& results,
const String& title,
const File& currentFileOrDirectory,
const String& filter,
bool selectsDirectory,
bool isSaveDialogue,
bool warnAboutOverwritingExistingFiles,
bool selectMultipleFiles,
FilePreviewComponent* extraInfoComponent)
{
juce_initialiseUnicodeFileBrowserFunctions();
const int numCharsAvailable = 32768;
MemoryBlock filenameSpace ((numCharsAvailable + 1) * sizeof (WCHAR), true);
WCHAR* const fname = (WCHAR*) filenameSpace.getData();
int fnameIdx = 0;
JUCE_TRY
{
// use a modal window as the parent for this dialog box
// to block input from other app windows
const Rectangle mainMon (Desktop::getInstance().getMainMonitorArea());
Component w (String::empty);
w.setBounds (mainMon.getX() + mainMon.getWidth() / 4,
mainMon.getY() + mainMon.getHeight() / 4,
0, 0);
w.setOpaque (true);
w.setAlwaysOnTop (areThereAnyAlwaysOnTopWindows());
w.addToDesktop (0);
if (extraInfoComponent == 0)
w.enterModalState();
String initialDir;
if (currentFileOrDirectory.isDirectory())
{
initialDir = currentFileOrDirectory.getFullPathName();
}
else
{
if (wSHBrowseForFolderW != 0)
currentFileOrDirectory.getFileName().copyToBuffer (fname, numCharsAvailable);
else
currentFileOrDirectory.getFileName().copyToBuffer ((char*) fname, numCharsAvailable);
initialDir = currentFileOrDirectory.getParentDirectory().getFullPathName();
}
if (currentExtraFileWin->isValidComponent())
{
jassertfalse
return;
}
if (selectsDirectory)
{
LPITEMIDLIST list = 0;
filenameSpace.fillWith (0);
if (wSHBrowseForFolderW != 0)
{
BROWSEINFOW bi;
zerostruct (bi);
bi.hwndOwner = (HWND) w.getWindowHandle();
bi.pszDisplayName = fname;
bi.lpszTitle = title;
bi.lpfn = browseCallbackProc;
#ifdef BIF_USENEWUI
bi.ulFlags = BIF_USENEWUI | BIF_VALIDATE;
#else
bi.ulFlags = 0x50;
#endif
defaultDirPath = (const WCHAR*) initialDir;
list = wSHBrowseForFolderW (&bi);
if (! wSHGetPathFromIDListW (list, fname))
{
fname[0] = 0;
returnedString = String::empty;
}
}
else
{
BROWSEINFO bi;
zerostruct (bi);
bi.hwndOwner = (HWND) w.getWindowHandle();
bi.pszDisplayName = (TCHAR*) fname;
bi.lpszTitle = title;
bi.lpfn = browseCallbackProc;
#ifdef BIF_USENEWUI
bi.ulFlags = BIF_USENEWUI | BIF_VALIDATE;
#else
bi.ulFlags = 0x50;
#endif
defaultDirPath = (const char*) initialDir;
list = SHBrowseForFolder (&bi);
if (! SHGetPathFromIDList (list, (char*) fname))
{
fname[0] = 0;
returnedString = String::empty;
}
}
LPMALLOC al;
if (list != 0 && SUCCEEDED (SHGetMalloc (&al)))
al->Free (list);
defaultDirPath = 0;
if (returnedString.isNotEmpty())
{
String stringFName;
if (wSHBrowseForFolderW != 0)
stringFName = fname;
else
stringFName = (char*) fname;
results.add (new File (File (stringFName).getSiblingFile (returnedString)));
returnedString = String::empty;
return;
}
}
else
{
DWORD flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_NOCHANGEDIR | OFN_HIDEREADONLY;
if (warnAboutOverwritingExistingFiles)
flags |= OFN_OVERWRITEPROMPT;
if (selectMultipleFiles)
flags |= OFN_ALLOWMULTISELECT;
if (extraInfoComponent != 0)
{
flags |= OFN_ENABLEHOOK;
currentExtraFileWin = new FPComponentHolder();
currentExtraFileWin->addAndMakeVisible (extraInfoComponent);
currentExtraFileWin->setSize (jlimit (20, 800, extraInfoComponent->getWidth()),
extraInfoComponent->getHeight());
currentExtraFileWin->addToDesktop (0);
currentExtraFileWin->enterModalState();
}
if (wGetSaveFileNameW != 0)
{
WCHAR filters [1024];
zeromem (filters, sizeof (filters));
filter.copyToBuffer (filters, 1024);
filter.copyToBuffer (filters + filter.length() + 1,
1022 - filter.length());
OPENFILENAMEW of;
zerostruct (of);
#ifdef OPENFILENAME_SIZE_VERSION_400W
of.lStructSize = OPENFILENAME_SIZE_VERSION_400W;
#else
of.lStructSize = sizeof (of);
#endif
of.hwndOwner = (HWND) w.getWindowHandle();
of.lpstrFilter = filters;
of.nFilterIndex = 1;
of.lpstrFile = fname;
of.nMaxFile = numCharsAvailable;
of.lpstrInitialDir = initialDir;
of.lpstrTitle = title;
of.Flags = flags;
if (extraInfoComponent != 0)
of.lpfnHook = &openCallback;
if (isSaveDialogue)
{
if (! wGetSaveFileNameW (&of))
fname[0] = 0;
else
fnameIdx = of.nFileOffset;
}
else
{
if (! wGetOpenFileNameW (&of))
fname[0] = 0;
else
fnameIdx = of.nFileOffset;
}
}
else
{
TCHAR filters [1024];
zeromem (filters, sizeof (filters));
filter.copyToBuffer (filters, 1024);
filter.copyToBuffer (filters + filter.length() + 1,
1022 - filter.length());
OPENFILENAME of;
zerostruct (of);
#ifdef OPENFILENAME_SIZE_VERSION_400
of.lStructSize = OPENFILENAME_SIZE_VERSION_400;
#else
of.lStructSize = sizeof (of);
#endif
of.hwndOwner = (HWND) w.getWindowHandle();
of.lpstrFilter = filters;
of.nFilterIndex = 1;
of.lpstrFile = (TCHAR*) fname;
of.nMaxFile = numCharsAvailable;
of.lpstrInitialDir = initialDir;
of.lpstrTitle = title;
of.Flags = flags;
if (extraInfoComponent != 0)
of.lpfnHook = &openCallback;
if (isSaveDialogue)
{
if (! GetSaveFileName (&of))
fname[0] = 0;
else
fnameIdx = of.nFileOffset;
}
else
{
if (! GetOpenFileName (&of))
fname[0] = 0;
else
fnameIdx = of.nFileOffset;
}
}
}
}
#if JUCE_CATCH_UNHANDLED_EXCEPTIONS
catch (...)
{
fname[0] = 0;
}
#endif
deleteAndZero (currentExtraFileWin);
if (wGetSaveFileNameW != 0)
{
const WCHAR* const files = fname;
if (selectMultipleFiles && fnameIdx > 0 && files [fnameIdx - 1] == 0)
{
const WCHAR* filename = files + fnameIdx;
while (*filename != 0)
{
const String filepath (String (files) + T("\\") + String (filename));
results.add (new File (filepath));
filename += CharacterFunctions::length (filename) + 1;
}
}
else if (files[0] != 0)
{
results.add (new File (files));
}
}
else
{
const char* const files = (const char*) fname;
if (selectMultipleFiles && fnameIdx > 0 && files [fnameIdx - 1] == 0)
{
const char* filename = files + fnameIdx;
while (*filename != 0)
{
const String filepath (String (files) + T("\\") + String (filename));
results.add (new File (filepath));
filename += CharacterFunctions::length (filename) + 1;
}
}
else if (files[0] != 0)
{
results.add (new File (files));
}
}
}
END_JUCE_NAMESPACE

+ 960
- 0
build/win32/platform_specific_code/juce_win32_Files.cpp View File

@@ -0,0 +1,960 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#ifdef _MSC_VER
#pragma warning (disable: 4514)
#pragma warning (push)
#endif
#include "win32_headers.h"
#include "../../../src/juce_core/basics/juce_StandardHeader.h"
#include <ctime>
#ifndef _WIN32_IE
#define _WIN32_IE 0x0400
#endif
#include <shlobj.h>
BEGIN_JUCE_NAMESPACE
#include "../../../src/juce_core/io/files/juce_File.h"
#include "../../../src/juce_core/io/network/juce_URL.h"
#include "../../../src/juce_core/basics/juce_SystemStats.h"
#include "../../../src/juce_core/io/files/juce_NamedPipe.h"
#include "../../../src/juce_core/misc/juce_PlatformUtilities.h"
#ifdef _MSC_VER
#pragma warning (pop)
#endif
//==============================================================================
const tchar File::separator = T('\\');
const tchar* File::separatorString = T("\\");
//==============================================================================
UNICODE_FUNCTION (GetFileAttributesW, DWORD, (LPCWSTR))
UNICODE_FUNCTION (SetFileAttributesW, BOOL, (LPCWSTR, DWORD))
UNICODE_FUNCTION (RemoveDirectoryW, BOOL, (LPCWSTR))
UNICODE_FUNCTION (DeleteFileW, BOOL, (LPCWSTR))
UNICODE_FUNCTION (MoveFileW, BOOL, (LPCWSTR, LPCWSTR))
UNICODE_FUNCTION (CopyFileW, BOOL, (LPCWSTR, LPCWSTR, BOOL))
UNICODE_FUNCTION (CreateDirectoryW, BOOL, (LPCWSTR, LPSECURITY_ATTRIBUTES))
UNICODE_FUNCTION (CreateFileW, HANDLE, (LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE))
UNICODE_FUNCTION (CreateNamedPipeW, HANDLE, (LPCWSTR, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, LPSECURITY_ATTRIBUTES))
UNICODE_FUNCTION (GetTempPathW, DWORD, (DWORD, LPCWSTR))
UNICODE_FUNCTION (SHGetSpecialFolderPathW, BOOL, (HWND, LPCWSTR, int, BOOL))
UNICODE_FUNCTION (GetModuleFileNameW, DWORD, (HMODULE, LPCWSTR, DWORD))
UNICODE_FUNCTION (GetCurrentDirectoryW, DWORD, (DWORD, LPCWSTR))
UNICODE_FUNCTION (SetCurrentDirectoryW, BOOL, (LPCWSTR))
UNICODE_FUNCTION (FindFirstFileW, HANDLE, (LPCWSTR, LPWIN32_FIND_DATAW))
UNICODE_FUNCTION (FindNextFileW, BOOL, (HANDLE, LPWIN32_FIND_DATAW))
void juce_initialiseUnicodeFileFunctions()
{
if ((SystemStats::getOperatingSystemType() & SystemStats::WindowsNT) != 0)
{
HMODULE h = GetModuleHandleA ("kernel32.dll");
UNICODE_FUNCTION_LOAD (GetFileAttributesW)
UNICODE_FUNCTION_LOAD (SetFileAttributesW)
UNICODE_FUNCTION_LOAD (RemoveDirectoryW)
UNICODE_FUNCTION_LOAD (DeleteFileW)
UNICODE_FUNCTION_LOAD (MoveFileW)
UNICODE_FUNCTION_LOAD (CopyFileW)
UNICODE_FUNCTION_LOAD (CreateDirectoryW)
UNICODE_FUNCTION_LOAD (CreateFileW)
UNICODE_FUNCTION_LOAD (CreateNamedPipeW)
UNICODE_FUNCTION_LOAD (GetTempPathW)
UNICODE_FUNCTION_LOAD (GetModuleFileNameW)
UNICODE_FUNCTION_LOAD (GetCurrentDirectoryW)
UNICODE_FUNCTION_LOAD (SetCurrentDirectoryW)
UNICODE_FUNCTION_LOAD (FindFirstFileW)
UNICODE_FUNCTION_LOAD (FindNextFileW)
h = LoadLibraryA ("shell32.dll");
UNICODE_FUNCTION_LOAD (SHGetSpecialFolderPathW)
}
}
//==============================================================================
bool juce_fileExists (const String& fileName,
const bool dontCountDirectories)
{
if (fileName.isEmpty())
return false;
const DWORD attr = (wGetFileAttributesW != 0) ? wGetFileAttributesW (fileName)
: GetFileAttributes (fileName);
return (dontCountDirectories) ? ((attr & FILE_ATTRIBUTE_DIRECTORY) == 0)
: (attr != 0xffffffff);
}
bool juce_isDirectory (const String& fileName)
{
const DWORD attr = (wGetFileAttributesW != 0) ? wGetFileAttributesW (fileName)
: GetFileAttributes (fileName);
return (attr != 0xffffffff)
&& ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0);
}
bool juce_canWriteToFile (const String& fileName)
{
const DWORD attr = (wGetFileAttributesW != 0) ? wGetFileAttributesW (fileName)
: GetFileAttributes (fileName);
return ((attr & FILE_ATTRIBUTE_READONLY) == 0);
}
bool juce_setFileReadOnly (const String& fileName,
bool isReadOnly)
{
DWORD attr = (wGetFileAttributesW != 0) ? wGetFileAttributesW (fileName)
: GetFileAttributes (fileName);
if (attr == 0xffffffff)
return false;
if (isReadOnly != juce_canWriteToFile (fileName))
return true;
if (isReadOnly)
attr |= FILE_ATTRIBUTE_READONLY;
else
attr &= ~FILE_ATTRIBUTE_READONLY;
if (wSetFileAttributesW != 0)
return wSetFileAttributesW (fileName, attr) != FALSE;
return SetFileAttributes (fileName, attr) != FALSE;
}
//==============================================================================
bool juce_deleteFile (const String& fileName)
{
if (juce_isDirectory (fileName))
return (wRemoveDirectoryW != 0) ? wRemoveDirectoryW (fileName) != 0
: RemoveDirectory (fileName) != 0;
else
return (wDeleteFileW != 0) ? wDeleteFileW (fileName) != 0
: DeleteFile (fileName) != 0;
}
bool juce_moveFile (const String& source, const String& dest)
{
return (wMoveFileW != 0) ? wMoveFileW (source, dest) != 0
: MoveFile (source, dest) != 0;
}
bool juce_copyFile (const String& source, const String& dest)
{
return (wCopyFileW != 0) ? wCopyFileW (source, dest, false) != 0
: CopyFile (source, dest, false) != 0;
}
void juce_createDirectory (const String& fileName)
{
if (! juce_fileExists (fileName, true))
{
if (wCreateDirectoryW != 0)
wCreateDirectoryW (fileName, 0);
else
CreateDirectory (fileName, 0);
}
}
//==============================================================================
// return 0 if not possible
void* juce_fileOpen (const String& fileName, bool forWriting)
{
HANDLE h;
if (forWriting)
{
if (wCreateFileW != 0)
h = wCreateFileW (fileName, GENERIC_WRITE, FILE_SHARE_READ, 0,
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
else
h = CreateFile (fileName, GENERIC_WRITE, FILE_SHARE_READ, 0,
OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if (h != INVALID_HANDLE_VALUE)
SetFilePointer (h, 0, 0, FILE_END);
else
h = 0;
}
else
{
if (wCreateFileW != 0)
h = wCreateFileW (fileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, 0);
else
h = CreateFile (fileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, 0);
if (h == INVALID_HANDLE_VALUE)
h = 0;
}
return (void*) h;
}
void juce_fileClose (void* handle)
{
CloseHandle (handle);
}
//==============================================================================
int juce_fileRead (void* handle, void* buffer, int size)
{
DWORD num = 0;
ReadFile ((HANDLE) handle, buffer, size, &num, 0);
return num;
}
int juce_fileWrite (void* handle, const void* buffer, int size)
{
DWORD num;
WriteFile ((HANDLE) handle,
buffer, size,
&num, 0);
return num;
}
int64 juce_fileSetPosition (void* handle, int64 pos)
{
LARGE_INTEGER li;
li.QuadPart = pos;
li.LowPart = SetFilePointer ((HANDLE) handle,
li.LowPart,
&li.HighPart,
FILE_BEGIN); // (returns -1 if it fails)
return li.QuadPart;
}
int64 juce_fileGetPosition (void* handle)
{
LARGE_INTEGER li;
li.QuadPart = 0;
li.LowPart = SetFilePointer ((HANDLE) handle,
0, &li.HighPart,
FILE_CURRENT); // (returns -1 if it fails)
return jmax ((int64) 0, li.QuadPart);
}
void juce_fileFlush (void* handle)
{
FlushFileBuffers ((HANDLE) handle);
}
int64 juce_getFileSize (const String& fileName)
{
void* const handle = juce_fileOpen (fileName, false);
if (handle != 0)
{
LARGE_INTEGER li;
li.LowPart = GetFileSize (handle, (LPDWORD) &li.HighPart);
juce_fileClose (handle);
if (li.LowPart != INVALID_FILE_SIZE || GetLastError() != NO_ERROR)
return li.QuadPart;
}
return 0;
}
//==============================================================================
static int64 fileTimeToTime (const FILETIME* const ft) throw()
{
// tell me if this fails!
static_jassert (sizeof (ULARGE_INTEGER) == sizeof (FILETIME));
#ifdef JUCE_GCC
return (((const ULARGE_INTEGER*) ft)->QuadPart - 116444736000000000LL) / 10000;
#else
return (((const ULARGE_INTEGER*) ft)->QuadPart - 116444736000000000) / 10000;
#endif
}
static void timeToFileTime (const int64 time, FILETIME* const ft) throw()
{
#ifdef JUCE_GCC
((ULARGE_INTEGER*) ft)->QuadPart = time * 10000 + 116444736000000000LL;
#else
((ULARGE_INTEGER*) ft)->QuadPart = time * 10000 + 116444736000000000;
#endif
}
void juce_getFileTimes (const String& fileName,
int64& modificationTime,
int64& accessTime,
int64& creationTime)
{
creationTime = accessTime = modificationTime = 0;
void* const h = juce_fileOpen (fileName, false);
if (h != 0)
{
FILETIME m, a, c;
if (GetFileTime ((HANDLE) h, &c, &a, &m))
{
creationTime = fileTimeToTime (&c);
accessTime = fileTimeToTime (&a);
modificationTime = fileTimeToTime (&m);
}
juce_fileClose (h);
}
}
bool juce_setFileTimes (const String& fileName,
int64 modificationTime,
int64 accessTime,
int64 creationTime)
{
FILETIME m, a, c;
if (modificationTime > 0)
timeToFileTime (modificationTime, &m);
if (accessTime > 0)
timeToFileTime (accessTime, &a);
if (creationTime > 0)
timeToFileTime (creationTime, &c);
void* const h = juce_fileOpen (fileName, true);
bool ok = false;
if (h != 0)
{
ok = SetFileTime ((HANDLE) h,
(creationTime > 0) ? &c : 0,
(accessTime > 0) ? &a : 0,
(modificationTime > 0) ? &m : 0) != 0;
juce_fileClose (h);
}
return ok;
}
//==============================================================================
// return '\0' separated list of strings
const StringArray juce_getFileSystemRoots()
{
TCHAR buffer [2048];
buffer[0] = 0;
buffer[1] = 0;
GetLogicalDriveStrings (2048, buffer);
TCHAR* n = buffer;
StringArray roots;
while (*n != 0)
{
roots.add (String (n));
while (*n++ != 0)
{
}
}
roots.sort (true);
return roots;
}
//==============================================================================
const String juce_getVolumeLabel (const String& filenameOnVolume,
int& volumeSerialNumber)
{
TCHAR n [4];
n[0] = *(const TCHAR*) filenameOnVolume;
n[1] = L':';
n[2] = L'\\';
n[3] = 0;
TCHAR dest [64];
DWORD serialNum;
if (! GetVolumeInformation (n, dest, 64, (DWORD*) &serialNum, 0, 0, 0, 0))
{
dest[0] = 0;
serialNum = 0;
}
volumeSerialNumber = serialNum;
return String (dest);
}
int64 File::getBytesFreeOnVolume() const throw()
{
String fn (getFullPathName());
if (fn[1] == T(':'))
fn = fn.substring (0, 2) + T("\\");
ULARGE_INTEGER spc;
ULARGE_INTEGER tot;
ULARGE_INTEGER totFree;
if (GetDiskFreeSpaceEx (fn, &spc, &tot, &totFree))
return (int64)(spc.QuadPart);
return 0;
}
//==============================================================================
static unsigned int getWindowsDriveType (const String& fileName)
{
TCHAR n[4];
n[0] = *(const TCHAR*) fileName;
n[1] = L':';
n[2] = L'\\';
n[3] = 0;
return GetDriveType (n);
}
bool File::isOnCDRomDrive() const throw()
{
return getWindowsDriveType (getFullPathName()) == DRIVE_CDROM;
}
bool File::isOnHardDisk() const throw()
{
if (fullPath.isEmpty())
return false;
const unsigned int n = getWindowsDriveType (getFullPathName());
if (fullPath.toLowerCase()[0] <= 'b'
&& fullPath[1] == T(':'))
{
return n != DRIVE_REMOVABLE;
}
else
{
return n != DRIVE_CDROM && n != DRIVE_REMOTE;
}
}
bool File::isOnRemovableDrive() const throw()
{
if (fullPath.isEmpty())
return false;
const unsigned int n = getWindowsDriveType (getFullPathName());
return n == DRIVE_CDROM
|| n == DRIVE_REMOTE
|| n == DRIVE_REMOVABLE
|| n == DRIVE_RAMDISK;
}
//==============================================================================
#define MAX_PATH_CHARS (MAX_PATH + 256)
static const File juce_getSpecialFolderPath (int type)
{
if (wSHGetSpecialFolderPathW != 0)
{
WCHAR path [MAX_PATH_CHARS];
if (wSHGetSpecialFolderPathW (0, path, type, 0))
return File (String (path));
}
else
{
TCHAR path [MAX_PATH_CHARS];
if (SHGetSpecialFolderPath (0, path, type, 0))
return File (String (path));
}
return File::nonexistent;
}
const File File::getSpecialLocation (const SpecialLocationType type)
{
switch (type)
{
case userHomeDirectory:
case userDocumentsDirectory:
return juce_getSpecialFolderPath (CSIDL_PERSONAL);
case userDesktopDirectory:
return juce_getSpecialFolderPath (CSIDL_DESKTOP);
case userApplicationDataDirectory:
return juce_getSpecialFolderPath (CSIDL_APPDATA);
case commonApplicationDataDirectory:
return juce_getSpecialFolderPath (CSIDL_COMMON_APPDATA);
case globalApplicationsDirectory:
return juce_getSpecialFolderPath (CSIDL_PROGRAM_FILES);
case tempDirectory:
if (wGetTempPathW != 0)
{
WCHAR dest [2048];
dest[0] = 0;
wGetTempPathW (2048, dest);
return File (String (dest));
}
else
{
TCHAR dest [2048];
dest[0] = 0;
GetTempPath (2048, dest);
return File (String (dest));
}
case currentExecutableFile:
case currentApplicationFile:
{
HINSTANCE moduleHandle = (HINSTANCE) PlatformUtilities::getCurrentModuleInstanceHandle();
if (wGetModuleFileNameW != 0)
{
WCHAR dest [MAX_PATH_CHARS];
dest[0] = 0;
wGetModuleFileNameW (moduleHandle, dest, MAX_PATH_CHARS);
return File (String (dest));
}
else
{
TCHAR dest [MAX_PATH_CHARS];
dest[0] = 0;
GetModuleFileName (moduleHandle, dest, MAX_PATH_CHARS);
return File (String (dest));
}
}
break;
default:
jassertfalse // unknown type?
break;
}
return File::nonexistent;
}
void juce_setCurrentExecutableFileName (const String&)
{
// n/a on windows
}
//==============================================================================
const File File::getCurrentWorkingDirectory() throw()
{
if (wGetCurrentDirectoryW != 0)
{
WCHAR dest [MAX_PATH_CHARS];
dest[0] = 0;
wGetCurrentDirectoryW (MAX_PATH_CHARS, dest);
return File (String (dest));
}
else
{
TCHAR dest [MAX_PATH_CHARS];
dest[0] = 0;
GetCurrentDirectory (MAX_PATH_CHARS, dest);
return File (String (dest));
}
}
bool File::setAsCurrentWorkingDirectory() const throw()
{
return (wSetCurrentDirectoryW != 0) ? wSetCurrentDirectoryW (getFullPathName()) != FALSE
: SetCurrentDirectory (getFullPathName()) != FALSE;
}
//==============================================================================
template <class FindDataType>
static void getFindFileInfo (FindDataType& findData,
String& filename, bool* const isDir, bool* const isHidden,
int64* const fileSize, Time* const modTime, Time* const creationTime,
bool* const isReadOnly)
{
filename = findData.cFileName;
if (isDir != 0)
*isDir = ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0);
if (isHidden != 0)
*isHidden = ((findData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) != 0);
if (fileSize != 0)
*fileSize = findData.nFileSizeLow + (((int64) findData.nFileSizeHigh) << 32);
if (modTime != 0)
*modTime = fileTimeToTime (&findData.ftLastWriteTime);
if (creationTime != 0)
*creationTime = fileTimeToTime (&findData.ftCreationTime);
if (isReadOnly != 0)
*isReadOnly = ((findData.dwFileAttributes & FILE_ATTRIBUTE_READONLY) != 0);
}
void* juce_findFileStart (const String& directory, const String& wildCard, String& firstResult,
bool* isDir, bool* isHidden, int64* fileSize,
Time* modTime, Time* creationTime, bool* isReadOnly)
{
String wc (directory);
if (! wc.endsWithChar (File::separator))
wc += File::separator;
wc += wildCard;
if (wFindFirstFileW != 0)
{
WIN32_FIND_DATAW findData;
HANDLE h = wFindFirstFileW (wc, &findData);
if (h != INVALID_HANDLE_VALUE)
{
getFindFileInfo (findData, firstResult, isDir, isHidden, fileSize, modTime, creationTime, isReadOnly);
return h;
}
}
else
{
WIN32_FIND_DATA findData;
HANDLE h = FindFirstFile (wc, &findData);
if (h != INVALID_HANDLE_VALUE)
{
getFindFileInfo (findData, firstResult, isDir, isHidden, fileSize, modTime, creationTime, isReadOnly);
return h;
}
}
firstResult = String::empty;
return 0;
}
bool juce_findFileNext (void* handle, String& resultFile,
bool* isDir, bool* isHidden, int64* fileSize,
Time* modTime, Time* creationTime, bool* isReadOnly)
{
if (wFindNextFileW != 0)
{
WIN32_FIND_DATAW findData;
if (handle != 0 && wFindNextFileW ((HANDLE) handle, &findData) != 0)
{
getFindFileInfo (findData, resultFile, isDir, isHidden, fileSize, modTime, creationTime, isReadOnly);
return true;
}
}
else
{
WIN32_FIND_DATA findData;
if (handle != 0 && FindNextFile ((HANDLE) handle, &findData) != 0)
{
getFindFileInfo (findData, resultFile, isDir, isHidden, fileSize, modTime, creationTime, isReadOnly);
return true;
}
}
resultFile = String::empty;
return false;
}
void juce_findFileClose (void* handle)
{
FindClose (handle);
}
//==============================================================================
bool juce_launchFile (const String& fileName,
const String& parameters)
{
HINSTANCE hInstance = 0;
JUCE_TRY
{
hInstance = ShellExecute (0, 0, fileName, parameters, 0, SW_SHOWDEFAULT);
}
JUCE_CATCH_ALL
return hInstance > (HINSTANCE) 32;
}
//==============================================================================
struct NamedPipeInternal
{
HANDLE pipeH;
HANDLE cancelEvent;
bool connected, createdPipe;
NamedPipeInternal()
: pipeH (0),
cancelEvent (0),
connected (false),
createdPipe (false)
{
cancelEvent = CreateEvent (0, FALSE, FALSE, 0);
}
~NamedPipeInternal()
{
disconnect();
if (pipeH != 0)
CloseHandle (pipeH);
CloseHandle (cancelEvent);
}
bool connect (const int timeOutMs)
{
if (! createdPipe)
return true;
if (! connected)
{
OVERLAPPED over;
zerostruct (over);
over.hEvent = CreateEvent (0, TRUE, FALSE, 0);
if (ConnectNamedPipe (pipeH, &over))
{
connected = false; // yes, you read that right. In overlapped mode it should always return 0.
}
else
{
const int err = GetLastError();
if (err == ERROR_IO_PENDING || err == ERROR_PIPE_LISTENING)
{
HANDLE handles[] = { over.hEvent, cancelEvent };
if (WaitForMultipleObjects (2, handles, FALSE,
timeOutMs >= 0 ? timeOutMs : INFINITE) == WAIT_OBJECT_0)
connected = true;
}
else if (err == ERROR_PIPE_CONNECTED)
{
connected = true;
}
}
CloseHandle (over.hEvent);
}
return connected;
}
void disconnect()
{
if (connected)
{
DisconnectNamedPipe (pipeH);
connected = false;
}
}
};
void NamedPipe::close()
{
NamedPipeInternal* const intern = (NamedPipeInternal*) internal;
delete intern;
internal = 0;
}
bool NamedPipe::openInternal (const String& pipeName, const bool createPipe)
{
close();
NamedPipeInternal* const intern = new NamedPipeInternal();
String file (T("\\\\.\\pipe\\"));
file += pipeName;
intern->createdPipe = createPipe;
if (createPipe)
{
if (wCreateNamedPipeW != 0)
intern->pipeH = wCreateNamedPipeW (file, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 0,
1, 64, 64, 0, NULL);
else
intern->pipeH = CreateNamedPipe (file, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 0,
1, 64, 64, 0, NULL);
}
else
{
if (wCreateFileW != 0)
intern->pipeH = wCreateFileW (file, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING,
FILE_FLAG_OVERLAPPED, 0);
else
intern->pipeH = CreateFile (file, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING,
FILE_FLAG_OVERLAPPED, 0);
}
if (intern->pipeH != INVALID_HANDLE_VALUE)
{
internal = intern;
return true;
}
delete intern;
return false;
}
int NamedPipe::read (void* destBuffer, int maxBytesToRead, int timeOutMilliseconds)
{
int bytesRead = -1;
bool waitAgain = true;
while (waitAgain && internal != 0)
{
NamedPipeInternal* const intern = (NamedPipeInternal*) internal;
waitAgain = false;
if (! intern->connect (timeOutMilliseconds))
break;
if (maxBytesToRead <= 0)
return 0;
OVERLAPPED over;
zerostruct (over);
over.hEvent = CreateEvent (0, TRUE, FALSE, 0);
unsigned long numRead;
if (ReadFile (intern->pipeH, destBuffer, maxBytesToRead, &numRead, &over))
{
bytesRead = (int) numRead;
}
else if (GetLastError() == ERROR_IO_PENDING)
{
HANDLE handles[] = { over.hEvent, intern->cancelEvent };
if (WaitForMultipleObjects (2, handles, FALSE,
timeOutMilliseconds >= 0 ? timeOutMilliseconds
: INFINITE) == WAIT_OBJECT_0)
{
if (GetOverlappedResult (intern->pipeH, &over, &numRead, FALSE))
{
bytesRead = (int) numRead;
}
else if (GetLastError() == ERROR_BROKEN_PIPE && intern->createdPipe)
{
intern->disconnect();
waitAgain = true;
}
}
}
else
{
waitAgain = internal != 0;
Sleep (5);
}
CloseHandle (over.hEvent);
}
return bytesRead;
}
int NamedPipe::write (const void* sourceBuffer, int numBytesToWrite, int timeOutMilliseconds)
{
int bytesWritten = -1;
NamedPipeInternal* const intern = (NamedPipeInternal*) internal;
if (intern != 0 && intern->connect (timeOutMilliseconds))
{
if (numBytesToWrite <= 0)
return 0;
OVERLAPPED over;
zerostruct (over);
over.hEvent = CreateEvent (0, TRUE, FALSE, 0);
unsigned long numWritten;
if (WriteFile (intern->pipeH, sourceBuffer, numBytesToWrite, &numWritten, &over))
{
bytesWritten = (int) numWritten;
}
else if (GetLastError() == ERROR_IO_PENDING)
{
HANDLE handles[] = { over.hEvent, intern->cancelEvent };
if (WaitForMultipleObjects (2, handles, FALSE, timeOutMilliseconds >= 0 ? timeOutMilliseconds
: INFINITE) == WAIT_OBJECT_0)
{
if (GetOverlappedResult (intern->pipeH, &over, &numWritten, FALSE))
{
bytesWritten = (int) numWritten;
}
else if (GetLastError() == ERROR_BROKEN_PIPE && intern->createdPipe)
{
intern->disconnect();
}
}
}
CloseHandle (over.hEvent);
}
return bytesWritten;
}
void NamedPipe::cancelPendingReads()
{
NamedPipeInternal* const intern = (NamedPipeInternal*) internal;
if (intern != 0)
SetEvent (intern->cancelEvent);
}
END_JUCE_NAMESPACE

+ 662
- 0
build/win32/platform_specific_code/juce_win32_Fonts.cpp View File

@@ -0,0 +1,662 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "win32_headers.h"
#include "../../../src/juce_core/basics/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "../../../src/juce_appframework/gui/graphics/fonts/juce_Font.h"
#include "../../../src/juce_appframework/application/juce_DeletedAtShutdown.h"
#include "../../../src/juce_core/basics/juce_SystemStats.h"
#include "../../../src/juce_appframework/gui/graphics/imaging/juce_Image.h"
//==============================================================================
UNICODE_FUNCTION (GetGlyphOutlineW, DWORD, (HDC, UINT, UINT, LPGLYPHMETRICS, DWORD, LPVOID, CONST MAT2*))
UNICODE_FUNCTION (GetTextMetricsW, BOOL, (HDC, LPTEXTMETRICW))
UNICODE_FUNCTION (GetKerningPairsW, DWORD, (HDC, DWORD, LPKERNINGPAIR))
UNICODE_FUNCTION (EnumFontFamiliesExW, int, (HDC, LPLOGFONTW, FONTENUMPROCW, LPARAM, DWORD))
UNICODE_FUNCTION (CreateFontIndirectW, HFONT, (CONST LOGFONTW *));
static void juce_initialiseUnicodeFileFontFunctions()
{
static bool initialised = false;
if (! initialised)
{
initialised = true;
if ((SystemStats::getOperatingSystemType() & SystemStats::WindowsNT) != 0)
{
HMODULE h = LoadLibraryA ("gdi32.dll");
UNICODE_FUNCTION_LOAD (GetGlyphOutlineW)
UNICODE_FUNCTION_LOAD (GetTextMetricsW)
UNICODE_FUNCTION_LOAD (GetKerningPairsW)
UNICODE_FUNCTION_LOAD (EnumFontFamiliesExW)
UNICODE_FUNCTION_LOAD (CreateFontIndirectW)
}
}
}
//==============================================================================
static int CALLBACK fontEnum2 (ENUMLOGFONTEX* lpelfe,
NEWTEXTMETRICEX*,
int type,
LPARAM lParam)
{
if (lpelfe != 0 && type == TRUETYPE_FONTTYPE)
{
const String fontName (lpelfe->elfLogFont.lfFaceName);
((StringArray*) lParam)->addIfNotAlreadyThere (fontName.removeCharacters (T("@")));
}
return 1;
}
static int CALLBACK wfontEnum2 (ENUMLOGFONTEXW* lpelfe,
NEWTEXTMETRICEXW*,
int type,
LPARAM lParam)
{
if (lpelfe != 0 && type == TRUETYPE_FONTTYPE)
{
const String fontName (lpelfe->elfLogFont.lfFaceName);
((StringArray*) lParam)->addIfNotAlreadyThere (fontName.removeCharacters (T("@")));
}
return 1;
}
static int CALLBACK fontEnum1 (ENUMLOGFONTEX* lpelfe,
NEWTEXTMETRICEX*,
int type,
LPARAM lParam)
{
if (lpelfe != 0
&& ((type & (DEVICE_FONTTYPE | RASTER_FONTTYPE)) == 0))
{
LOGFONT lf;
zerostruct (lf);
lf.lfWeight = FW_DONTCARE;
lf.lfOutPrecision = OUT_TT_ONLY_PRECIS;
lf.lfQuality = DEFAULT_QUALITY;
lf.lfCharSet = DEFAULT_CHARSET;
lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
lf.lfPitchAndFamily = FF_DONTCARE;
const String fontName (lpelfe->elfLogFont.lfFaceName);
fontName.copyToBuffer (lf.lfFaceName, LF_FACESIZE - 1);
HDC dc = CreateCompatibleDC (0);
EnumFontFamiliesEx (dc, &lf,
(FONTENUMPROC) &fontEnum2,
lParam, 0);
DeleteDC (dc);
}
return 1;
}
static int CALLBACK wfontEnum1 (ENUMLOGFONTEXW* lpelfe,
NEWTEXTMETRICEXW*,
int type,
LPARAM lParam)
{
if (lpelfe != 0
&& ((type & (DEVICE_FONTTYPE | RASTER_FONTTYPE)) == 0))
{
LOGFONTW lf;
zerostruct (lf);
lf.lfWeight = FW_DONTCARE;
lf.lfOutPrecision = OUT_TT_ONLY_PRECIS;
lf.lfQuality = DEFAULT_QUALITY;
lf.lfCharSet = DEFAULT_CHARSET;
lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
lf.lfPitchAndFamily = FF_DONTCARE;
const String fontName (lpelfe->elfLogFont.lfFaceName);
fontName.copyToBuffer (lf.lfFaceName, LF_FACESIZE - 1);
HDC dc = CreateCompatibleDC (0);
wEnumFontFamiliesExW (dc, &lf,
(FONTENUMPROCW) &wfontEnum2,
lParam, 0);
DeleteDC (dc);
}
return 1;
}
const StringArray Font::findAllTypefaceNames()
{
StringArray results;
HDC dc = CreateCompatibleDC (0);
if (wEnumFontFamiliesExW != 0)
{
LOGFONTW lf;
zerostruct (lf);
lf.lfWeight = FW_DONTCARE;
lf.lfOutPrecision = OUT_TT_ONLY_PRECIS;
lf.lfQuality = DEFAULT_QUALITY;
lf.lfCharSet = DEFAULT_CHARSET;
lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
lf.lfPitchAndFamily = FF_DONTCARE;
lf.lfFaceName[0] = 0;
wEnumFontFamiliesExW (dc, &lf,
(FONTENUMPROCW) &wfontEnum1,
(LPARAM) &results, 0);
}
else
{
LOGFONT lf;
zerostruct (lf);
lf.lfWeight = FW_DONTCARE;
lf.lfOutPrecision = OUT_TT_ONLY_PRECIS;
lf.lfQuality = DEFAULT_QUALITY;
lf.lfCharSet = DEFAULT_CHARSET;
lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
lf.lfPitchAndFamily = FF_DONTCARE;
lf.lfFaceName[0] = 0;
EnumFontFamiliesEx (dc, &lf,
(FONTENUMPROC) &fontEnum1,
(LPARAM) &results, 0);
}
DeleteDC (dc);
results.sort (true);
return results;
}
void Font::getDefaultFontNames (String& defaultSans,
String& defaultSerif,
String& defaultFixed)
{
defaultSans = T("Verdana");
defaultSerif = T("Times");
defaultFixed = T("Lucida Console");
}
//==============================================================================
class FontDCHolder : private DeletedAtShutdown
{
HDC dc;
String fontName;
KERNINGPAIR* kps;
int numKPs;
bool bold, italic;
int size;
FontDCHolder (const FontDCHolder&);
const FontDCHolder& operator= (const FontDCHolder&);
public:
HFONT fontH;
//==============================================================================
FontDCHolder() throw()
: dc (0),
kps (0),
numKPs (0),
bold (false),
italic (false),
size (0)
{
juce_initialiseUnicodeFileFontFunctions();
}
~FontDCHolder() throw()
{
if (dc != 0)
{
DeleteDC (dc);
DeleteObject (fontH);
if (kps)
juce_free (kps);
}
}
static FontDCHolder* getInstance() throw()
{
static FontDCHolder* instance = 0;
if (instance == 0)
instance = new FontDCHolder();
return instance;
}
//==============================================================================
HDC loadFont (const String& fontName_,
const bool bold_,
const bool italic_,
const int size_) throw()
{
if (fontName != fontName_ || bold != bold_ || italic != italic_ || size != size_)
{
fontName = fontName_;
bold = bold_;
italic = italic_;
size = size_;
if (dc != 0)
{
DeleteDC (dc);
DeleteObject (fontH);
if (kps != 0)
{
juce_free (kps);
kps = 0;
}
}
fontH = 0;
dc = CreateCompatibleDC (0);
SetMapperFlags (dc, 0);
SetMapMode (dc, MM_TEXT);
LOGFONT lf;
LOGFONTW lfw;
HFONT standardSizedFont = 0;
if (wCreateFontIndirectW != 0)
{
zerostruct (lfw);
lfw.lfCharSet = DEFAULT_CHARSET;
lfw.lfClipPrecision = CLIP_DEFAULT_PRECIS;
lfw.lfOutPrecision = OUT_OUTLINE_PRECIS;
lfw.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
lfw.lfQuality = PROOF_QUALITY;
lfw.lfItalic = (BYTE) (italic ? TRUE : FALSE);
lfw.lfWeight = bold ? FW_BOLD : FW_NORMAL;
fontName.copyToBuffer (lfw.lfFaceName, LF_FACESIZE - 1);
lfw.lfHeight = size > 0 ? size : -256;
standardSizedFont = wCreateFontIndirectW (&lfw);
}
else
{
zerostruct (lf);
lf.lfCharSet = DEFAULT_CHARSET;
lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
lf.lfOutPrecision = OUT_OUTLINE_PRECIS;
lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
lf.lfQuality = PROOF_QUALITY;
lf.lfItalic = (BYTE) (italic ? TRUE : FALSE);
lf.lfWeight = bold ? FW_BOLD : FW_NORMAL;
fontName.copyToBuffer (lf.lfFaceName, LF_FACESIZE - 1);
lf.lfHeight = size > 0 ? size : -256;
standardSizedFont = CreateFontIndirect (&lf);
}
if (standardSizedFont != 0)
{
if (SelectObject (dc, standardSizedFont) != 0)
{
fontH = standardSizedFont;
if (size == 0)
{
OUTLINETEXTMETRIC otm;
if (GetOutlineTextMetrics (dc, sizeof (otm), &otm) != 0)
{
if (wCreateFontIndirectW != 0)
{
lfw.lfHeight = -(int) otm.otmEMSquare;
fontH = wCreateFontIndirectW (&lfw);
}
else
{
lf.lfHeight = -(int) otm.otmEMSquare;
fontH = CreateFontIndirect (&lf);
}
SelectObject (dc, fontH);
DeleteObject (standardSizedFont);
}
}
}
else
{
jassertfalse
}
}
else
{
jassertfalse
}
}
return dc;
}
//==============================================================================
KERNINGPAIR* getKerningPairs (int& numKPs_) throw()
{
if (kps == 0)
{
if (wGetKerningPairsW != 0)
{
numKPs = wGetKerningPairsW (dc, 0, 0);
kps = (KERNINGPAIR*) juce_calloc (sizeof (KERNINGPAIR) * numKPs);
wGetKerningPairsW (dc, numKPs, kps);
}
else
{
numKPs = GetKerningPairs (dc, 0, 0);
kps = (KERNINGPAIR*) juce_calloc (sizeof (KERNINGPAIR) * numKPs);
GetKerningPairs (dc, numKPs, kps);
}
}
numKPs_ = numKPs;
return kps;
}
};
//==============================================================================
static MAT2 identityMatrix;
static void addGlyphToTypeface (HDC dc,
juce_wchar character,
Typeface& dest,
bool addKerning)
{
Path destShape;
GLYPHMETRICS gm;
float height;
BOOL ok = false;
if (wGetTextMetricsW != 0)
{
TEXTMETRICW tm;
ok = wGetTextMetricsW (dc, &tm);
height = (float) tm.tmHeight;
}
else
{
TEXTMETRIC tm;
ok = GetTextMetrics (dc, &tm);
height = (float) tm.tmHeight;
}
if (! ok)
{
dest.addGlyph (character, destShape, 0);
return;
}
const float scaleX = 1.0f / height;
const float scaleY = -1.0f / height;
int bufSize;
if (wGetGlyphOutlineW != 0)
bufSize = wGetGlyphOutlineW (dc, character, GGO_NATIVE,
&gm, 0, 0, &identityMatrix);
else
bufSize = GetGlyphOutline (dc, character, GGO_NATIVE,
&gm, 0, 0, &identityMatrix);
if (bufSize > 0)
{
char* const data = (char*) juce_malloc (bufSize);
if (wGetGlyphOutlineW != 0)
wGetGlyphOutlineW (dc, character, GGO_NATIVE, &gm,
bufSize, data, &identityMatrix);
else
GetGlyphOutline (dc, character, GGO_NATIVE, &gm,
bufSize, data, &identityMatrix);
const TTPOLYGONHEADER* pheader = (TTPOLYGONHEADER*) data;
while ((char*) pheader < data + bufSize)
{
#define remapX(v) (scaleX * (v).x.value)
#define remapY(v) (scaleY * (v).y.value)
float x = remapX (pheader->pfxStart);
float y = remapY (pheader->pfxStart);
destShape.startNewSubPath (x, y);
const TTPOLYCURVE* curve = (const TTPOLYCURVE*) ((const char*) pheader + sizeof (TTPOLYGONHEADER));
const char* const curveEnd = ((const char*) pheader) + pheader->cb;
while ((const char*) curve < curveEnd)
{
if (curve->wType == TT_PRIM_LINE)
{
for (int i = 0; i < curve->cpfx; ++i)
{
x = remapX (curve->apfx [i]);
y = remapY (curve->apfx [i]);
destShape.lineTo (x, y);
}
}
else if (curve->wType == TT_PRIM_QSPLINE)
{
for (int i = 0; i < curve->cpfx - 1; ++i)
{
const float x2 = remapX (curve->apfx [i]);
const float y2 = remapY (curve->apfx [i]);
float x3, y3;
if (i < curve->cpfx - 2)
{
x3 = 0.5f * (x2 + remapX (curve->apfx [i + 1]));
y3 = 0.5f * (y2 + remapY (curve->apfx [i + 1]));
}
else
{
x3 = remapX (curve->apfx [i + 1]);
y3 = remapY (curve->apfx [i + 1]);
}
destShape.quadraticTo (x2, y2, x3, y3);
x = x3;
y = y3;
}
}
curve = (const TTPOLYCURVE*) &(curve->apfx [curve->cpfx]);
}
pheader = (const TTPOLYGONHEADER*) curve;
destShape.closeSubPath();
}
juce_free (data);
}
dest.addGlyph (character, destShape, gm.gmCellIncX / height);
if (addKerning)
{
int numKPs;
const KERNINGPAIR* const kps = FontDCHolder::getInstance()->getKerningPairs (numKPs);
for (int i = 0; i < numKPs; ++i)
{
if (kps[i].wFirst == character)
{
dest.addKerningPair (kps[i].wFirst,
kps[i].wSecond,
kps[i].iKernAmount / height);
}
}
}
}
//==============================================================================
void Typeface::findAndAddSystemGlyph (juce_wchar character)
{
HDC dc = FontDCHolder::getInstance()->loadFont (getName(), isBold(), isItalic(), 0);
addGlyphToTypeface (dc, character, *this, true);
}
/*Image* Typeface::renderGlyphToImage (juce_wchar character, float& topLeftX, float& topLeftY)
{
HDC dc = FontDCHolder::getInstance()->loadFont (getName(), isBold(), isItalic(), hintingSize);
int bufSize;
GLYPHMETRICS gm;
const UINT format = GGO_GRAY2_BITMAP;
const int shift = 6;
if (wGetGlyphOutlineW != 0)
bufSize = wGetGlyphOutlineW (dc, character, format, &gm, 0, 0, &identityMatrix);
else
bufSize = GetGlyphOutline (dc, character, format, &gm, 0, 0, &identityMatrix);
Image* im = new Image (Image::SingleChannel, jmax (1, gm.gmBlackBoxX), jmax (1, gm.gmBlackBoxY), true);
if (bufSize > 0)
{
topLeftX = (float) gm.gmptGlyphOrigin.x;
topLeftY = (float) -gm.gmptGlyphOrigin.y;
uint8* const data = (uint8*) juce_calloc (bufSize);
if (wGetGlyphOutlineW != 0)
wGetGlyphOutlineW (dc, character, format, &gm, bufSize, data, &identityMatrix);
else
GetGlyphOutline (dc, character, format, &gm, bufSize, data, &identityMatrix);
const int stride = ((gm.gmBlackBoxX + 3) & ~3);
for (int y = gm.gmBlackBoxY; --y >= 0;)
{
for (int x = gm.gmBlackBoxX; --x >= 0;)
{
const int level = data [x + y * stride] << shift;
if (level > 0)
im->setPixelAt (x, y, Colour ((uint8) 0xff, (uint8) 0xff, (uint8) 0xff, (uint8) jmin (0xff, level)));
}
}
juce_free (data);
}
return im;
}*/
//==============================================================================
void Typeface::initialiseTypefaceCharacteristics (const String& fontName,
bool bold,
bool italic,
bool addAllGlyphsToFont)
{
zerostruct (identityMatrix);
identityMatrix.eM11.value = 1;
identityMatrix.eM22.value = 1;
clear();
HDC dc = FontDCHolder::getInstance()->loadFont (fontName, bold, italic, 0);
float height;
int firstChar, lastChar;
if (wGetTextMetricsW != 0)
{
TEXTMETRICW tm;
wGetTextMetricsW (dc, &tm);
height = (float) tm.tmHeight;
firstChar = tm.tmFirstChar;
lastChar = tm.tmLastChar;
setAscent (tm.tmAscent / height);
setDefaultCharacter (tm.tmDefaultChar);
}
else
{
TEXTMETRIC tm;
GetTextMetrics (dc, &tm);
height = (float) tm.tmHeight;
firstChar = tm.tmFirstChar;
lastChar = tm.tmLastChar;
setAscent (tm.tmAscent / height);
setDefaultCharacter (tm.tmDefaultChar);
}
setName (fontName);
setBold (bold);
setItalic (italic);
if (addAllGlyphsToFont)
{
for (int character = firstChar; character <= lastChar; ++character)
addGlyphToTypeface (dc, (juce_wchar) character, *this, false);
int numKPs;
const KERNINGPAIR* const kps = FontDCHolder::getInstance()->getKerningPairs (numKPs);
for (int i = 0; i < numKPs; ++i)
{
addKerningPair (kps[i].wFirst,
kps[i].wSecond,
kps[i].iKernAmount / height);
}
}
}
END_JUCE_NAMESPACE

+ 247
- 0
build/win32/platform_specific_code/juce_win32_Messaging.cpp View File

@@ -0,0 +1,247 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "win32_headers.h"
#include "../../../src/juce_core/basics/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "../../../src/juce_appframework/events/juce_MessageManager.h"
#include "../../../src/juce_appframework/application/juce_Application.h"
#include "../../../src/juce_core/basics/juce_SystemStats.h"
#include "../../../src/juce_core/misc/juce_PlatformUtilities.h"
#include "../../../src/juce_core/basics/juce_Time.h"
//==============================================================================
static const unsigned int specialId = WM_APP + 0x4400;
static const unsigned int broadcastId = WM_APP + 0x4403;
static const unsigned int specialCallbackId = WM_APP + 0x4402;
static const TCHAR* const messageWindowName = _T("JUCEWindow");
HWND juce_messageWindowHandle = 0;
extern long improbableWindowNumber; // defined in windowing.cpp
//==============================================================================
static LRESULT CALLBACK juce_MessageWndProc (HWND h,
UINT message,
WPARAM wParam,
LPARAM lParam) throw()
{
JUCE_TRY
{
if (h == juce_messageWindowHandle)
{
if (message == specialCallbackId)
{
MessageCallbackFunction* const func = (MessageCallbackFunction*) wParam;
return (LRESULT) (*func) ((void*) lParam);
}
else if (message == specialId)
{
// these are trapped early in the dispatch call, but must also be checked
// here in case there are windows modal dialog boxes doing their own
// dispatch loop and not calling our version
MessageManager::getInstance()->deliverMessage ((void*) lParam);
return 0;
}
else if (message == broadcastId)
{
String* const messageString = (String*) lParam;
MessageManager::getInstance()->deliverBroadcastMessage (*messageString);
delete messageString;
return 0;
}
else if (message == WM_COPYDATA && ((const COPYDATASTRUCT*) lParam)->dwData == broadcastId)
{
const String messageString ((const juce_wchar*) ((const COPYDATASTRUCT*) lParam)->lpData,
((const COPYDATASTRUCT*) lParam)->cbData / sizeof (juce_wchar));
PostMessage (juce_messageWindowHandle, broadcastId, 0, (LPARAM) new String (messageString));
return 0;
}
}
return DefWindowProc (h, message, wParam, lParam);
}
JUCE_CATCH_EXCEPTION
return 0;
}
bool juce_dispatchNextMessageOnSystemQueue (bool returnIfNoPendingMessages)
{
MSG m;
if (returnIfNoPendingMessages && ! PeekMessage (&m, (HWND) 0, 0, 0, 0))
return false;
if (GetMessage (&m, (HWND) 0, 0, 0) > 0)
{
if (m.message == specialId
&& m.hwnd == juce_messageWindowHandle)
{
MessageManager::getInstance()->deliverMessage ((void*) m.lParam);
}
else
{
if (GetWindowLong (m.hwnd, GWLP_USERDATA) != improbableWindowNumber
&& (m.message == WM_LBUTTONDOWN || m.message == WM_RBUTTONDOWN))
{
// if it's someone else's window being clicked on, and the focus is
// currently on a juce window, pass the kb focus over..
HWND currentFocus = GetFocus();
if (currentFocus == 0 || GetWindowLong (currentFocus, GWLP_USERDATA) == improbableWindowNumber)
SetFocus (m.hwnd);
}
TranslateMessage (&m);
DispatchMessage (&m);
}
}
return true;
}
//==============================================================================
bool juce_postMessageToSystemQueue (void* message)
{
return PostMessage (juce_messageWindowHandle, specialId, 0, (LPARAM) message) != 0;
}
//==============================================================================
void* MessageManager::callFunctionOnMessageThread (MessageCallbackFunction* callback,
void* userData)
{
if (MessageManager::getInstance()->isThisTheMessageThread())
return (*callback) (userData);
else
return (void*) SendMessage (juce_messageWindowHandle,
specialCallbackId,
(WPARAM) callback,
(LPARAM) userData);
}
//==============================================================================
static BOOL CALLBACK BroadcastEnumWindowProc (HWND hwnd, LPARAM lParam)
{
if (hwnd != juce_messageWindowHandle)
(reinterpret_cast <VoidArray*> (lParam))->add ((void*) hwnd);
return TRUE;
}
void MessageManager::broadcastMessage (const String& value)
{
VoidArray windows;
EnumWindows (&BroadcastEnumWindowProc, (LPARAM) &windows);
const String localCopy (value);
COPYDATASTRUCT data;
data.dwData = broadcastId;
data.cbData = (localCopy.length() + 1) * sizeof (juce_wchar);
data.lpData = (void*) (const juce_wchar*) localCopy;
for (int i = windows.size(); --i >= 0;)
{
HWND hwnd = (HWND) windows.getUnchecked(i);
TCHAR windowName [64]; // no need to read longer strings than this
GetWindowText (hwnd, windowName, 64);
windowName [63] = 0;
if (String (windowName) == String (messageWindowName))
{
DWORD_PTR result;
SendMessageTimeout (hwnd, WM_COPYDATA,
(WPARAM) juce_messageWindowHandle,
(LPARAM) &data,
SMTO_BLOCK | SMTO_ABORTIFHUNG,
8000,
&result);
}
}
}
//==============================================================================
static const String getMessageWindowClassName()
{
// this name has to be different for each app/dll instance because otherwise
// poor old Win32 can get a bit confused (even despite it not being a process-global
// window class).
static int number = 0;
if (number == 0)
number = 0x7fffffff & (int) Time::getHighResolutionTicks();
return T("JUCEWindowClass_") + String (number);
}
void MessageManager::doPlatformSpecificInitialisation()
{
OleInitialize (0);
const String className (getMessageWindowClassName());
HMODULE hmod = (HMODULE) PlatformUtilities::getCurrentModuleInstanceHandle();
WNDCLASSEX wc;
zerostruct (wc);
wc.cbSize = sizeof (wc);
wc.lpfnWndProc = (WNDPROC) juce_MessageWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 4;
wc.hInstance = hmod;
wc.lpszClassName = className;
RegisterClassEx (&wc);
juce_messageWindowHandle = CreateWindow (wc.lpszClassName,
messageWindowName,
0, 0, 0, 0, 0, 0, 0,
hmod, 0);
}
void MessageManager::doPlatformSpecificShutdown()
{
DestroyWindow (juce_messageWindowHandle);
UnregisterClass (getMessageWindowClassName(), 0);
OleUninitialize();
}
END_JUCE_NAMESPACE

+ 656
- 0
build/win32/platform_specific_code/juce_win32_Midi.cpp View File

@@ -0,0 +1,656 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "win32_headers.h"
#include "../../../src/juce_core/basics/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "../../../src/juce_appframework/audio/devices/juce_MidiOutput.h"
#include "../../../src/juce_appframework/audio/devices/juce_MidiInput.h"
#include "../../../src/juce_core/basics/juce_Time.h"
#include "../../../src/juce_core/threads/juce_Thread.h"
#include "../../../src/juce_core/containers/juce_MemoryBlock.h"
#ifdef JUCE_MSVC
#pragma warning (disable: 4312)
#endif
//==============================================================================
static const int midiBufferSize = 1024 * 10;
static const int numInHeaders = 32;
static const int inBufferSize = 128;
class MidiInThread : public Thread
{
public:
//==============================================================================
MidiInThread (MidiInput* const input_,
MidiInputCallback* const callback_)
: Thread (T("Juce Midi")),
hIn (0),
input (input_),
callback (callback_),
isStarted (false),
startTime (0),
pendingLength(0)
{
for (int i = numInHeaders; --i >= 0;)
{
zeromem (&hdr[i], sizeof (MIDIHDR));
hdr[i].lpData = inData[i];
hdr[i].dwBufferLength = inBufferSize;
}
};
~MidiInThread()
{
stop();
if (hIn != 0)
{
int count = 5;
while (--count >= 0)
{
if (midiInClose (hIn) == MMSYSERR_NOERROR)
break;
Sleep (20);
}
}
}
//==============================================================================
void handle (const uint32 message, const uint32 timeStamp)
{
jassert (validityInt == 0x12345678);
if (validityInt != 0x12345678)
return;
const int byte = message & 0xff;
if (byte < 0x80)
return;
static const char extraDataLengths[] = {
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
const int numBytes = extraDataLengths [byte - 0x80] + 1;
const double time = timeStampToTime (timeStamp);
lock.enter();
if (pendingLength < midiBufferSize - 12)
{
char* const p = pending + pendingLength;
*(double*) p = time;
*(uint32*) (p + 8) = numBytes;
*(uint32*) (p + 12) = message;
pendingLength += 12 + numBytes;
}
else
{
jassertfalse // midi buffer overflow! You might need to increase the size..
}
lock.exit();
notify();
}
void handleSysEx (MIDIHDR* hdr, const uint32 timeStamp)
{
jassert (validityInt == 0x12345678);
if (validityInt != 0x12345678)
return;
const int num = hdr->dwBytesRecorded;
if (num > 0)
{
const double time = timeStampToTime (timeStamp);
lock.enter();
if (pendingLength < midiBufferSize - (8 + num))
{
char* const p = pending + pendingLength;
*(double*) p = time;
*(uint32*) (p + 8) = num;
memcpy (p + 12, hdr->lpData, num);
pendingLength += 12 + num;
}
else
{
jassertfalse // midi buffer overflow! You might need to increase the size..
}
lock.exit();
notify();
}
}
void writeBlock (int i)
{
hdr[i].dwBytesRecorded = 0;
MMRESULT res = midiInPrepareHeader (hIn, &hdr[i], sizeof (MIDIHDR));
jassert (res == MMSYSERR_NOERROR);
res = midiInAddBuffer (hIn, &hdr[i], sizeof (MIDIHDR));
jassert (res == MMSYSERR_NOERROR);
}
void run()
{
MemoryBlock pendingCopy (64);
while (! threadShouldExit())
{
for (int i = 0; i < numInHeaders; ++i)
{
if ((hdr[i].dwFlags & WHDR_DONE) != 0)
{
MMRESULT res = midiInUnprepareHeader (hIn, &hdr[i], sizeof (MIDIHDR));
(void) res;
jassert (res == MMSYSERR_NOERROR);
writeBlock (i);
}
}
lock.enter();
int len = pendingLength;
if (len > 0)
{
pendingCopy.ensureSize (len);
pendingCopy.copyFrom (pending, 0, len);
pendingLength = 0;
}
lock.exit();
if (len == 0)
{
wait (500);
}
else
{
const char* p = (const char*) pendingCopy.getData();
while (len > 0)
{
const double time = *(const double*) p;
const int messageLen = *(const int*) (p + 8);
const MidiMessage message ((const uint8*) (p + 12), messageLen, time);
callback->handleIncomingMidiMessage (input, message);
p += 12 + messageLen;
len -= 12 + messageLen;
}
}
}
}
void start()
{
jassert (hIn != 0);
if (hIn != 0 && ! isStarted)
{
stop();
validityInt = 0x12345678;
int i;
for (i = 0; i < numInHeaders; ++i)
writeBlock (i);
startTime = Time::getMillisecondCounter();
MMRESULT res = midiInStart (hIn);
jassert (res == MMSYSERR_NOERROR);
if (res == MMSYSERR_NOERROR)
{
isStarted = true;
pendingLength = 0;
startThread (6);
}
}
}
void stop()
{
if (isStarted)
{
stopThread (5000);
midiInReset (hIn);
midiInStop (hIn);
for (int i = numInHeaders; --i >= 0;)
{
if ((hdr[i].dwFlags & WHDR_DONE) != 0)
{
int c = 10;
while (--c >= 0 && midiInUnprepareHeader (hIn, &hdr[i], sizeof (MIDIHDR)) == MIDIERR_STILLPLAYING)
Sleep (20);
jassert (c >= 0);
}
}
isStarted = false;
validityInt = 0;
}
}
juce_UseDebuggingNewOperator
HMIDIIN hIn;
private:
int validityInt;
MidiInput* input;
MidiInputCallback* callback;
bool isStarted;
uint32 startTime;
CriticalSection lock;
MIDIHDR hdr [numInHeaders];
char inData [numInHeaders] [inBufferSize];
int pendingLength;
char pending [midiBufferSize];
double timeStampToTime (uint32 timeStamp)
{
timeStamp += startTime;
const uint32 now = Time::getMillisecondCounter();
if (timeStamp > now)
{
if (timeStamp > now + 2)
--startTime;
timeStamp = now;
}
return 0.001 * timeStamp;
}
MidiInThread (const MidiInThread&);
const MidiInThread& operator= (const MidiInThread&);
};
static void CALLBACK midiInCallback (HMIDIIN,
UINT uMsg,
DWORD dwInstance,
DWORD midiMessage,
DWORD timeStamp)
{
MidiInThread* const thread = (MidiInThread*) dwInstance;
if (thread != 0)
{
if (uMsg == MIM_DATA)
thread->handle (midiMessage, timeStamp);
else if (uMsg == MIM_LONGDATA)
thread->handleSysEx ((MIDIHDR*) midiMessage, timeStamp);
}
}
//==============================================================================
const StringArray MidiInput::getDevices()
{
StringArray s;
const int num = midiInGetNumDevs();
for (int i = 0; i < num; ++i)
{
MIDIINCAPSW mc;
zerostruct (mc);
if (midiInGetDevCapsW (i, &mc, sizeof (mc)) == MMSYSERR_NOERROR)
s.add (String (mc.szPname, sizeof (mc.szPname)));
}
return s;
}
int MidiInput::getDefaultDeviceIndex()
{
return 0;
}
MidiInput* MidiInput::openDevice (int index, MidiInputCallback* callback)
{
if (callback == 0)
return 0;
UINT deviceId = MIDI_MAPPER;
int n = 0;
const int num = midiInGetNumDevs();
for (int i = 0; i < num; ++i)
{
MIDIINCAPSW mc;
zerostruct (mc);
if (midiInGetDevCapsW (i, &mc, sizeof (mc)) == MMSYSERR_NOERROR)
{
if (index == n)
{
deviceId = i;
break;
}
++n;
}
}
MidiInput* const in = new MidiInput (getDevices() [index]);
MidiInThread* const thread = new MidiInThread (in, callback);
HMIDIIN h;
HRESULT err = midiInOpen (&h, deviceId,
(DWORD_PTR) &midiInCallback,
(DWORD_PTR) thread,
CALLBACK_FUNCTION);
if (err == MMSYSERR_NOERROR)
{
thread->hIn = h;
in->internal = (void*) thread;
return in;
}
else
{
delete in;
delete thread;
return 0;
}
}
MidiInput::MidiInput (const String& name_)
: name (name_),
internal (0)
{
}
MidiInput::~MidiInput()
{
if (internal != 0)
{
MidiInThread* const thread = (MidiInThread*) internal;
delete thread;
}
}
void MidiInput::start()
{
((MidiInThread*)internal)->start();
}
void MidiInput::stop()
{
((MidiInThread*)internal)->stop();
}
//==============================================================================
struct MidiOutHandle
{
int refCount;
UINT deviceId;
HMIDIOUT handle;
juce_UseDebuggingNewOperator
};
static VoidArray handles (4);
//==============================================================================
const StringArray MidiOutput::getDevices()
{
StringArray s;
const int num = midiOutGetNumDevs();
for (int i = 0; i < num; ++i)
{
MIDIOUTCAPSW mc;
zerostruct (mc);
if (midiOutGetDevCapsW (i, &mc, sizeof (mc)) == MMSYSERR_NOERROR)
s.add (String (mc.szPname, sizeof (mc.szPname)));
}
return s;
}
int MidiOutput::getDefaultDeviceIndex()
{
const int num = midiOutGetNumDevs();
int n = 0;
for (int i = 0; i < num; ++i)
{
MIDIOUTCAPSW mc;
zerostruct (mc);
if (midiOutGetDevCapsW (i, &mc, sizeof (mc)) == MMSYSERR_NOERROR)
{
if ((mc.wTechnology & MOD_MAPPER) != 0)
return n;
++n;
}
}
return 0;
}
MidiOutput* MidiOutput::openDevice (int index)
{
UINT deviceId = MIDI_MAPPER;
const int num = midiOutGetNumDevs();
int i, n = 0;
for (i = 0; i < num; ++i)
{
MIDIOUTCAPSW mc;
zerostruct (mc);
if (midiOutGetDevCapsW (i, &mc, sizeof (mc)) == MMSYSERR_NOERROR)
{
// use the microsoft sw synth as a default - best not to allow deviceId
// to be MIDI_MAPPER, or else device sharing breaks
if (String (mc.szPname, sizeof (mc.szPname)).containsIgnoreCase (T("microsoft")))
deviceId = i;
if (index == n)
{
deviceId = i;
break;
}
++n;
}
}
for (i = handles.size(); --i >= 0;)
{
MidiOutHandle* const han = (MidiOutHandle*) handles[i];
if (han != 0 && han->deviceId == deviceId)
{
han->refCount++;
MidiOutput* out = new MidiOutput();
out->internal = (void*)han;
return out;
}
}
HMIDIOUT h = 0;
MMRESULT res = MMSYSERR_NOERROR + 1;
for (i = 4; --i >= 0;)
{
UINT devId = deviceId; // copy because this call changes the value
res = midiOutOpen (&h, devId, 0, 0, CALLBACK_NULL);
if (res != MMSYSERR_ALLOCATED)
break;
Sleep (100);
}
if (res == MMSYSERR_NOERROR)
{
MidiOutHandle* const han = new MidiOutHandle();
han->deviceId = deviceId;
han->refCount = 1;
han->handle = h;
handles.add (han);
MidiOutput* const out = new MidiOutput();
out->internal = (void*)han;
return out;
}
return 0;
}
MidiOutput::MidiOutput()
{
}
MidiOutput::~MidiOutput()
{
MidiOutHandle* const h = (MidiOutHandle*) internal;
if (handles.contains ((void*) h) && --(h->refCount) == 0)
{
midiOutClose (h->handle);
handles.removeValue ((void*)h);
handles.minimiseStorageOverheads();
delete h;
}
}
void MidiOutput::reset()
{
const MidiOutHandle* const h = (MidiOutHandle*) internal;
midiOutReset (h->handle);
}
bool MidiOutput::getVolume (float& leftVol,
float& rightVol)
{
const MidiOutHandle* const handle = (const MidiOutHandle*) internal;
DWORD n;
if (midiOutGetVolume (handle->handle, &n) == MMSYSERR_NOERROR)
{
const unsigned short* const nn = (const unsigned short*) &n;
rightVol = nn[0] / (float) 0xffff;
leftVol = nn[1] / (float) 0xffff;
return true;
}
else
{
rightVol = leftVol = 1.0f;
return false;
}
}
void MidiOutput::setVolume (float leftVol,
float rightVol)
{
const MidiOutHandle* const handle = (MidiOutHandle*)internal;
DWORD n;
unsigned short* nn = (unsigned short*) &n;
nn[0] = (unsigned short) jlimit (0, 0xffff, (int)(rightVol * 0xffff));
nn[1] = (unsigned short) jlimit (0, 0xffff, (int)(leftVol * 0xffff));
midiOutSetVolume (handle->handle, n);
}
void MidiOutput::sendMessageNow (const MidiMessage& message)
{
const MidiOutHandle* const handle = (const MidiOutHandle*) internal;
if (message.getRawDataSize() > 3)
{
MIDIHDR h;
zerostruct (h);
h.lpData = (char*) message.getRawData();
h.dwBufferLength = message.getRawDataSize();
h.dwBytesRecorded = message.getRawDataSize();
if (midiOutPrepareHeader (handle->handle, &h, sizeof (MIDIHDR)) == MMSYSERR_NOERROR)
{
MMRESULT res = midiOutLongMsg (handle->handle, &h, sizeof (MIDIHDR));
if (res == MMSYSERR_NOERROR)
{
while ((h.dwFlags & MHDR_DONE) == 0)
Sleep (1);
int count = 500; // 1 sec timeout
while (--count >= 0)
{
res = midiOutUnprepareHeader (handle->handle, &h, sizeof (MIDIHDR));
if (res == MIDIERR_STILLPLAYING)
Sleep (2);
else
break;
}
}
}
}
else
{
midiOutShortMsg (handle->handle,
*(unsigned int*) message.getRawData());
}
}
END_JUCE_NAMESPACE

+ 120
- 0
build/win32/platform_specific_code/juce_win32_Misc.cpp View File

@@ -0,0 +1,120 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "win32_headers.h"
#include "../../../src/juce_core/basics/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "../../../src/juce_core/misc/juce_PlatformUtilities.h"
#include "../../../src/juce_appframework/application/juce_SystemClipboard.h"
#include "../../../src/juce_appframework/gui/components/windows/juce_AlertWindow.h"
//==============================================================================
bool AlertWindow::showNativeDialogBox (const String& title,
const String& bodyText,
bool isOkCancel)
{
return MessageBox (0, bodyText, title,
(isOkCancel) ? MB_OKCANCEL
: MB_OK) == IDOK;
}
//==============================================================================
void PlatformUtilities::beep()
{
MessageBeep (MB_OK);
}
//==============================================================================
#ifdef JUCE_MSVC
#pragma warning (disable : 4127) // "Conditional expression is constant" warning
#endif
void SystemClipboard::copyTextToClipboard (const String& text)
{
if (OpenClipboard (0) != 0)
{
if (EmptyClipboard() != 0)
{
const int len = text.length();
if (len > 0)
{
HGLOBAL bufH = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE,
(len + 1) * sizeof (wchar_t));
if (bufH != 0)
{
wchar_t* const data = (wchar_t*) GlobalLock (bufH);
text.copyToBuffer (data, len);
GlobalUnlock (bufH);
SetClipboardData (CF_UNICODETEXT, bufH);
}
}
}
CloseClipboard();
}
}
const String SystemClipboard::getTextFromClipboard()
{
String result;
if (OpenClipboard (0) != 0)
{
HANDLE bufH = GetClipboardData (CF_UNICODETEXT);
if (bufH != 0)
{
const wchar_t* const data = (const wchar_t*) GlobalLock (bufH);
if (data != 0)
{
result = String (data, (int) (GlobalSize (bufH) / sizeof (tchar)));
GlobalUnlock (bufH);
}
}
CloseClipboard();
}
return result;
}
END_JUCE_NAMESPACE

+ 339
- 0
build/win32/platform_specific_code/juce_win32_Network.cpp View File

@@ -0,0 +1,339 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#ifdef _MSC_VER
#pragma warning (disable: 4514)
#pragma warning (push)
#endif
#include "win32_headers.h"
#include <wininet.h>
#include <nb30.h>
#include <iphlpapi.h>
#include "../../../src/juce_core/basics/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "../../../src/juce_core/text/juce_String.h"
#include "juce_win32_DynamicLibraryLoader.h"
#include "../../../src/juce_core/basics/juce_SystemStats.h"
#include "../../../src/juce_core/containers/juce_MemoryBlock.h"
#ifndef INTERNET_FLAG_NEED_FILE
#define INTERNET_FLAG_NEED_FILE 0x00000010
#endif
#ifdef _MSC_VER
#pragma warning (pop)
#endif
//==============================================================================
bool juce_isOnLine()
{
DWORD connectionType;
return InternetGetConnectedState (&connectionType, 0) != 0
|| (connectionType & (INTERNET_CONNECTION_LAN | INTERNET_CONNECTION_PROXY)) != 0;
}
struct ConnectionAndRequestStruct
{
HINTERNET connection, request;
};
static HINTERNET sessionHandle = 0;
void* juce_openInternetFile (const String& url,
const String& postText,
const bool isPost)
{
if (sessionHandle == 0)
sessionHandle = InternetOpen (_T("juce"), INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, 0);
if (sessionHandle != 0)
{
// break up the url..
TCHAR file[1024], server[1024];
URL_COMPONENTS uc;
zerostruct (uc);
uc.dwStructSize = sizeof (uc);
uc.dwUrlPathLength = sizeof (file);
uc.dwHostNameLength = sizeof (server);
uc.lpszUrlPath = file;
uc.lpszHostName = server;
if (InternetCrackUrl (url, 0,
ICU_ESCAPE | ICU_DECODE,
&uc))
{
const bool isFtp = url.startsWithIgnoreCase (T("ftp:"));
HINTERNET connection = InternetConnect (sessionHandle,
uc.lpszHostName,
uc.nPort,
_T(""), _T(""),
(isFtp) ? INTERNET_SERVICE_FTP
: INTERNET_SERVICE_HTTP,
0, 0);
if (connection != 0)
{
if (isFtp)
{
HINTERNET request = FtpOpenFile (connection,
uc.lpszUrlPath,
GENERIC_READ,
FTP_TRANSFER_TYPE_BINARY | INTERNET_FLAG_NEED_FILE,
0);
ConnectionAndRequestStruct* const result = new ConnectionAndRequestStruct();
result->connection = connection;
result->request = request;
return result;
}
else
{
const TCHAR* mimeTypes[] = { _T("*"), 0 };
HINTERNET request = HttpOpenRequest (connection,
isPost ? _T("POST")
: _T("GET"),
uc.lpszUrlPath,
0, 0,
mimeTypes,
INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE, 0);
if (request != 0)
{
// (this header is needed to make webservers process a POST request correctly)
const String hdr (T("Content-Type: application/x-www-form-urlencoded"));
if (HttpSendRequest (request,
hdr, hdr.length(),
(void*)(const char*) postText,
postText.length()))
{
ConnectionAndRequestStruct* const result = new ConnectionAndRequestStruct();
result->connection = connection;
result->request = request;
return result;
}
InternetCloseHandle (request);
}
InternetCloseHandle (connection);
}
}
}
}
return 0;
}
int juce_readFromInternetFile (void* handle, void* buffer, int bytesToRead)
{
DWORD bytesRead = 0;
const ConnectionAndRequestStruct* const crs = (const ConnectionAndRequestStruct*) handle;
if (crs != 0)
InternetReadFile (crs->request,
buffer, bytesToRead,
&bytesRead);
return bytesRead;
}
int juce_seekInInternetFile (void* handle, int newPosition)
{
if (handle != 0)
{
const ConnectionAndRequestStruct* const crs = (const ConnectionAndRequestStruct*) handle;
return InternetSetFilePointer (crs->request,
newPosition, 0,
FILE_BEGIN, 0);
}
else
{
return -1;
}
}
int juce_getStatusCodeFor (void* handle)
{
DWORD result = 404;
const ConnectionAndRequestStruct* const crs = (const ConnectionAndRequestStruct*) handle;
if (crs != 0)
{
DWORD index = 0;
DWORD size = sizeof (result);
HttpQueryInfo (crs->request,
HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER,
&result,
&size,
&index);
}
return (int) result;
}
void juce_closeInternetFile (void* handle)
{
if (handle != 0)
{
ConnectionAndRequestStruct* const crs = (ConnectionAndRequestStruct*) handle;
InternetCloseHandle (crs->request);
InternetCloseHandle (crs->connection);
delete crs;
}
}
static int getMACAddressViaGetAdaptersInfo (int64* addresses, int maxNum)
{
int numFound = 0;
DynamicLibraryLoader dll (T("iphlpapi.dll"));
DynamicLibraryImport (GetAdaptersInfo, getAdaptersInfo, DWORD, dll, (PIP_ADAPTER_INFO, PULONG))
if (getAdaptersInfo != 0)
{
ULONG len = sizeof (IP_ADAPTER_INFO);
MemoryBlock mb;
PIP_ADAPTER_INFO adapterInfo = (PIP_ADAPTER_INFO) mb.getData();
if (getAdaptersInfo (adapterInfo, &len) == ERROR_BUFFER_OVERFLOW)
{
mb.setSize (len);
adapterInfo = (PIP_ADAPTER_INFO) mb.getData();
}
if (getAdaptersInfo (adapterInfo, &len) == NO_ERROR)
{
PIP_ADAPTER_INFO adapter = adapterInfo;
while (adapter != 0)
{
int64 mac = 0;
for (unsigned int i = 0; i < adapter->AddressLength; ++i)
mac = (mac << 8) | adapter->Address[i];
if (numFound < maxNum && mac != 0)
addresses [numFound++] = mac;
adapter = adapter->Next;
}
}
}
return numFound;
}
static int getMACAddressesViaNetBios (int64* addresses, int maxNum)
{
int numFound = 0;
DynamicLibraryLoader dll (T("netapi32.dll"));
DynamicLibraryImport (Netbios, NetbiosCall, UCHAR, dll, (PNCB))
if (NetbiosCall != 0)
{
NCB ncb;
zerostruct (ncb);
typedef struct _ASTAT_
{
ADAPTER_STATUS adapt;
NAME_BUFFER NameBuff [30];
} ASTAT;
ASTAT astat;
zerostruct (astat);
LANA_ENUM enums;
zerostruct (enums);
ncb.ncb_command = NCBENUM;
ncb.ncb_buffer = (unsigned char*) &enums;
ncb.ncb_length = sizeof (LANA_ENUM);
NetbiosCall (&ncb);
for (int i = 0; i < enums.length; ++i)
{
zerostruct (ncb);
ncb.ncb_command = NCBRESET;
ncb.ncb_lana_num = enums.lana[i];
if (NetbiosCall (&ncb) == 0)
{
zerostruct (ncb);
memcpy (ncb.ncb_callname, "* ", NCBNAMSZ);
ncb.ncb_command = NCBASTAT;
ncb.ncb_lana_num = enums.lana[i];
ncb.ncb_buffer = (unsigned char*) &astat;
ncb.ncb_length = sizeof (ASTAT);
if (NetbiosCall (&ncb) == 0)
{
if (astat.adapt.adapter_type == 0xfe)
{
int64 mac = 0;
for (unsigned int i = 0; i < 6; ++i)
mac = (mac << 8) | astat.adapt.adapter_address[i];
if (numFound < maxNum && mac != 0)
addresses [numFound++] = mac;
}
}
}
}
}
return numFound;
}
int SystemStats::getMACAddresses (int64* addresses, int maxNum)
{
int numFound = getMACAddressViaGetAdaptersInfo (addresses, maxNum);
if (numFound == 0)
numFound = getMACAddressesViaNetBios (addresses, maxNum);
return numFound;
}
END_JUCE_NAMESPACE

+ 291
- 0
build/win32/platform_specific_code/juce_win32_PlatformUtils.cpp View File

@@ -0,0 +1,291 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#ifdef _MSC_VER
#pragma warning (disable: 4514)
#pragma warning (push)
#endif
#include "win32_headers.h"
#include <float.h>
#include "../../../src/juce_core/basics/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "../../../src/juce_core/misc/juce_PlatformUtilities.h"
#include "../../../src/juce_core/basics/juce_SystemStats.h"
#ifdef _MSC_VER
#pragma warning (pop)
#endif
//==============================================================================
UNICODE_FUNCTION (RegCreateKeyExW, LONG, (HKEY, LPCWSTR, DWORD, LPWSTR, DWORD, REGSAM, LPSECURITY_ATTRIBUTES, PHKEY, LPDWORD))
UNICODE_FUNCTION (RegOpenKeyExW, LONG, (HKEY, LPCWSTR, DWORD, REGSAM, PHKEY))
UNICODE_FUNCTION (RegQueryValueExW, LONG, (HKEY, LPCWSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD))
UNICODE_FUNCTION (RegSetValueExW, LONG, (HKEY, LPCWSTR, DWORD, DWORD, const BYTE*, DWORD))
UNICODE_FUNCTION (RegDeleteValueW, LONG, (HKEY, LPCWSTR))
UNICODE_FUNCTION (RegDeleteKeyW, LONG, (HKEY, LPCWSTR))
void juce_initialiseUnicodeRegistryFunctions()
{
static bool initialised = false;
if (! initialised)
{
initialised = true;
if ((SystemStats::getOperatingSystemType() & SystemStats::WindowsNT) != 0)
{
HMODULE h = LoadLibraryA ("Advapi32.dll");
UNICODE_FUNCTION_LOAD (RegCreateKeyExW)
UNICODE_FUNCTION_LOAD (RegOpenKeyExW)
UNICODE_FUNCTION_LOAD (RegQueryValueExW)
UNICODE_FUNCTION_LOAD (RegSetValueExW)
UNICODE_FUNCTION_LOAD (RegDeleteValueW)
UNICODE_FUNCTION_LOAD (RegDeleteKeyW)
}
}
}
//==============================================================================
static HKEY findKeyForPath (String name,
const bool createForWriting,
String& valueName)
{
juce_initialiseUnicodeRegistryFunctions();
HKEY rootKey = 0;
if (name.startsWithIgnoreCase (T("HKEY_CURRENT_USER\\")))
rootKey = HKEY_CURRENT_USER;
else if (name.startsWithIgnoreCase (T("HKEY_LOCAL_MACHINE\\")))
rootKey = HKEY_LOCAL_MACHINE;
else if (name.startsWithIgnoreCase (T("HKEY_CLASSES_ROOT\\")))
rootKey = HKEY_CLASSES_ROOT;
if (rootKey != 0)
{
name = name.substring (name.indexOfChar (T('\\')) + 1);
const int lastSlash = name.lastIndexOfChar (T('\\'));
valueName = name.substring (lastSlash + 1);
name = name.substring (0, lastSlash);
HKEY key;
DWORD result;
if (createForWriting)
{
if (wRegCreateKeyExW != 0)
{
if (wRegCreateKeyExW (rootKey, name, 0, L"", REG_OPTION_NON_VOLATILE,
(KEY_WRITE | KEY_QUERY_VALUE), 0, &key, &result) == ERROR_SUCCESS)
{
return key;
}
}
else
{
if (RegCreateKeyEx (rootKey, name, 0, _T(""), REG_OPTION_NON_VOLATILE,
(KEY_WRITE | KEY_QUERY_VALUE), 0, &key, &result) == ERROR_SUCCESS)
{
return key;
}
}
}
else
{
if (wRegOpenKeyExW != 0)
{
if (wRegOpenKeyExW (rootKey, name, 0, KEY_READ, &key) == ERROR_SUCCESS)
{
return key;
}
}
else
{
if (RegOpenKeyEx (rootKey, name, 0, KEY_READ, &key) == ERROR_SUCCESS)
{
return key;
}
}
}
}
return 0;
}
const String PlatformUtilities::getRegistryValue (const String& regValuePath,
const String& defaultValue)
{
String valueName, s;
HKEY k = findKeyForPath (regValuePath, false, valueName);
if (k != 0)
{
if (wRegQueryValueExW != 0)
{
WCHAR buffer [2048];
unsigned long bufferSize = sizeof (buffer);
DWORD type = REG_SZ;
if (wRegQueryValueExW (k, valueName, 0, &type, (LPBYTE) buffer, &bufferSize) == ERROR_SUCCESS)
s = buffer;
else
s = defaultValue;
}
else
{
TCHAR buffer [2048];
unsigned long bufferSize = sizeof (buffer);
DWORD type = REG_SZ;
if (RegQueryValueEx (k, valueName, 0, &type, (LPBYTE) buffer, &bufferSize) == ERROR_SUCCESS)
s = buffer;
else
s = defaultValue;
}
RegCloseKey (k);
}
return s;
}
void PlatformUtilities::setRegistryValue (const String& regValuePath,
const String& value)
{
String valueName;
HKEY k = findKeyForPath (regValuePath, true, valueName);
if (k != 0)
{
if (wRegSetValueExW != 0)
wRegSetValueExW (k, valueName, 0, REG_SZ,
(const BYTE*) (const WCHAR*) value,
sizeof (WCHAR) * (value.length() + 1));
else
RegSetValueEx (k, valueName, 0, REG_SZ,
(const BYTE*) (const TCHAR*) value,
sizeof (TCHAR) * (value.length() + 1));
RegCloseKey (k);
}
}
bool PlatformUtilities::registryValueExists (const String& regValuePath)
{
bool exists = false;
String valueName;
HKEY k = findKeyForPath (regValuePath, false, valueName);
if (k != 0)
{
unsigned char buffer [2048];
unsigned long bufferSize = sizeof (buffer);
DWORD type = 0;
if (wRegQueryValueExW != 0)
{
if (wRegQueryValueExW (k, valueName, 0, &type, buffer, &bufferSize) == ERROR_SUCCESS)
exists = true;
}
else
{
if (RegQueryValueEx (k, valueName, 0, &type, buffer, &bufferSize) == ERROR_SUCCESS)
exists = true;
}
RegCloseKey (k);
}
return exists;
}
void PlatformUtilities::deleteRegistryValue (const String& regValuePath)
{
String valueName;
HKEY k = findKeyForPath (regValuePath, true, valueName);
if (k != 0)
{
if (wRegDeleteValueW != 0)
wRegDeleteValueW (k, valueName);
else
RegDeleteValue (k, valueName);
RegCloseKey (k);
}
}
void PlatformUtilities::deleteRegistryKey (const String& regKeyPath)
{
String valueName;
HKEY k = findKeyForPath (regKeyPath, true, valueName);
if (k != 0)
{
if (wRegDeleteKeyW != 0)
wRegDeleteKeyW (k, valueName);
else
RegDeleteKey (k, valueName);
RegCloseKey (k);
}
}
//==============================================================================
static void* currentModuleHandle = 0;
void* PlatformUtilities::getCurrentModuleInstanceHandle()
{
if (currentModuleHandle == 0)
currentModuleHandle = GetModuleHandle (0);
return currentModuleHandle;
}
void PlatformUtilities::setCurrentModuleInstanceHandle (void* newHandle)
{
currentModuleHandle = newHandle;
}
void PlatformUtilities::fpuReset()
{
#ifdef JUCE_MSVC
_clearfp();
#endif
}
END_JUCE_NAMESPACE

+ 605
- 0
build/win32/platform_specific_code/juce_win32_SystemStats.cpp View File

@@ -0,0 +1,605 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "win32_headers.h"
#include "../../../src/juce_core/basics/juce_StandardHeader.h"
//==============================================================================
// Auto-link the other win32 libs that are needed by library calls..
#if defined (JUCE_DLL_BUILD) && JUCE_MSVC
#pragma comment(lib, "kernel32.lib")
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "shell32.lib")
#pragma comment(lib, "gdi32.lib")
#pragma comment(lib, "vfw32.lib")
#pragma comment(lib, "comdlg32.lib")
#pragma comment(lib, "winmm.lib")
#pragma comment(lib, "wininet.lib")
#pragma comment(lib, "ole32.lib")
#pragma comment(lib, "advapi32.lib")
#pragma comment(lib, "ws2_32.lib")
#if JUCE_OPENGL
#pragma comment(lib, "OpenGL32.Lib")
#pragma comment(lib, "GlU32.Lib")
#endif
#endif
//==============================================================================
BEGIN_JUCE_NAMESPACE
#include "../../../src/juce_core/io/files/juce_File.h"
#include "../../../src/juce_core/basics/juce_SystemStats.h"
#include "juce_win32_DynamicLibraryLoader.h"
extern void juce_updateMultiMonitorInfo(); // from WindowDriver
//==============================================================================
void Logger::outputDebugString (const String& text)
{
OutputDebugString (text + T("\n"));
}
void Logger::outputDebugPrintf (const tchar* format, ...)
{
String text;
va_list args;
va_start (args, format);
text.vprintf(format, args);
outputDebugString (text);
}
//==============================================================================
static int64 hiResTicksPerSecond;
static double hiResTicksScaleFactor;
static SYSTEM_INFO systemInfo;
static struct _LogicalCpuInfo
{
bool htSupported;
bool htAvailable;
int numPackages;
int numLogicalPerPackage;
unsigned long physicalAffinityMask;
} logicalCpuInfo;
//==============================================================================
#if JUCE_USE_INTRINSICS
// CPU info functions using intrinsics...
#pragma intrinsic (__cpuid)
#pragma intrinsic (__rdtsc)
static unsigned int getCPUIDWord (int* familyModel = 0, int* extFeatures = 0)
{
int info [4];
__cpuid (info, 1);
if (familyModel != 0)
*familyModel = info [0];
if (extFeatures != 0)
*extFeatures = info[1];
return info[3];
}
const String SystemStats::getCpuVendor()
{
int info [4];
__cpuid (info, 0);
char v [12];
memcpy (v, info + 1, 4);
memcpy (v + 4, info + 3, 4);
memcpy (v + 8, info + 2, 4);
return String (v, 12);
}
#else
//==============================================================================
// CPU info functions using old fashioned inline asm...
static juce_noinline unsigned int getCPUIDWord (int* familyModel = 0, int* extFeatures = 0)
{
unsigned int cpu = 0;
unsigned int ext = 0;
unsigned int family = 0;
#ifdef JUCE_GCC
unsigned int dummy = 0;
#endif
#ifndef __MINGW32__
__try
#endif
{
#ifdef JUCE_GCC
__asm__ ("cpuid" : "=a" (family), "=b" (ext), "=c" (dummy),"=d" (cpu) : "a" (1));
#else
__asm
{
mov eax, 1
cpuid
mov cpu, edx
mov family, eax
mov ext, ebx
}
#endif
}
#ifndef __MINGW32__
__except (EXCEPTION_EXECUTE_HANDLER)
{
return 0;
}
#endif
if (familyModel != 0)
*familyModel = family;
if (extFeatures != 0)
*extFeatures = ext;
return cpu;
}
static void juce_getCpuVendor (char* const v)
{
int vendor[4];
zeromem (vendor, 16);
#ifdef JUCE_64BIT
#else
#ifndef __MINGW32__
__try
#endif
{
#ifdef JUCE_GCC
unsigned int dummy = 0;
__asm__ ("cpuid" : "=a" (dummy), "=b" (vendor[0]), "=c" (vendor[2]),"=d" (vendor[1]) : "a" (0));
#else
__asm
{
mov eax, 0
cpuid
mov [vendor], ebx
mov [vendor + 4], edx
mov [vendor + 8], ecx
}
#endif
}
#ifndef __MINGW32__
__except (EXCEPTION_EXECUTE_HANDLER)
{
*v = 0;
}
#endif
#endif
memcpy (v, vendor, 16);
}
const String SystemStats::getCpuVendor()
{
char v [16];
juce_getCpuVendor (v);
return String (v, 16);
}
#endif
static void initLogicalCpuInfo()
{
int familyModelWord, extFeaturesWord;
int featuresWord = getCPUIDWord (&familyModelWord, &extFeaturesWord);
HANDLE hCurrentProcessHandle = GetCurrentProcess();
logicalCpuInfo.htSupported = false;
logicalCpuInfo.htAvailable = false;
logicalCpuInfo.numLogicalPerPackage = 1;
logicalCpuInfo.numPackages = 0;
logicalCpuInfo.physicalAffinityMask = 0;
DWORD_PTR processAffinity, systemAffinity;
if (! GetProcessAffinityMask (hCurrentProcessHandle, &processAffinity, &systemAffinity))
return;
// Checks: CPUID supported, model >= Pentium 4, Hyperthreading bit set, logical CPUs per package > 1
if (featuresWord == 0
|| ((familyModelWord >> 8) & 0xf) < 15
|| (featuresWord & (1 << 28)) == 0
|| ((extFeaturesWord >> 16) & 0xff) < 2)
{
logicalCpuInfo.physicalAffinityMask = static_cast <unsigned long> (processAffinity);
return;
}
logicalCpuInfo.htSupported = true;
logicalCpuInfo.numLogicalPerPackage = (extFeaturesWord >> 16) & 0xff;
unsigned int affinityMask;
unsigned int physAff = 0;
unsigned char i = 1;
unsigned char physIdMask = 0xFF;
unsigned char physIdShift = 0;
unsigned char apicId;
unsigned char logId;
unsigned char physId;
while (i < logicalCpuInfo.numLogicalPerPackage)
{
i *= 2;
physIdMask <<= 1;
physIdShift++;
}
affinityMask = 1;
logicalCpuInfo.numPackages = 0;
while ((affinityMask != 0) && (affinityMask <= processAffinity))
{
if (SetProcessAffinityMask (hCurrentProcessHandle, affinityMask))
{
Sleep(0); // schedule onto correct CPU
featuresWord = getCPUIDWord (&familyModelWord, &extFeaturesWord);
apicId = (unsigned char) (extFeaturesWord >> 24);
logId = (unsigned char) (apicId & ~physIdMask);
physId = (unsigned char) (apicId >> physIdShift);
if (logId != 0)
logicalCpuInfo.htAvailable = true;
if ((((int) logId) % logicalCpuInfo.numLogicalPerPackage) == 0)
{
// This is a physical CPU
physAff |= affinityMask;
logicalCpuInfo.numPackages++;
}
}
affinityMask = affinityMask << 1;
}
logicalCpuInfo.physicalAffinityMask = physAff;
SetProcessAffinityMask(hCurrentProcessHandle, processAffinity);
}
//==============================================================================
void juce_initialiseThreadEvents();
void juce_initialiseUnicodeFileFunctions();
static struct JuceCpuProps
{
bool hasMMX : 1, hasSSE : 1, hasSSE2 : 1, has3DNow : 1;
} juce_CpuProps;
bool SystemStats::hasMMX()
{
return juce_CpuProps.hasMMX;
}
bool SystemStats::hasSSE()
{
return juce_CpuProps.hasSSE;
}
bool SystemStats::hasSSE2()
{
return juce_CpuProps.hasSSE2;
}
bool SystemStats::has3DNow()
{
return juce_CpuProps.has3DNow;
}
void SystemStats::initialiseStats()
{
juce_initialiseUnicodeFileFunctions();
juce_initialiseThreadEvents();
juce_CpuProps.hasMMX = IsProcessorFeaturePresent (PF_MMX_INSTRUCTIONS_AVAILABLE) != 0;
juce_CpuProps.hasSSE = IsProcessorFeaturePresent (PF_XMMI_INSTRUCTIONS_AVAILABLE) != 0;
juce_CpuProps.hasSSE2 = IsProcessorFeaturePresent (PF_XMMI64_INSTRUCTIONS_AVAILABLE) != 0;
#ifdef PF_AMD3D_INSTRUCTIONS_AVAILABLE
juce_CpuProps.has3DNow = IsProcessorFeaturePresent (PF_AMD3D_INSTRUCTIONS_AVAILABLE) != 0;
#else
juce_CpuProps.has3DNow = IsProcessorFeaturePresent (PF_3DNOW_INSTRUCTIONS_AVAILABLE) != 0;
#endif
LARGE_INTEGER f;
QueryPerformanceFrequency (&f);
hiResTicksPerSecond = f.QuadPart;
hiResTicksScaleFactor = 1000.0 / hiResTicksPerSecond;
String s (SystemStats::getJUCEVersion());
GetSystemInfo (&systemInfo);
initLogicalCpuInfo();
#ifdef JUCE_DEBUG
const MMRESULT res = timeBeginPeriod (1);
jassert (res == TIMERR_NOERROR);
#else
timeBeginPeriod (1);
#endif
#if JUCE_DEBUG && JUCE_MSVC && JUCE_CHECK_MEMORY_LEAKS
_CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif
}
//==============================================================================
SystemStats::OperatingSystemType SystemStats::getOperatingSystemType()
{
OSVERSIONINFO info;
info.dwOSVersionInfoSize = sizeof (info);
GetVersionEx (&info);
if (info.dwPlatformId == VER_PLATFORM_WIN32_NT)
{
switch (info.dwMajorVersion)
{
case 3:
return WinNT351;
case 4:
return WinNT40;
case 5:
return (info.dwMinorVersion == 0) ? Win2000 : WinXP;
case 6:
return WinVista;
default:
break;
}
}
else if (info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
{
return (info.dwMinorVersion == 0) ? Win95 : Win98;
}
return UnknownOS;
}
const String SystemStats::getOperatingSystemName()
{
const tchar* name = T("Unknown OS");
switch (getOperatingSystemType())
{
case WinXP:
name = T("Windows XP");
break;
case Win2000:
name = T("Windows 2000");
break;
case Win98:
name = T("Windows 98");
break;
case Win95:
name = T("Windows 95");
break;
case WinNT351:
name = T("Windows NT 3.51");
break;
case WinNT40:
name = T("Windows NT4");
break;
case WinVista:
name = T("Windows Vista");
break;
default:
break;
}
return name;
}
//==============================================================================
int SystemStats::getMemorySizeInMegabytes()
{
MEMORYSTATUS mem;
GlobalMemoryStatus (&mem);
return (int) (mem.dwTotalPhys / (1024 * 1024)) + 1;
}
bool SystemStats::hasHyperThreading()
{
return logicalCpuInfo.htAvailable;
}
int SystemStats::getNumPhysicalCpus()
{
if (logicalCpuInfo.numPackages)
return logicalCpuInfo.numPackages;
return getNumLogicalCpus();
}
int SystemStats::getNumLogicalCpus()
{
return systemInfo.dwNumberOfProcessors;
}
uint32 SystemStats::getPhysicalAffinityMask()
{
return logicalCpuInfo.physicalAffinityMask;
}
//==============================================================================
uint32 juce_millisecondsSinceStartup() throw()
{
return (uint32) GetTickCount();
}
int64 Time::getHighResolutionTicks() throw()
{
LARGE_INTEGER ticks;
QueryPerformanceCounter (&ticks);
const int64 mainCounterAsHiResTicks = (GetTickCount() * hiResTicksPerSecond) / 1000;
const int64 newOffset = mainCounterAsHiResTicks - ticks.QuadPart;
// fix for a very obscure PCI hardware bug that can make the counter
// sometimes jump forwards by a few seconds..
static int64 hiResTicksOffset = 0;
const int offsetDrift = abs ((int) (newOffset - hiResTicksOffset));
if (offsetDrift > ((int) hiResTicksPerSecond) >> 1)
hiResTicksOffset = newOffset;
return ticks.QuadPart + hiResTicksOffset;
}
double Time::getMillisecondCounterHiRes() throw()
{
return getHighResolutionTicks() * hiResTicksScaleFactor;
}
int64 Time::getHighResolutionTicksPerSecond() throw()
{
return hiResTicksPerSecond;
}
int64 SystemStats::getClockCycleCounter()
{
#if JUCE_USE_INTRINSICS
// MS intrinsics version...
return __rdtsc();
#elif JUCE_GCC
// GNU inline asm version...
unsigned int hi = 0, lo = 0;
__asm__ __volatile__ (
"xor %%eax, %%eax \n\
xor %%edx, %%edx \n\
rdtsc \n\
movl %%eax, %[lo] \n\
movl %%edx, %[hi]"
:
: [hi] "m" (hi),
[lo] "m" (lo)
: "cc", "eax", "ebx", "ecx", "edx", "memory");
return (int64) ((((uint64) hi) << 32) | lo);
#else
// MSVC inline asm version...
unsigned int hi = 0, lo = 0;
__asm
{
xor eax, eax
xor edx, edx
rdtsc
mov lo, eax
mov hi, edx
}
return (int64) ((((uint64) hi) << 32) | lo);
#endif
}
int SystemStats::getCpuSpeedInMegaherz()
{
const int64 cycles = SystemStats::getClockCycleCounter();
const uint32 millis = Time::getMillisecondCounter();
int lastResult = 0;
for (;;)
{
int n = 1000000;
while (--n > 0) {}
const uint32 millisElapsed = Time::getMillisecondCounter() - millis;
const int64 cyclesNow = SystemStats::getClockCycleCounter();
if (millisElapsed > 80)
{
const int newResult = (int) (((cyclesNow - cycles) / millisElapsed) / 1000);
if (millisElapsed > 500 || (lastResult == newResult && newResult > 100))
return newResult;
lastResult = newResult;
}
}
}
//==============================================================================
bool Time::setSystemTimeToThisTime() const
{
SYSTEMTIME st;
st.wDayOfWeek = 0;
st.wYear = (WORD) getYear();
st.wMonth = (WORD) (getMonth() + 1);
st.wDay = (WORD) getDayOfMonth();
st.wHour = (WORD) getHours();
st.wMinute = (WORD) getMinutes();
st.wSecond = (WORD) getSeconds();
st.wMilliseconds = (WORD) (millisSinceEpoch % 1000);
// do this twice because of daylight saving conversion problems - the
// first one sets it up, the second one kicks it in.
return SetLocalTime (&st) != 0
&& SetLocalTime (&st) != 0;
}
int SystemStats::getPageSize()
{
return systemInfo.dwPageSize;
}
END_JUCE_NAMESPACE

+ 390
- 0
build/win32/platform_specific_code/juce_win32_Threads.cpp View File

@@ -0,0 +1,390 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "win32_headers.h"
#ifdef _MSC_VER
#pragma warning (disable: 4514)
#pragma warning (push)
#include <crtdbg.h>
#endif
#include <process.h>
#include "../../../src/juce_core/basics/juce_StandardHeader.h"
BEGIN_JUCE_NAMESPACE
#include "../../../src/juce_core/text/juce_String.h"
#include "../../../src/juce_core/threads/juce_CriticalSection.h"
#include "../../../src/juce_core/threads/juce_WaitableEvent.h"
#include "../../../src/juce_core/threads/juce_Thread.h"
#include "../../../src/juce_core/threads/juce_Process.h"
#include "../../../src/juce_core/threads/juce_InterProcessLock.h"
extern HWND juce_messageWindowHandle;
#ifdef _MSC_VER
#pragma warning (pop)
#endif
//==============================================================================
CriticalSection::CriticalSection() throw()
{
// (just to check the MS haven't changed this structure and broken things...)
#if _MSC_VER >= 1400
static_jassert (sizeof (CRITICAL_SECTION) <= sizeof (internal));
#else
static_jassert (sizeof (CRITICAL_SECTION) <= 24);
#endif
InitializeCriticalSection ((CRITICAL_SECTION*) internal);
}
CriticalSection::~CriticalSection() throw()
{
DeleteCriticalSection ((CRITICAL_SECTION*) internal);
}
void CriticalSection::enter() const throw()
{
EnterCriticalSection ((CRITICAL_SECTION*) internal);
}
bool CriticalSection::tryEnter() const throw()
{
return TryEnterCriticalSection ((CRITICAL_SECTION*) internal) != FALSE;
}
void CriticalSection::exit() const throw()
{
LeaveCriticalSection ((CRITICAL_SECTION*) internal);
}
//==============================================================================
WaitableEvent::WaitableEvent() throw()
{
internal = CreateEvent (0, FALSE, FALSE, 0);
}
WaitableEvent::~WaitableEvent() throw()
{
CloseHandle (internal);
}
bool WaitableEvent::wait (const int timeOutMillisecs) const throw()
{
return WaitForSingleObject (internal, timeOutMillisecs) == WAIT_OBJECT_0;
}
void WaitableEvent::signal() const throw()
{
SetEvent (internal);
}
void WaitableEvent::reset() const throw()
{
ResetEvent (internal);
}
//==============================================================================
void JUCE_API juce_threadEntryPoint (void*);
static unsigned int __stdcall threadEntryProc (void* userData)
{
AttachThreadInput (GetWindowThreadProcessId (juce_messageWindowHandle, 0),
GetCurrentThreadId(), TRUE);
juce_threadEntryPoint (userData);
_endthread();
return 0;
}
void* juce_createThread (void* userData)
{
unsigned int threadId;
return (void*) _beginthreadex (0, 0,
&threadEntryProc,
userData,
0, &threadId);
}
void juce_killThread (void* handle)
{
if (handle != 0)
{
#ifdef JUCE_DEBUG
OutputDebugString (_T("** Warning - Forced thread termination **\n"));
#endif
TerminateThread (handle, 0);
}
}
void juce_setCurrentThreadName (const String& name)
{
#if JUCE_DEBUG && JUCE_MSVC
struct
{
DWORD dwType;
LPCSTR szName;
DWORD dwThreadID;
DWORD dwFlags;
} info;
info.dwType = 0x1000;
info.szName = name;
info.dwThreadID = GetCurrentThreadId();
info.dwFlags = 0;
#define MS_VC_EXCEPTION 0x406d1388
__try
{
RaiseException (MS_VC_EXCEPTION, 0, sizeof (info) / sizeof (ULONG_PTR), (ULONG_PTR*) &info);
}
__except (EXCEPTION_CONTINUE_EXECUTION)
{}
#else
(void) name;
#endif
}
int Thread::getCurrentThreadId()
{
return (int) GetCurrentThreadId();
}
// priority 1 to 10 where 5=normal, 1=low
void juce_setThreadPriority (void* threadHandle, int priority)
{
int pri = THREAD_PRIORITY_TIME_CRITICAL;
if (priority < 1)
pri = THREAD_PRIORITY_IDLE;
else if (priority < 2)
pri = THREAD_PRIORITY_LOWEST;
else if (priority < 5)
pri = THREAD_PRIORITY_BELOW_NORMAL;
else if (priority < 7)
pri = THREAD_PRIORITY_NORMAL;
else if (priority < 9)
pri = THREAD_PRIORITY_ABOVE_NORMAL;
else if (priority < 10)
pri = THREAD_PRIORITY_HIGHEST;
if (threadHandle == 0)
threadHandle = GetCurrentThread();
SetThreadPriority (threadHandle, pri);
}
void Thread::setCurrentThreadAffinityMask (const uint32 affinityMask)
{
SetThreadAffinityMask (GetCurrentThread(), affinityMask);
}
static HANDLE sleepEvent = 0;
void juce_initialiseThreadEvents()
{
sleepEvent = CreateEvent (0, 0, 0, 0);
}
void Thread::yield()
{
Sleep (0);
}
void Thread::sleep (int millisecs)
{
if (millisecs >= 10)
{
Sleep (millisecs);
}
else
{
jassert (sleepEvent != 0);
// unlike Sleep() this is guaranteed to return to the current thread after
// the time expires, so we'll use this for short waits, which are more likely
// to need to be accurate
WaitForSingleObject (sleepEvent, millisecs);
}
}
//==============================================================================
static int lastProcessPriority = -1;
// called by WindowDriver because Windows does wierd things to process priority
// when you swap apps, and this forces an update when the app is brought to the front.
void repeatLastProcessPriority()
{
if (lastProcessPriority >= 0) // (avoid changing this if it's not been explicitly set by the app..)
{
DWORD p;
switch (lastProcessPriority)
{
case Process::LowPriority:
p = IDLE_PRIORITY_CLASS;
break;
case Process::NormalPriority:
p = NORMAL_PRIORITY_CLASS;
break;
case Process::HighPriority:
p = HIGH_PRIORITY_CLASS;
break;
case Process::RealtimePriority:
p = REALTIME_PRIORITY_CLASS;
break;
default:
jassertfalse // bad priority value
return;
}
SetPriorityClass (GetCurrentProcess(), p);
}
}
void Process::setPriority (ProcessPriority prior)
{
if (lastProcessPriority != (int) prior)
{
lastProcessPriority = (int) prior;
repeatLastProcessPriority();
}
}
//==============================================================================
void Process::raisePrivilege()
{
jassertfalse // xxx not implemented
}
void Process::lowerPrivilege()
{
jassertfalse // xxx not implemented
}
void Process::terminate()
{
#if JUCE_DEBUG && JUCE_MSVC && JUCE_CHECK_MEMORY_LEAKS
_CrtDumpMemoryLeaks();
#endif
// bullet in the head in case there's a problem shutting down..
ExitProcess (0);
}
void* Process::loadDynamicLibrary (const String& name)
{
void* result = 0;
JUCE_TRY
{
result = (void*) LoadLibrary (name);
}
JUCE_CATCH_ALL
return result;
}
void Process::freeDynamicLibrary (void* h)
{
JUCE_TRY
{
if (h != 0)
FreeLibrary ((HMODULE) h);
}
JUCE_CATCH_ALL
}
void* Process::getProcedureEntryPoint (void* h, const String& name)
{
return (h != 0) ? (void*) GetProcAddress ((HMODULE) h, name)
: 0;
}
//==============================================================================
InterProcessLock::InterProcessLock (const String& name_)
: internal (0),
name (name_),
reentrancyLevel (0)
{
}
InterProcessLock::~InterProcessLock()
{
exit();
}
bool InterProcessLock::enter (int timeOutMillisecs)
{
if (reentrancyLevel++ == 0)
{
internal = CreateMutex (0, TRUE, name);
if (internal != 0 && GetLastError() == ERROR_ALREADY_EXISTS)
{
if (timeOutMillisecs == 0
|| WaitForSingleObject (internal, (timeOutMillisecs < 0) ? INFINITE : timeOutMillisecs)
== WAIT_TIMEOUT)
{
ReleaseMutex (internal);
CloseHandle (internal);
internal = 0;
}
}
}
return (internal != 0);
}
void InterProcessLock::exit()
{
if (--reentrancyLevel == 0 && internal != 0)
{
ReleaseMutex (internal);
CloseHandle (internal);
internal = 0;
}
}
END_JUCE_NAMESPACE

+ 3536
- 0
build/win32/platform_specific_code/juce_win32_Windowing.cpp
File diff suppressed because it is too large
View File


+ 76
- 0
build/win32/platform_specific_code/win32_headers.h View File

@@ -0,0 +1,76 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#ifndef __WIN32_HEADERS_JUCEHEADER__
#define __WIN32_HEADERS_JUCEHEADER__
#include "../../../juce_Config.h"
#define STRICT
#define WIN32_LEAN_AND_MEAN
// don't want to get told about microsoft's mistakes..
#ifdef _MSC_VER
#pragma warning (push)
#pragma warning (disable : 4100 4201)
#endif
// use Platform SDK as win2000 unless this is disabled
#ifndef DISABLE_TRANSPARENT_WINDOWS
#define _WIN32_WINNT 0x0500
#endif
#include <windows.h>
#include <commdlg.h>
#include <shellapi.h>
#include <mmsystem.h>
#include <vfw.h>
#include <tchar.h>
#undef PACKED
#ifdef _MSC_VER
#pragma warning (pop)
#endif
//==============================================================================
// helpers for dynamically loading unicode functions..
#define UNICODE_FUNCTION(functionName, returnType, params) \
typedef returnType (WINAPI *type##functionName) params; \
static type##functionName w##functionName = 0;
#define UNICODE_FUNCTION_LOAD(functionName) \
w##functionName = (type##functionName) GetProcAddress (h, #functionName); \
jassert (w##functionName != 0); \
#endif // __WIN32_HEADERS_JUCEHEADER__

+ 2901
- 0
build/win32/vc6/JUCE.dsp
File diff suppressed because it is too large
View File


+ 6086
- 0
build/win32/vc8/JUCE.vcproj
File diff suppressed because it is too large
View File


+ 683
- 0
docs/JUCE changelist.txt View File

@@ -0,0 +1,683 @@

==============================================================================

JUCE version 1.44

==============================================================================
Changelist for version 1.44

- changed the MouseEvent structure so that it now contains a pointer to the event component and also the original component.
- added a PopupMenu::dismissAllActiveMenus() method
- added the JUCE_LOG_ASSERTIONS flag, which can automatically log assertion failures, even in release builds


==============================================================================
Changelist for version 1.43

- I've done a bit of tidying up of the juce tree, moving things like the demo, the jucer, etc into a folder called "extras", and this also now includes the audio plugin code and BinaryBuilder, rather than having those available as separate downloads.
- native menu bar support for the Mac! See MenuBarModel::setMacMainMenu().
- a few changes to the MenuBarModel class and MenuBarComponent - the model object now has listeners, and when a menu changes, you should call MenuBarModel::menuItemsChanged() rather than calling the old equivalent method on the bar component. Also, the MenuBarModel virtual methods have changed slightly and no longer have a menu bar component as one of their parameters. One other related change is that DocumentWindow::setMenuBar() no longer takes a command manager - you should register the command manager directly using MenuBarModel::setApplicationCommandManagerToWatch
- horizontal mouse-wheel support - this involves a change to the Component::mouseWheelMove method, to add an extra parameter. If you've got existing code that uses the old form of this method, it should fail to compile with an error, and you just need to tweak it to add the new parameter
- sorted out some problems with the jucer's colour swatch menus
- fixes for AudioDeviceManager forgetting channel selection
- added a textCharacter member to the KeyPress class - this allows a unicode printing character to be stored separately from the keycode.
- added support for extra numeric keypad keys like add, subtract etc, and F13-F16
- added a radio group ID field to buttons in the jucer
- renamed TaskbarIconComponent as SystemTrayIconComponent to make it more obvious what it does, and added support for tray icons on linux (thanks to kraken for the code for that one)
- new class: ChannelRemappingAudioSource, which lets you take a source and remap its input and output channels.
- some tweaks to the Time functions on win32 to make them slightly more efficient
- new method: Slider::setIncDecButtonsDraggable(), which adds a hybrid click/drag mode to the inc/dec button slider
- added some linux-specific methods for creating new midi in/out devices (ta to kraken)

==============================================================================
Changelist for version 1.42

- jucer: fix for crash when trying to add items to a button
- optimisation for UndoManager when there's a lot of items
- added multiple file selection as an option for the FileChooser (using native dialogs, not yet juce file browsers)
- added some colour IDs for rotary slider colours
- new method: PopupMenu::addSectionHeader()
- tweaked the way that options are passed to the PropertiesFile constructor, and added an option to save the file as XML.
- new method: Slider::setSkewFactorFromMidPoint()
- jucer: added an option to specify a virtual parent class for components, so that you can edit a component of your own class using a built-in type (e.g. edit your own slider subclass using the slider class). Thanks to kraken for this idea.
- plugins: added support for current-program-only settings to be saved for VSTs
- changes to the way events are dispatched on the mac, to make use of mouse-tracking. This was necessary to avoid problems embedding HIViews in juce windows, and hopefully shouldn't cause any problems anywhere else in the code
- altered the way Files are stored internally to avoid ambiguity between "/" (on mac/linux) and File::nonexistent. Previously all files were stored without a trailing slash, but now in the case of the root dir, the slash is kept.

==============================================================================
Changelist for version 1.41

- handy new macro: numElementsInArray()
- improved menu highlighting of custom menu components
- win32 windowing changes to avoid problems with plugins messing up their host's keyboard accelerators
- new class: ApplicationProperties - this is a handy singleton for managing PropertyFile objects when you need both user-specific settings and settings that are common to all users of a machine
- extra options for PopupMenu to allow more control over the width and number of columns used. Note that there's a small change to the prototype of LookAndFeel::getIdealPopupMenuItemSize, in case you've overridden this in your code
- for consistency, changed the ComboBox to use a normal menu as its popup component, instead of the slightly-different component it had been using. This also involved ditching a load of LookAndFeel methods that were for drawing the old popup.
- the FLAC and Ogg-Vorbis libraries are now embedded and integrated into the juce build. Previously these could only be used if you linked to their library files, which needed building separately, but now it all just works without any external dependencies.
- tweaked the AudioDeviceSelectorComponent to give more flexible control over which channels are enabled in a multi-channel soundcard
- Linux + Mac: added a sockets-based HTTP stream class, so that linux now has this functionality. On the Mac, this replaces the old version which used deprecated OS functions (and which kept randomly crashing deep inside Apple's HTTP code)
- altered the AudioFormat::createWriterFor method to take an OutputStream rather than a FileOutputStream - if you've written a custom AudioFormat you'll have to tweak your method prototypes
- more efficient zip file parsing
- renamed MemoryBlock::to64BitEncoding and MemoryBlock::from64BitEncoding because they're a misnomer, and I must have been a bit muddled when I wrote those. They're now called toBase64Encoding and fromBase64Encoding.
- new methods: String::indexOfAnyOf and lastIndexOfAnyOf
- changes to the prototype of File::findChildFiles, DirectoryIterator, and a couple of other related methods, so that you can use an enum to specify whether to search for files, directories, or both.
- added some methods to ListBox and TableListBox to return the position of rows and cells
- added a method to allow easy drag-and-dropping of treeview items
- added support for the numeric keypad in KeyPress
- added methods to create custom buttons in TabbedComponents, and to save/restore the scroll position of a ListBox
- fixed whitespace display in a password textbox
- jucer: a very useful change allows each co-ordinate of a component to now be made relative to another component instead of the parent, allowing some complex layout behaviour.
- linux: added support for dealing with drag-and-dropped files (thanks to kraken for the code behind that one!)

==============================================================================
Changelist for version 1.40

- Audio Plugins: added an initial release of an RTAS wrapper!
- new classes: IIRFilter and IIRFilterAudioSource
- changed the Synthesiser to use reference counting for SynthesiserSound objects, so that sounds can be allowed to play on after being removed.
- added some colour options to the GroupComponent and Toolbar classes
- added a mouse-sensitivity setting to sliders
- Linux: added support for XShm, which uses shared memory to improve rendering speed
- Added a new method File::getSpecialLocation(), which lets you find out various system paths, e.g. home folders, documents folders, etc. This replaces a bunch of existing static method calls in SystemStats.
- Added a TableListBoxModel::getDragSourceDescription() method to allow easier dragging of table rows
- Added an option to PropertiesFile for creating files that are common to all users. Also tweaked a couple of methods in this class.
- Mac: added a PlatformUtilities method to convert unicode strings to their precomposed form, and used this in lots of file handling routines to avoid mix-ups between encodings of extended characters.
- Altered the directory search code to optimise fetching of file attributes - this should help when browsing directories on slower network drives
- couple of small fixes for TableHeaderComponent in stretch-to-fit mode
- added a new virtual method to OpenGLComponent to provide a callback for setting-up a new GL context
- some improvements to the AudioDeviceManager to make it do a better job of saving and restoring its state
- Jucer: some fixes for embedded jucer components
- changed the PNG loading code to correctly handle interlaced PNG formats
- added methods to convert a Path into a simple string of co-ordinates that can be reloaded. Also added a button to the font demo to turn glyphs into these strings
- added a multi-select option flag to treeviews
- mac + linux: implemented the InterProcessLock class
- fixed DirectSound handling of unicode driver names

==============================================================================
Changelist for version 1.39

- change to the way Components and LookAndFeel objects handle colour. Preset colours are now identified by a unique ID number, and can be retrieved or set either for the lookandfeel object or overridden for an individual component. See the new Component::findColour and LookAndFeel::findColour methods for more info on this.
- new classes: SamplerSound and SamplerVoice, which are used with the Symthesiser class to form a very simple sampler. I've added an example of this to the audio demo.
- some Win32 changes to enable window maximising via the native system menu
- added an option to the Slider class for showing min/max values
- added ALSA midi output support for Linux
- support for Linux displays with only 16-bit colour, and fixes for handling of exteneded keycode input
- added some more string constructors, for creating strings from unsigned integers as well as signed ones
- new class: ComponentMovementWatcher, for keeping track of movements of deeply nested components (probably quite esoteric, but needed for things like OpenGL and ActiveX windows)
- Jucer: made references to embedded jucer files use relative pathnames rather than absolute, so directories of jucer files can be moved easily without breaking links
- Jucer: added constructor parameters properties for the components inside tabbed components, viewports and jucer components.
- Jucer: SVG files can now be dropped in as image resources
- changed the ApplicationCommandManager::getFirstCommandTarget() method to add a command ID parameter
- MemoryBlock::to64BitEncoding now returns a string rather than taking a dest string parameter
- tweaked the ImageCache class to use 64-bit hash-codes
- Plugin toolkit: added a class StandAloneFilterWindow, which is a window object you can use to build a plugin as a standalone app

==============================================================================
Changelist for version 1.38

- Windows: mouse cursors and taskbar icons now use a full 8-bit alpha channel when running on WinXP
- Fixed some SVG bugs and made the parser more efficient
- got rid of the Component::setDragRepeatInterval() method and replaced it with a static method beginDragAutoRepeat(). This makes it easier for a parent component to enable auto-repeat when its children are clicked.
- bugfixes for some keyboard codes on Windows, RelativeTime rounding accuracy, Linux opengl repainting, mac window repainting, BWAV history chunk parsing, Table components, Mac fonts, Mac CoreAudio built-in device pairing, nested modal state return values, full-screen windows using native title bars, linux filenames with extended character sets.
- Windows: updated the network MAC address function, which wasn't correctly finding all network cards on some systems
- changes to allow a 64-bit build on Windows, including greater use of compiler intrinsics
- two new header files: juce_WithoutMacros.h and juce_DefineMacros.h (in the juce/src directory) - these make it easy to include juce.h without it defining macros that may conflict with other 3rd party header files. See the comments in these files for more info.
- tidied up the SystemStats operating system detection detection, to use an enum instead of strings, added Windows Vista detection, and renamed some of the methods. If you use these, you'll probably have to change the method you're calling, but it's not difficult.
- added an option to TreeView to set the indent size
- updated the build instructions for Windows compilers

==============================================================================
Changelist for version 1.37

- new classes: Toolbar and a bunch of related classes. For creating and dynamically customising toolbars.
- new class: ComponentAnimator, which will move and resize components to new positions, taking a specified length of time to get there. There's a button to demonstrate this in the jucedemo widgets section, on the buttons page
- new class: MultiTimer, which is like a Timer, but allows multiple independent timers with different frequencies to share a callback
- fixed a few bugs in the SVG parser and a gradient-rendering bug, and added an SVG object to the "paths + transforms" demo page
- added some assertions to warn people about adding components directly to a ResizableWindow rather than using setContentComponent()
- to improve performance of the ElementComparator class, I've changed the sort routines to use a templated class rather than a virtual method. If this breaks your code, all you need to do is to no longer derive your class from ElementComparator and everything else should continue to work as normal.
- finished off the ThreadPool class, and souped-up the threading page of the demo app to show how to use it.
- added some static methods to Drawable to automatically load Drawables from some kind of image or SVG file
- fixes for some Mac VST and AU windowing bugs
- new method Component::canModalEventBeSentToComponent(), which allows a modal component to selectively allow events to reach components that it is blocking
- fixed deprecated function warnings in MSVC8
- all projects and solutions are now compatible with MS Visual Studio 2005 - I've renamed some of the vcexpress directories to "vc7", and the projects in them will load with either VCexpress or VC8
- updated the "hello world" projects to use a document window
- altered the AudioFileFormat::createReaderFor() method to specify whether the input stream should be preserved if opening fails

==============================================================================
Changelist for version 1.36

- Windows: ActiveXComponents (and QuickTime components) now get told about any mouse events that happen inside the control
- Graphics::saveState() now saves the colour and brush as well as the clip region and origin
- SimpleListBox now prevents mouse clicks from getting sent to the list if the component is disabled
- new classes: TableListBox, TableHeaderComponent - these are for creating table components with column headings that can be re-ordered, resized, etc. I've added a table demo to the juce demo to show how to use it, and the Jucer's resources panel also now uses a stretch-to-fit table.
- removed class SimpleListBox: I've got rid of the separate SimpleListBox class, and merged its functionality with ListBox. If you're currently using a SimpleListBox, the only change you should need to make is to replace "SimpleListBox" in your code with "ListBox".
- Changes to ListBox: if you're using a ListBox with custom row components, you'll need to change your class to also derive from ListBoxModel, and make sure you call ListBox::setModel() to make it use your model class. Then you'll need to replace the old createRowComponent() and updateRowComponent() methods with the new refreshComponentForRow() method.
- new handy macro: forEachXmlChildElement, which is a neat way of iterating the child elements of an XmlElement
- new class: StretchableObjectResizer, which is for calculating how to fit a set of resizable items into a given space
- new class: TaskbarIconComponent, on Windows only, this lets you show an icon in the system tray.
- fixes for using a DLL build on Windows - I've moved all the allocators into the juce DLL, so this should now work ok
- added a bit of SSE optimisation in the graphics rendering code (just for blending large blocks of solid colour)

==============================================================================
Changelist for version 1.35

- added a simple SVG parser to the Drawable class - this can parse SVG into a graph of Drawable objects that you can then render. The parser's pretty basic, and doesn't support much of the (very large) SVG spec, but I'll keep adding features to it as they're needed
- fixed the updating of ToggleButtons that are connected to app commands so that they correctly reflect the command's 'ticked' state.
- fixed the XML parser's handling of non-text element entities
- added a few handy static methods to AffineTransform
- gradient fills can now have a transform matrix specified, to deform their shape
- new class: RectanglePlacement, which is a bit like Justification, but specifically for fitting rectangular graphics within a viewport with various positioning options. This will break a few places where you call methods like drawImageWithin(), but is easy to update and the result is more readable code.
- new method Colours::findColourForName() for looking up colour names from a string
- added a flag to ApplicationCommandInfo to stop menus and buttons getting flashed when particular commands are invoked
- new class: CharacterFunctions, which contains a set of static functions for manipulating ascii and unicode characters and null-terminated strings. This is intended to replace any use of functions like strlen, etc, with a set of safe, platform-independent ones.
- some fixes and optimisations to the file chooser components
- altered the Graphics and LowLevelGraphicsContext classes to use a stack for pushing and popping the clip regions, instead of setting these explicitly with a RectangleList. (This change is needed for future support of OS contexts that can't retrieve the clip path as a set of rectangles)
- removed the Graphics class's copy constructor (use the saveState/restoreState methods instead of a temporary copy)
- added method String::indexOfWholeWord()
- tidied up some of the header files, moving all inline functions (like jlimit, jmax, etc) into the juce namespace
- Mac: complete rewite of the windowing code. Components are now placed in HIViews, rather than directly in Windows. As well as being more futureproof, this is vital for support of AudioUnits and VSTs on Intel Macs.
- Mac: tidied up the build environment. It now compiles a universal binary which is compatible with any system from 10.2 onwards, including intel on 10.4
- Windows: new ActiveXControlComponent class, which lets you embed an ActiveX control in a Juce window. I wrote this to get the new Quicktime control working, but made it generic so you could use it for other things like embedding a web browser, etc.
- Windows: completely rewritten Quicktime support. This now requires QT7 (on windows, not Mac), but it now uses the new ActiveX QT control, which is much better than the archaic way it used to be done. Would like to update the Mac version too, but that'd only work on 10.4, so will wait until older OS versions are less common.
- Windows: fixes for non-western keyboard input sometimes not working in textboxes
- Linux: added a MIDI input device, using ALSA
- Linux: made launching of URLs in the default browser work properly
- Jucer: added an option to view a semi-transparent overlay of the components while editing the background graphics
- Jucer: better positioning of new objects when zoomed-in
- Jucer: added a "common background" graphics layer to buttons, which is drawn behind all the other button states
- Jucer: added key shortcuts for nudging component's position and size around
- JuceAudioPlugin: rewrote the mac VST and AU wrappers to embed a HIView rather than the old window hackery it was using.

==============================================================================
Changelist for version 1.34

- a bunch of changes to continue improving the expressiveness and consistency of listener classes, (and moving away from generic listeners like ChangeListener):
- new class: LabelListener class now replaces Label's use of ChangeListeners
- new class: ComboBoxListener for ComboBoxes, replacing the old use of ActionListener
- new class: ScrollBarListener for ScrollBars, replacing the old use of ChangeListener
- new class: KeyboardFocusTraverser, to take the logic of keyboard focus traversal out of the component class.
- removed the Component::setFocusOrder method - instead, a KeyboardFocusTraverser object now decides the focus order (and can be overridden to support custom behaviours)
- new class: ApplicationCommandManagerListener - this is used to listen for commands being invoked, and for changes to the status of commands. The Button class now uses this so that when a button is linked to a command, it enables itself only when the command is active, and flashes when it's invoked.
- new class: FocusChangeListener - this can be registered with the Desktop class to receive callbacks whenever the focused component changes
- new class: FilenameComponentListener - for getting events from FilenameComponents, replacing the use of ActionListener
- new class: BooleanPropertyComponent - a property component with a toggle button in it
- some fixes to DLL builds on windows
- couple of additions to the MidiKeyboardComponent class
- fix for large menus not scrolling correctly
- got rid of Component::getMouseX() and getMouseY() - this functionality is already available in Desktop::getMousePosition(), so not needed here as well
- replaced the Component::getMouseXRelative() and getMouseYRelative() method with a single method getMouseXYRelative() that returns both co-ordinates at once (this is a more efficient way of doing things)
- added new methods Component::relativePositionToGlobal, globalPositionToRelative and relativePositionToOtherComponent for converting co-ordinates to and from screen co-ords. These replace the old getXRelativeTo() method.
- new class: MagnifierComponent, which magnifies or shrinks any component that you put inside it
- added colour swatches to the ColourSelectorComponent
- Jucer: literal text strings can now contain special strings which are treated as c++ code - anything inside a pair of %% characters counts as c++, so %%getName()%% gets translated into the name of the component; %%getButtonText()%% into getButtonText(), and these are concatenated with the rest of the string.
- Jucer: Button documents now have a list of the various over/down/toggled states for which you want to design paint routines, and any combination of these can be enabled
- Jucer: you can now drag-and-drop a Jucer .cpp file into a component's layout window, and it will add it as a Jucer component
- Jucer: highlighted object borders can now go beyond the edges of the component, making it easier to edit comps that are slightly off-screen or aligned with the edges of the parent comp
- Jucer: new command to bring any items that are off the edges of the screen back into the middle
- Jucer: ComboBoxes and Labels now create callback methods
- Jucer: Zoom mode! As well as the zoom in/out commands on the menus and keyboard, you can use the mouse-wheel with ctrl or alt held down to zoom.
- Jucer: Holding down the space bar now lets you scroll around the component
- Jucer: ability to group paint elements together to treat them as a single entity

==============================================================================
Changelist for version 1.33

- fixed some graphics error with path strokes, and optimised the stroke creation code
- improved the ellipse and rounded rectangle path routines by using cubic approximations
- couple of extra methods for the AsyncUpdater class
- changed sliders so that they now use a SliderListener class to receive callbacks instead of using ChangeListeners
- Jucer: lots and lots of bugfixes
- Jucer: added options for converting text and other graphics elements into paths
- Jucer: Viewports can now have a content component specified, which may be a Jucer component
- Jucer: TabbedComponents can now be edited and have the contents of each tab specified
- Jucer: Added a list of extra callback methods that can be added to the code automatically
- Jucer: Added an option to images to change the stretch mode
- Jucer: Graphic objects can now use an ImageBrush for their fill or stroke
- Jucer: You can now drag-and-drop image files onto the graphics element editor page
- Jucer: Added a tooltip property to those components that implement the SettableTooltipClient interface
- Jucer: Gave it an icon
- Jucer: Sliders now create a SliderListener callback

==============================================================================
Changelist for version 1.32

- Jucer: added undo/redo support!
- Jucer: restructured most of the project, adding support for documents of different types, so now it can create either normal components, or buttons with normal/over/down graphics. More document types can be added in future
- Jucer: added a VC6 project, and fixed some things that didn't build because of VC6 compiler bugs
- Jucer: holding down shift when resizing things now fixes the aspect ratio
- Jucer: holding down ctrl when dragging disables/enables grid-snapping
- added a couple of options to MultiDocumentPanel
- fixed a graphics bug with thick path strokes not being created correctly
- mac: managed to stop it repainting windows unnecessarily while dragging them around

==============================================================================
Changelist for version 1.31

- First release of the Jucer! This is a component development tool that lets you design Juce components and produces c++ code. This initial release is functional but still a work-in-progress - it will be an ongoing project, adding more and more functionality and shortcuts for creating juce-based code. The Jucer source code lives inside the Juce tree, in the juce/jucer folder.
- new class: PositionedRectangle, which specifies a rectangle using either absolute or proportional co-ordinates, and giving flexible control over the anchor points used. Handy for positioning components.
- new set of classes: PropertyComponent, PropertyPanel and various basic subclasses of PropertyComponent. These allow you to quickly set up a properties panel for something, e.g. a selected object, which shows a list of named properties of various types, e.g. text, sliders, combo boxes, etc.
- added a method ApplicationCommandManager::setFirstCommandTarget() to make it easier to set up non-component command targets
- change to the FileBasedDocument load/save methods so that they can return an error message on failure
- new method: Graphics::fillCheckerBoard()
- added options to FileChooser and FileChooserDialogBox to prompt the user about overwriting files that already exist
- change to TabbedComponent, so that instead of using a virtual method to create the components for the tabs, you add components using the addTab method and the TabbedComponent looks after them for you.
- fixes to some focus issues, such as popup menus temporarily moving focus away from the main window
- new class: MultiDocumentPanel to hold multiple document windows as either floating DocumentWindows or in a TabbedComponent.

==============================================================================
Changelist for version 1.30

- major set of new classes to introduce "application commands". This is a powerful mechanism for despatching commands to command targets. It allows commands to be bound to keystrokes and easily triggered by menus, buttons, etc. New classes to support this include ApplicationCommandManager, ApplicationCommandTarget, ApplicationCommandInfo. I've rewritten the Juce demo to use commands to control its menu system, and added key-shortcuts to select the various demos.
- the new app command stuff replaces a lot of the functionality that was in KeyPressMappingSet, so this class has been slimmed down with some functionality moving into the new classes. I've renamed the createXml() and restoreFromXml() methods to draw attention to the slight difference in the way they're used, (and to make the names more consistent with other code)
- new class SettableTooltipClient, and made a lot of the existing widgets inherit from this, to make it easy to set tooltips for them
- new flag in the Justification class - horizontallyJustified, which spreads text out to align both its left and right margins
- tidied up the Uuid class and got rid of any platform-dependent libraries it was using
- the constructor for the Thread class now takes a name, and on windows this gets passed to the debugger to make it easy to see which thread is which. (Haven't got mac or linux implementations for this yet)
- some UI fixes for running under KDE on Linux
- added a File::areFileNamesCaseSensitive() method
- added a method to the MidiInputCallback class to handle incoming sections of a long sysex message. (This is only currently supported on the mac)
- the XML parser now loads extended UTF-8 characters correctly

==============================================================================
Changelist for version 1.29

- moved the Juce demo app into the main Juce tree, to make it all easier to download
- added classes for FLAC and Ogg-Vorbis audio formats
- added support for native window title bars and borders
- moved the window style flag enum out of Component and into ComponentPeer, adding lots of new flags.
- changed some of the methods in ComponentBoundsConstrainer so it'd work with the new windowing stuff
- couple of minor fixes to named pipes on windows
- some Quicktime component fixes and optimisations
- changed the AudioFormat class to allow multiple file extensions, and added a method AudioFormatManager::getWildcardForAllFormats() to make it easy to show browsers for audio files
- on OSX, added a juce.xcconfig file to the XCode build, to make it easier to select whether to build for gcc3 or 4
- made the TabBarButton class public to allow customised tab bar components
- changed the default font on OSX from Verdana to Lucida Grande, as Verdana isn't actually guaranteed to be installed on all systems

==============================================================================
Changelist for version 1.28

- Cleaned up the audio device driver architecture, adding an AudioIODeviceType class to represent the different types, (e.g. DSound, ASIO, CoreAudio, ALSA, etc). The AudioIODevice class is now an abstract base class, and instances can only be created by using an AudioIODeviceType object. This means that user code no longer needs to care whether support for ASIO is enabled or not.
- Fixes to the ReadWriteLock class
- Couple of bugfixes to stop older VC7 compilers complaining
- Finally found a way of making the windows come to the front correctly under Gnome on Linux
- Fixed a linux mouse focus bug that messed up menus
- New class: Socket, which is.. you guessed it.. a socket.
- New class: NamedPipe, which is, unsurprisingly, a named pipe, for interprocess comms.
- new class: InterprocessConnection, which manages a simple two-way socket or pipe-based message passing connection to another process or machine on the network.
- Added a new interprocess comms page to the demo, to demonstrate InterprocessConnections.
- Improvements to repaint speed on win32 when there are complex repaint regions
- Fix for a mac windowing bug that stopped modal windows coming to the front correctly

==============================================================================
Changelist for version 1.27

- lots of new file selector classes: DirectoryContentsList, FileListComponent, FileChooserDialogBox, FileBrowserComponent, FileFilter, etc. These can be used either as separate components or as a ready-made dialog box file chooser, which means that the Linux build finally has a file chooser!
- jazzed-up the colour selector to give more control over how it looks
- added a simple pattern match (for matching filenames, mainly) to the String class
- fixes to avoid problems with drifting clocks on the new dual-core intel cpus
- added UTF-8 conversion methods to the String class
- made PropertiesFile support unicode strings
- new class: BorderSize, which is used to represent the gaps around things - I've changed a few methods in classes like LookAndFeel, ResizableWindow, Component to use this instead of specifying the gaps manually, which was a bit messy.
- new class: AudioDataConverters, which contains methods for converting floating point audio to various integer formats
- new static_jassert macro for doing compile-time assertions
- fixes for mac MidiInput with certain drivers
- tidied up the MemoryBlock class and got rid of its virtual base class to make it quicker. Also dumped the AlignedMemoryBlock class: if anyone wants it back, let me know and I'll do a new version!
- optimised repainting for cases where there are a lot of deeply-nested components
- tweak to the broadcast message code on win32 to avoid deadlocks
- fixes for GCC4.0 optimised build under linux - the crashes here were due to strict aliasing in some numeric conversion functions. I've been through and made them more complient now.

==============================================================================
Changelist for version 1.26

- Linux audio support using ALSA! This is a first stab at an implementation, so I've only had chance to try it on one soundcard - linux audio experts, please let me know what I've done wrong!
- Restructured the way components are housed in windows, getting rid of NativeDesktopWindow and instead having a ComponentPeer base class, of which there may be more than one implementation. (This won't make any difference to most people, only power-users)
- Graphics contexts now work with a RectangleList as their clip region, instead of just a single rectangle
- added some methods to Desktop to access a list of top-level desktop components
- fixes and improvements to TextEditor, improving its handling of word-wrapping
- added a QuickTime page and an audio input monitor to the demo app.

==============================================================================
Changelist for version 1.25

- new class: TopLevelWindow to handle the concept of "active" windows
- new class: MidiMessageCollector helper for realtime midi input, and created a midi folder to tidy up the directory structure of the midi classes.
- added a JUCE_CATCH_UNHANDLED_EXCEPTIONS config to turn off the juce exception logging
- renamed JUCEApplication::getApplicationInstance() to JUCEApplication::getInstance(), for consistency with all the other singletons. Sorry for the hassle, but it's easy to find-and-replace it in your code.
- finished keyboard navigation for menu bars
- new class: Synthesiser, which is an abstract base class for multitimbral synths. Also added one of these to the audio page of the Juce demo
- TreeViews now have an extra item width parameter for each item, and horizontal scrollbars if items are too wide to fit on screen.

==============================================================================
Changelist for version 1.24

- more flexible gradient control, allowing sequences of colours
- new class: DocumentWindow, which is a resizable window with a titlebar, nice-looking maximise/minimise/close buttons, a menubar, and lots of cool options.
- improved the ability for ResizableWindows to be used as child components as well as on the desktop, without them losing their drop-shadows
- eye-candy changes to ShinyLookAndFeel, adding glassy-looking buttons
- added a JUCE_VERSION macro to allow conditional builds against different juce versions
- added an option to PopupMenu that allows any component to be easily added as a custom component, rather than only ones derived from PopupMenuCustomComponent.
- made the win32 crt memory debugging overrides conditional with JUCE_CHECK_MEMORY_LEAKS macro in juce_Config.h
- new class: LassoComponent for easy lassoing of groups of UI objects
- additions to SelectedItemSet to improve the logic used when multi-selecting items that might be dragged.
- handy new method: File::replaceWithText()
- new class: RecentlyOpenedFilesList
- updated some crt function names for compatibility with the latest msvc pro
- misc fixes to glyph layout, text editor listener callbacks + lots of other things.
- new class: ComponentBoundsConstrainer for more flexible control over resizing and dragging components around. This replaces the ResizableBase class.
- popup menus now accept keyboard navigation (not done this for jumping between them on menubars yet, though)

==============================================================================
Changelist for version 1.23

- new class AudioDeviceManager - this makes it super-easy for audio applications to manage the user's choice of audio and midi devices, and to save and load the user's audio settings.
- new class AudioDeviceSelectorComponent - goes with the AudioDeviceManager to make it easy to let the user change the audio settings. I've also updated the JuceDemo audio section to use these new features.
- fix to ProgressBar
- a few graphics rendering fixes, and some optimisations for pixel blending operations
- change to AudioIODeviceCallback class to add methods to tell the callback when the device starts and stops
- small tweak to AudioSourcePlayer now that it no longer needs to be told the sample rate and buffer size
- a few more tweaks for 64-bit compatibility on linux
- added a checkNewSize() method to ResizableBase and ResizableWindow to allow custom resize constraints.
- fix for a mac midi input bug that could freeze the system when malformed midi packets arrive
- optional drop-shadows on menus via the LookAndFeel class

==============================================================================
Changelist for version 1.22

- new class: AudioFormatManager
- removed any dependencies on DSound.h or DSound.lib so Juce can be built with the latest Platform SDK without needing the DX SDK as well.
- fixed a mac drag-and-drop bug
- made drop-shadows optional for alert boxes + splash screens
- added some fixes for compiling on gcc4.0.2 in mandriva linux
- big restructuring of the graphics code to make it ready for adding OS or hardware-accelerated UI rendering. In its current state it should be pretty much the same speed as before, but I've moved all the software rendering into one class. Small changes to the Image class mean that you can no longer get a pointer to its pixels, you need to lock and unlock a section of the image, so that this will also work in future for images that aren't kept in main memory.

==============================================================================
Changelist for version 1.21

- new class: MidiBuffer - an efficient array of midi messages for use in audio filters
- new class: MidiKeyboardComponent - a UI comp that shows a piano keyboard and has lots of groovy features
- additions to DragAndDropContainer to allow files to be dragged to external applications
- fix to Array::move()
- added a couple of accessor methods to TreeViewItem
- changed the colour selector component to make the alpha-channel optional
- fixed a layout bug with some tooltips
- fixes to the AIFF file format handler
- efficiency improvements to the Timer class
- add a Component::visibilityChanged() callback method
- added file and line info to the internal exception handling code
- linux window focus bugfix

==============================================================================
Changelist for version 1.20

- changes to support the latest XCode 2.2 on the Mac, and some changes ready for Intel-based macs
- changes to support the latest version of VSExpress
- optimisations to DirectoryIterator - should make it much faster when scanning slow disks
- optimised the way Timers are triggered
- mac fixes for repainting transparent windows on 10.4
- some tweaks necessary for AudioUnit support

==============================================================================
Changelist for version 1.19

- added some more translation macros for various strings that were missing
- translation files can now contain escaped characters, e.g. "\t" or "\n"
- added a method to the QuickTimeMovieComponent to manually unload QT, as the automatic method it was using could interfere with other uses of QT in your app
- on the mac, minimising windows now animates and properly minimises them rather than just hiding them
- on the mac, hide/show application now works correctly
- small fix to ComboBox/FilenameComponent
- updated to include the latest versions of all 3rd party libraries - i.e. libjpeg, libpng and zlib, so lots of speed and security improvements there
- added ImageFileFormat::writeImageToStream() method, currently supporting writing of JPEG and PNG files
- fixed a bug in PopupMenus with a large number of items on them
- fixed a mac audio cd reading bug that could mix up the track order
- option for ComponentDragger to keep the entire thing on-screen

==============================================================================
Changelist for version 1.18

- fixes to the audio resampler, and also to some looping bugs in the audio sources
- ComboBox::getSelectedId() was returning -1 if nothing was selected - changes this to be 0 instead, (it should always have been 0, as item IDs must be non-zero, but -1 is a valid ID)
- added a tryEnter() method to CriticalSection
- some tweaks to DirectSound support to allow the names of input devices to be used as well as those of output devices
- got rid of deprecated calls to strcpy
- a few fixes for gcc4.0 compatibility on linux
- new instructions for linking to the library in XCode

==============================================================================
Changelist for version 1.17

- fixes for the Mac in string parsing and windowing
- fix for initial folder in the directory chooser on windows
- better unicode font name handling for winXP
- added some code for handling uncaught exceptions on the message thread
- made the DialogWindow::closeButtonPressed a pure virtual to force subclasses to handle it properly
- fixes for some keypresses that didn't work on foreign keyboards on the mac

==============================================================================
Changelist for version 1.16

- added some methods to the ComboBox class to allow it to have disabled items in its drop-down list, and also to have separator lines and subheadings for different sections.
- new class: ToneGeneratorAudioSource
- more bugfixes for win98 support, XML, unicode, etc.
- on the mac, added DEBUG macros to the project, as these weren't being properly set up before and assertions were left in the release build
- on the mac, the project now creates two separate lib files for release and debug: libjuce.a and libjucedebug.a. Unfortunately there's no obvious way of making an app link to the correct one depending on whether you're doing a debug build, so you'll need to manually set the one you want in your project.
- on linux, fixed up a SUPPORT_AFFINITIES macro because some distros have obsolete APIs that won't compile the cpu affinity code
- methods to add XML elements to a PropertySet

==============================================================================
Changelist for version 1.15

- got rid of the separate unicode/ansi builds, deleted juce_unicode.h and introduced a JUCE_STRINGS_USE_UNICODE macro which is defined in juce_Config.h. This is now turned on by default, so if there's some reason why you don't want your app to use unicode, you'll need to opt-out by disabling the macro.
- a bunch of unicode fixes and tweaks
- changed the method KeyPressMappingSet::isSafeToInvokeCallbacks() into isSafeToInvokeCommand() so it can choose whether particular commands are safe to run
- added an option to the ResizableBorderComponent and ResizableCornerComponent so that they can enforce a fixed aspect ratio
- new helper method for logging: FileLogger::createDefaultAppLogger()
- new class ResizableBase, as a base class for various resizable components
- various win98 fixes
- made the name of the juce namespace optional
- added methods Rectangle::toString() and fromString() to save/load rectangles easily
- fixed a stupid bug in FilenameComponent
- fixed mac file handling to fully support unicode filenames
- added drag-and-drop functionality to SimpleListBox, with helper methods in ListBox and also a few tweaks to DragAndDropContainer to help it deal with drag sources that are different from the component currently under the mouse. Also updated the demo drag-and-drop to use a listbox.
- various mac UI fixes, including some focus gain/loss improvements
- fixed the Dev-Cpp build, and added a Dev-Cpp project for building the demo app

==============================================================================
Changelist for version 1.14

- tweaks to ComboBox to make it look and work better, and also to give control over the text justification
- buttons and menu items can now be linked to a command in a KeyPressMappingSet, to trigger commands automatically
- change to Buttons - rather than using an ActionListener, buttons now use a special ButtonListener to respond to callbacks. This allows for up/down messages as well as clicks, and provides a pointer to the button that triggered the event. You might have to alter a few of your classes to deal with this - sorry! but it's not too difficult to change and it does make your code neater and more readable.
- Rewrote BubbleComponent to now be a base class for drawing arbitrary graphics inside a speech bubble shape. Created BubbleMessageComponent as a subclass for showing a text message in a bubble (like the old BubbleComponent used to do).
- Sliders now have an optional pop-up bubble that shows you their current value while they're being dragged. This is handy for sliders which don't have a text box. See Slider::setPopupDisplayEnabled()
- Sliders can now have a suffix which they append to the text string that they display, to make it easy to show units without having to write a subclass
- cosmetic improvements to combo-boxes, menus, textboxes, sliders, and a few other bits + pieces
- mouse events now have a click counter to detect triple and quadruple clicks, and the TextEditor uses these to select the current paragraph or entire document
- added methods to the Desktop class to allow "global" MouseListeners to be registered, that will be told about all mouse events to all components
- new classes : MenuBarComponent and MenuBarModel for doing menu bars (obviously). This is a lightweight menu bar component, not yet an OS-specific menubar, which I'll eventually implement on the Mac, but the same model will apply to both.
- A few 64-bit compatibility tweaks, and the MessageCallbackFunction definition (used in MessageManager::callFunctionOnMessageThread()) now returns a void* instead of an int. This shouldn't affect many people.
- new class: FileBasedDocument - writing all the load/save/save-as logic for documents is pretty tedious, so this handy base-class takes care of all that stuff for you, doing all the file dialog boxes and asking whether to overwrite existing files, etc.
- on Windows, you can now build juce as a DLL, and your app can link to the DLL version by simply defining the JUCE_DLL macro before including the juce headers

==============================================================================
Changelist for version 1.13

- tidied up the components directory, recategorising the components that were there and putting them into more appropriate folders
- new class: PreferencesPanel for doing mac-style prefs panels.
- improved the KeyMappingEditorComponent to use a treeview instead of a list, and to just look a bit nicer.
- added parameters to DrawableButton to allow it to show another set of images when used as a toggle button.
- changed DrawableText to use a GlyphArrangement. (Not sure why I didn't do that in the first place)
- new class: ColourGradient for specifying a colour gradient (obviously..)
- DrawablePath now uses a ColourGradient to specify its fill type
- tweaked DrawableButton to make it a bit more flexible
- slider thumb size can now be specified in the lookandfeel class
- sliders now hide the mouse when in velocity-sensitive mode
- completely all-new TabbedComponent class, bearing no resemblence to the old one. This one's much easier to use, has look-and-feel support and looks nicer. I've also split out a TabbedButtonBar class so you can just use the bar on its own, rather than using the TabbedComponent, which manages the whole panel.
- fixed a leak when using modal components
- added a new slider style: LinearBar, which is a left-right bar with the text label over the top
- new class: ProgressBar, and a demo of the ThreadWithProgressWindow class (in jucedemo, widgets page, click the "show a popup menu" and it's under "alert windows")
- more refactoring of the LookAndFeel class, in particular moving colours into the base class so you can create looks with customised colours without needing to override any functions
- added an extra clicked() method to buttons so you can handle right clicks and modifier keys
- added a text colour option to the TextButton
- on Linux, sorted out setting the mouse position and invisible mouse cursors

==============================================================================
Changelist for version 1.12

- fixes to OpenGLComponent to make it work when parent components are moved
- added a flag to allow building of non-GUI apps under linux where UI libraries aren't present
- popup menus can now be positioned to align with a button or other component
- created some static initialiseJuce() functions in juce_Initialisation.h, to make it easy to embed juce in command-line apps or apps that use their own event-loop.
- new class: GroupComponent for drawing a line around a group of components
- new sliders! Completely revamped the Slider class so that it can now do vertical and rotary sliders, as well as allowing user-defined scaling and snapping.
- updated the Mac projects for XCode 2.1 and fixed the GCC4 problems. Apple have just changed the project format for this release, so if you're still on XCode 2.0, then sorry, you'll need to upgrade to build this release.
- a couple of changes to Path to clean up the elliptic-arc and pie-shape drawing methods
- added a Path::addStar() method for drawing star shapes and addBubble() for drawing speech bubble shapes
- new class: ComponentDragger to easily add logic for dragging components around
- new class: ResizableBorderComponent for adding windows-style resizable edges to components
- name change: ResizerComponent is now called ResizableCornerComponent to complement ResizableBorderComponent
- new class: ResizableWindow to make it easy to create top-level windows that are resizable/maximisable, and to make it easy to save/restore their position and state. DialogWindow has also now been changed to use this as its base class.
- renamed method: UndoManager::clear() becomes UndoManager::clearUndoHistory() (just to disambiguate when subclasses are used)
- Component::setInterceptsMouseClicks() can now optionally intercept clicks on child components
- fixed a bug in Array::move
- new set of classes: Drawables - these are used to build up a tree of graphic elements that can be drawn, forming a complex image. So far there are coloured shapes, images and text, but there may be more to add in future. They also have a persistence mechanism so can be saved/loaded and used as a vector graphics format. Although the classes are quite basic at the moment, I might expand these one day to form a way of rendering SVG.
- changes to Buttons - moved all the toggle-button logic into the base class so that all buttons can now have an on/off state and belong to button groups. TextButtons and DrawableButtons use this to draw themselves in an on/off state, and the old ToggleButton class is still there for a tickbox-style toggle button.
- new button type: DrawableButton which takes some Drawables as its image and has a few different styles. This button will ultimately take over from ImageButton and ShapeButton.
- moved isEnabled()/setEnabled() into the Component base class, so that it now applies hierarchically. (previously the different widgets all had their own separate enablement methods)
- fixes and tweaks to the windowing system on Linux to hopefully make it run more happily on Gnome

==============================================================================
Changelist for version 1.11

- fix for some file methods that were failing to identify volume type correctly in OSX10.4
- rearranged the OpenGL code to move it into the platform-specific folders.
- added openGL support for Linux
- replaced many of the win32 native calls with dual unicode/ansi implementations, so the same code will run on win98 but take advantage of unicode on win2000/XP
- reorganised the String::getHexValue() methods into 32 and 64 bit versions
- new class: SelectedObjectSet - for managing multiply-selected items
- fixed some maths bugs with rendering certain types of gradient brush
- buttons that auto-repeat can now be made to speed up the auto-repeat frequency the longer they're held down
- scrollbars can now have their buttons hidden
- implemented the MD5Checksum class
- new class: PropertySet, which now forms the base class for PropertiesFile
- each Component now has a set of named properties associated with it, which can be inherited from its parent component
- handy new method: DialogWindow::centreAroundComponent()
- finished implementing the Primes class
- finished the RSAKey class, to provide RSA public/private key cryptography
- beefed up the BitArray class, giving it a sign, so it can be used as a large number class, and added some new methods (mostly because they were needed for cryptography)
- implemented the BlowFish class, which is a symmetric-key encryption algorithm
- new layout classes: StretchableLayoutManager and StretchableLayoutResizerBar - these are for creating all kinds of sets of nested components that stretch to fill the available space, with vertical or horizontal divider bars to rescale them. I've added some code to the fonts page of the demo app to demonstrate how to use them
- better makefiles for Linux, generated using premake
- added xinerama support for Linux

==============================================================================
Changelist for version 1.10

- initial rough release of the Linux build! This is only the first release, so there are still a lot of things missing (audio support, file browsers, etc) and it's bound to be a bit buggy, but the demo app works!
- new class: FilenameComponent
- new class: ReadWriteLock for allowing multiple-reader access to a critical section.
- new class: SplashScreen
- new class: LocalisedStrings, which lets you use a translation file in your app for multi-language support
- improved the sample-rate conversion algorithm in ResamplingAudioSource
- some tweaks to the win32 demo projects (rtti wasn't enabled)
- made the image loading code support Exif digital camera files
- some enhancements to TextEditor and ComboBox, to allow a message to be displayed when nothing is yet entered or selected
- fixed a bug in SubregionStream
- changes to make the code GCC 3.4 complient

==============================================================================
Changelist for version 1.9

- OpenGL support with the OpenGLComponent class!
- fixed a bug with Array::addSorted that made list multi-selections go wrong
- added some methods to move array elements around
- added the TimeSliceThread class
- added the FileLogger class

==============================================================================
Changelist for version 1.8

- added some convenience methods to the URL class to download and parse a URL as a string, xml, etc.
- rewrote the TreeView class completely - sorry if you were using the old version, but this one's better, honest!
- TextEditors can now be used for entering passwords with an option to obscure their content
- renamed KeyPressMappingManager to KeyPressMappingSet, and tweaked it slightly
- and a load of bugfixes suggested by users
- updated the i/o streams to use 64-bit read/write positions, (and also the audio reader and writer classes)
- added an option to compile using unicode Win32 calls (turned on in win32_headers.h). This is off by default because although it's better for win2k/XP, it stops apps running on win98.

==============================================================================
Changelist for version 1.7

- new class: MouseHoverDetector
- new key-shortcut classes: KeyPressMappingManager and KeyMappingEditorComponent
- added QuickTime movie support via the QuickTimeMovieComponent class
- mouse-events are now time-stamped with the time the event occurred rather than using the time it was delivered (better for detecting double-clicks, etc)s
- getScreenX() now takes into account windows that are contained in non-juce parent windows (e.g. audio plugins)

==============================================================================
Changelist for version 1.6

- added a MessageManagerLock class for allowing multi-threaded access to UI components
- new audio source classes: PositionableAudioSource, BufferingAudioSource, AudioSourcePlayer, etc to make playback more generic

==============================================================================
Changelist for version 1.5

- added some workarounds to get it to build under the Borland C++ compiler
- added a VCExpress project, that should also (presumably) work in VC7
- changes to Component::focusGained() and focusLost() to indicate the cause of the focus change - be sure to check your code and update any places you've used these methods!
- changed NativeDesktopWindow::setFullScreen() to restore the last known size when full-screening is turned off
- tweaks to win32 window minimisation because some people had mysterious non-repainting windows when building with certain libraries
- added semi-transparent window support on the mac, and some fixes so that windows with the "appearsOnTaskbar" flag set will appear properly in expose

==============================================================================
Changelist for version 1.4

- made changes to the Mac event handling to allow Juce-based dynamic libraries to work correctly
- cleaned up a lot of warnings under newer MS compilers and got it to build under VC Express
- couple of minor midi bugfixes

==============================================================================
Changelist for version 1.3

- cleaned up various aspects of the code so it'll build under Mingw
- created a DevC++ project to build the library
- added some AudioFormatReader methods to scan for audio levels
- added some more timecode methods to MidiMessage
- the tab/shift-tab key now moves the focus between components
- changes to the DirectSound support to allow easier addressing of the individual devices and pair up matching input/output devices
- better build settings in XCode on the Mac, so it puts the build products in the right folder

==============================================================================
Changelist for version 1.2

- changed various bits of the message-handling code to allow it to work better when used to build DLLs on Windows

==============================================================================
Changelist for version 1.1

- added a StringPairArray class and used it to tidy up some other bits of code
- fixed StringArray::addTokens, which was missing out empty tokens
- added metadata to the audio format readers and writers
- added support for BWAV chunks to WavAudioFormat
- finished some ImageBrush and GradientBrush methods that hadn't been implemented
- added an operator= for the Image class
- tightened up some copy constructors and operator= methods for classes that shouldn't be copied
- added an AudioSubsectionReader class
- added AudioFormatWriter::writeFromAudioReader() and writeFromAudioSource() methods
- added a format type name to AudioFormatReaders and writers
- fixed a small bug with mouse cursors when using modal windows
- added some methods to AudioCDReader to scan for indexes (PC only)
- added FloatElementComparator and IntegerElementComparator classes
- fixed a couple of layout bugettes in AlertWindow
- added the ThreadWithProgressWindow class to make it easy to show a dialog box while a background task completes
- fixed a bug with certain accented characters not displaying correctly on the Mac
- fixed the cursor position sometimes being wrong in TextEditors when undoing/redoing
- added a sample rate parameter to AudioSource::prepareToPlay

==============================================================================
Changelist for version 1.0 - August 5th 2004

- initial release!

==============================================================================

+ 273
- 0
docs/JUCE readme.html View File

@@ -0,0 +1,273 @@
<?xml version="1.0" encoding="windows-1250"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta http-equiv="Content-Language" content="en-us" />
<meta name="description" content="Raw Material Software" />
<meta name="keywords" content="audio, music, juce, tracktion, c++, sequencer, library, programming, software, julian storer$otherkeywords" />
<meta name="robots" content="index,follow" />
<title>JUCE - installation and compiling</title>
<link href="rawmat.css" rel="stylesheet" type="text/css" media="all" />
</head>
<body>
<div class="pageholder">
<div class="banner">
<a href="http://www.rawmaterialsoftware.com">
<img src="images/rms_logo.gif" alt="raw material software" title="raw material software"/></a>
</div>
<p><a href="#intro">Introduction</a> - <a href="#license">License</a> -
<a href="#install">Installation</a> -
<a href="#buildvc2005">Building with VC2005</a> -
<a href="#buildvcx">Building with VC Express</a> -
<a href="#buildvc6">Building with VC6</a> -
<a href="#buildvc7">Building with VC7</a> -
<a href="#buildxcode">Building with XCode</a> -
<a href="#builddevcpp">Building with Dev-Cpp</a> -
<a href="#buildlinux">Building on Linux</a> -
</p>
<h1>JUCE</h1>
<h2><a name="intro"></a>Introduction</h2>
<p>JUCE is an all-encompassing C++ class
library for developing cross-platform applications.</p>
<p>A complete doxygen-created API guide is available <a href="http://www.rawmaterialsoftware.com/juce/api/index.html" target="juce api">here</a>
as HTML, or can be downloaded as a precompiled Windows help file from the
<a href="http://www.rawmaterialsoftware.com/juce/download.php">downloads</a> page.</p>
<p>For more help and information, please visit the <a href="http://www.rawmaterialsoftware.com/juce">JUCE website</a>.</p>
<h2><a name="license"></a>License</h2>
<p>JUCE is released under the <a href="http://www.gnu.org/copyleft/gpl.html">Gnu Public License</a>,
which means it can be freely copied and distributed, and costs nothing to use in open-source applications.</p>
<p>If you'd like to release a closed-source application that uses JUCE, commercial licenses are available
for a fee - click <a href="http://www.rawmaterialsoftware.com/juce/licensing.php">here</a> for more information on pricing and terms.</p>
<h2><a name="install"></a>Installation</h2>
<h3>Installing the source code</h3>
<p>The JUCE source code all lives in a folder called, unsurprisingly, <code>juce</code>, which you can unzip
and put somewhere on your system.</p>
<p>To compile the library, there is a subfolder <code>juce/build</code> that contains projects for different
operating systems and compilers.</p>
<h3>Building the demo application</h3>
<p>Inside the <code>juce</code> folder is a demo application that shows off a few of Juce's features.
The <code>juce/extras/juce demo/build</code> folder contains projects and workspaces for the various platforms and compilers.</p>
<h2>Building your application with JUCE</h2>
<h3><a name="buildvc2005"></a>Compiling with Microsoft Visual Studio 2005</h3>
<p>The quickest way to get started is to try building the demo application - there's a Visual Studio
soluion in <code>juce/extras/juce demo/build/win32_vc8/jucedemo.sln</code> which contains both the juce
library project and the demo application project.</p>
<p>This should build and run with no extra set-up needed in Visual Studio. (If you're using VCExpress Edition
see below for the few extra steps needed).</p>
<p>The only thing to check if you're unfamiliar with Visual Studio is that the <code>jucedemo</code>
project needs to be selected as your "startup" project (right-click on the
jucedemo project in the solution explorer for this option). Also, the active configuration should be
set to "Debug" or "Release", (the first time you load a project, VS selects one of the configurations and
usually picks "Debug DLL" as its default, for reasons best known to itself).</p>
<p>To create your own application that links to Juce:</p>
<ol>
<li>Either make a copy of the example project in <code>juce/projects</code> and rename/customise
it, or create a new application project as an 'empty' WIN32 application - avoid saying yes to
MFC or any of the other rubbish that Visual Studio might offer to pollute your application with.</li>
<li>Include the header file <code>juce.h</code> in all your source files (it's best to
put this in a precompiled header).</li>
<li>Ensure that the linker's search path for libraries includes the the <code>juce/bin</code> directory.
This path can be set globally, or can be added to your project's linker settings.</li>
<li>Choose to link to the "Multithreaded" or "Debug Multithreaded" run-time libraries, depending on
whether you're doing a debug or release build. On VC6, this is set in the Project Settings / C/C++ / Code
Generation options panel. In Visual Studio, it's in the project properties.</li>
<li>Make sure that your project has exception handling and run-time type information (RTTI) turned ON.</li>
<li>Have a look at the 'hello world' projects, demo projects, or the API documentation about the
<code>JUCEApplication</code> class to find out how to create the application launch code.</li>
</ol>
<h3><a name="buildvcx"></a>Compiling with Microsoft Visual C++ Express edition</h3>
<p>Although VCExpress is basically the same thing as Visual Studio 2005, it doesn't come
with all the Win32 library code pre-installed, so a couple of extra steps are required before JUCE
can be compiled with it:</p>
<ol>
<li>Install the latest Platform SDK from Microsoft.</li>
<li>A few extra items need to be added to your include and library search paths. The first few
entries on your include path should look like this (obviously you might have things installed in
different places, but the order is important!):
<pre>C:\Program Files\Microsoft Platform SDK\include
C:\Program Files\Microsoft Platform SDK\include\crt
C:\Program Files\Microsoft Platform SDK\include\mfc
C:\mycode\juce
...</pre>
And the library search path should begin like this:
<pre>$(VSInstallDir)VC\lib
C:\Program Files\Microsoft Platform SDK\lib
C:\mycode\juce\bin
...</pre>
</li>
</ol>
<p>Then, you can follow the same instructions as for Visual Studio 2005 above.</p>
<h3><a name="buildvc6"></a>Compiling with Microsoft Visual Studio 6</h3>
<p>To compile the JUCE .lib files from the source code:</p>
<ol>
<li>Install the latest Platform SDK from Microsoft.</li>
<li>Set up your include and library search paths. The first few items on your include path
should look like this (obviously you might have things installed in different places, but the
order is important!):
<pre>C:\Program Files\Microsoft Platform SDK\include
C:\Program Files\Microsoft Platform SDK\include\crt
C:\Program Files\Microsoft Platform SDK\include\mfc
C:\mycode\juce
...</pre>
And the library search path should begin like this:
<pre>C:\Program Files\Microsoft Visual Studio\VC98\LIB
C:\Program Files\Microsoft Platform SDK\lib
C:\mycode\juce\bin
...</pre>
</li>
<li>Open the juce.dsp project file in <code>juce/build/win32/vc6</code></li>
<li>There are several configurations: debug, release, debug-unicode, and release-unicode.
You can build all or some of these, and the resultant .lib files should end up in the
"juce/bin" folder.</li>
</ol>
<p>Note that there's a rather lame bug in VC6 that causes an internal compiler error if you include
filenames that are too long. This can get triggered if you put the juce folder in a deeply-nested
directory (such as your user home directory). Unfortunately I think the only workaround for this
is to move the source tree to a shallower directory.</p>
<p>For info on how to create an application that uses Juce, see the VC2005 notes above.</p>
<h3><a name="buildvc7"></a>Compiling with Microsoft Visual Studio 7</h3>
<p>For VC7, you can import the VC6 projects and this should work ok. It's also possible to
tweak the version number in the VC8 projects so that they can be opened in VC7, but that's a
less reliable method!</p>
<h3><a name="buildxcode"></a>Compiling with XCode on MacOSX</h3>
<p>To compile the JUCE binaries from the source code:</p>
<ol>
<li>Open the <code>Juce.xcodeproj</code> file in <code>juce/build/macosx</code></li>
<li>This project has "debug" and "release" configurations, and the library files it creates
are <code>libjuce.a</code> (release) and <code>libjucedebug.a</code> (debug), which will appear
in the <code>juce/bin</code> directory.</li>
</ol>
<p>Then, to create and build an application:</p>
<ol>
<li>Either make a copy of the example project in <code>juce/extras/example projects</code> and rename/customise it, or
create a new "Carbon Application" project.</li>
<li>Include the header file <code>juce.h</code> in all your source files.</li>
<li>Get rid of any main() functions that XCode might have generated for you, and instead use the
<code>JUCEApplication</code> class as your application launcher - see the API documentation for this
class for more details, or have a look at the example projects, or demos.</li>
<li>Drag-and-drop the <code>juce.xcodeproj</code> file into the project's "External Frameworks and Libraries"
list.</li>
<li>Expand this item in the treeview, and inside there'll be an item "libjuce.a" or "libjucedebug.a" - drag-and-drop
this into the "link binary with libraries" phase inside the xcode target. When you select either a debug
or release juce build these entries will (usually) update themselves to show the correct debug or release library
name. If you want your project to automatically rebuild Juce when you make changes to a juce file, you can
also add Juce to your target's "Direct Dependency" list (show information for the target, and this is on the
"general" tab).<br/>Alternative ways of linking to juce would be to add the libjuce.a or libjucedebug.a library to
your "External Frameworks and Libraries" list, or to add switch to the linker's command-line of either "-ljuce"
or "-ljucedebug".</li>
<li>You'll also need to add some of the following OSX frameworks to your "External Frameworks and Libraries" list,
depending on what features your application uses:
<pre>Carbon.framework
IOKit.framework
CoreAudio.framework
CoreMIDI.framework
QuickTime.framework
OpenGL.framework
AGL.framework</pre>
In future there may be other frameworks that you'll need to link with to support new JUCE features.
(It should be pretty obvious from the link-time error when one of these is missing).
</li>
</ol>
<h3><a name="builddevcpp"></a>Creating a JUCE application with Dev-C++</h3>
<ol>
<li>open <code>\juce\build\win32\devcpp\juce.dev</code></li>
<li>You may need to install the Platform SDK from Microsoft, and add <pre>C:\Program Files\Microsoft Platform SDK\Include</pre>
at the <strong>end</strong> of your include path to get some of the more recent header files.</li>
<li>Compile! It should produce a library file called <code>juce/bin/libjuce.a</code></li>
</ol>
<p>Then, to create and build an application:</p>
<ol>
<li>Create a new project, as a "win32 GUI".</li>
<li>Remove <code>main.cpp</code></li>
<li>Either copy the example main.cpp from the MSVC juce example project, or write your own based
around the <code>JUCEApplication</code> class</li>
<li>In your project settings (alt-P), you'll need to adjust the linker's options so that it links the following libraries:
<pre>libjuce.a (this will be in your juce/bin/ directory)
libwininet.a
libdsound.a
libole32.a
libwinmm.a
libgdi32.a
libuuid.a
libshell32.a
libvfw32.a
librpcrt4.a (these are all in the Dev-C++ libraries folder)</pre>
</li>
</ol>
<h3><a name="buildlinux"></a>Creating a JUCE application on Linux with GCC</h3>
<ol>
<li>Most linux distros should come with the tools you need, although you might want to get hold of
<a href="http://premake.sourceforge.net/">premake</a>, which is used to automatically generate the
juce makefile. (This isn't necessary if you're just going to use the makefile that's provided).</li>
<li>Get a command prompt and go into <code>/juce/build/linux</code></li>
<li>To build the debug version, use "<code>make CONFIG=Debug</code>", or use "<code>make CONFIG=Release</code>"
to build the release version. You can also use "<code>make clean</code>" to delete the intermediate
files.</li>
</ol>
<p>Then, to create and build an application:</p>
<ol>
<li>Building the library will have produced the library files <code>/juce/bin/libjuce.a</code> and
<code>/juce/bin/libjuce_debug.a</code>. You'll need to link to one of these in your app, and you'll
also need to link to these libraries:
<pre>freetype
pthread
X11</pre>
If you've set the <code>JUCE_USE_XINERAMA</code> flag in juce_Config.h, you'll also need to link to the
<code>xinerama</code> library.
And you'll need the <code>GL</code> and <code>GLU</code> libraries if you've enabled
<code>JUCE_OPENGL</code>
</li>
</ol>
<div class="ad">
<p class="ad">***</p>
</div>
<div class="bottomsection">
<p class="bottombar">- Copyright 2005 Raw Material Software Ltd -</p>
</div>
</div>
</body>
</html>

+ 340
- 0
docs/gpl.txt View File

@@ -0,0 +1,340 @@
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.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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.
<signature of Ty Coon>, 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.

BIN
docs/images/rms_logo.gif View File

Before After
Width: 342  |  Height: 60  |  Size: 3.4KB

+ 193
- 0
docs/rawmat.css View File

@@ -0,0 +1,193 @@
body {
color: #444444;
font-family: Tahoma, Geneva, Arial, Helvetica, sans-serif;
font-size: 0.8em;
line-height: 1.5em;
text-align: left;
background: #e0e0e0;
}
a { color: #005888; }
a:hover { color: #1c90b0; }
a:visited { color: #006699; }
a:visited:hover { color: #1c90b0; }
h1 {
font-family: "Arial Narrow", Tahoma, Geneva, Arial, Helvetica, sans-serif;
font-size: 1.6em;
color: #006b95;
margin: 15px 0 15px 0;
padding-left: 15px;
}
h2 {
font-family: "Arial Narrow", Tahoma, Geneva, Arial, Helvetica, sans-serif;
font-size: 1.3em;
color: #007aac;
margin: 15px;
}
h3 {
font-family: "Arial Narrow", Tahoma, Geneva, Arial, Helvetica, sans-serif;
font-size: 1.1em;
color: #56a7c1;
margin: 15px;
}
p {
margin: 10px 15px 5px 15px;
}
pre {
font-family: monospace;
font-size: 1.1em;
line-height: 1.1em;
}
code {
font-family: monospace;
font-size: 1.2em;
line-height: 1.1em;
}
.pageholder {
width: 800px;
min-width: 800px;
margin: 10px auto 0 auto;
background: #ffffff none;
padding: 0 !important; position: relative; }
.banner {
height: 90px;
background: #3366cc none; line-height: 20px; font-family: Arial, Tahoma, Geneva, Helvetica, sans-serif; }
.banner img {
float: left;
color: #ffffff;
margin: 15px 0 0 16px;
border: 0;
background: none; font-family: sans-serif; font-size: 25px;
}
.mainsections {
margin: 6px 0px 6px 0px;
padding: 0; position: absolute; left: 390px; top: 56px;
float: left;
font-size: 13px; }
.mainsections ul {
margin: 0;
padding: 0 0 0 10px; background-color: #3366cc; background-image: none; }
.mainsections li {
list-style-type: none;
float: left;
width: auto;
min-width: 50;
min-height: 22px; max-height: 22px;
text-align: center; margin: 6px 4px 0px 4px;
font-size: 12px; background: url(images/inactiverightcorner.gif) no-repeat top right; }
.mainsections a:link, .mainsections a:visited {
display: block;
color: #d0eef3; text-decoration: none;
padding: 2px 8px 0px 10px;
background: url(images/inactiveleftcorner.gif) no-repeat top left;
max-height: 20px; }
.mainsections a:hover, .mainsections a:visited:hover {
color: #ffffff;
text-decoration: none;
padding: 2px 8px 0px 10px;
}
.currentsection {
margin-top: 4px;
background-image: url(images/activerightcorner.gif) !important;
}
.currentsection a:link, .currentsection a:visited {
color: #006b95 !important;
background-image: url(images/activeleftcorner.gif) !important;
}
.currentsection a:hover, .currentsection a:visited:hover {
color: #2c93b0 !important;
}
.subsections {
clear: both;
}
.subsections ul {
margin: 0;
padding: 0 6px 0 6px;
}
.subsections li {
list-style-type: none;
float: left;
margin: 0px 4px 0 4px;
background-image: url(images/inactivesubsection.gif);
background-repeat: no-repeat;
background-position: center left;
padding-left: 10px; }
.subsections a:link, .subsections a:visited {
padding: 0 4px 0 4px;
text-decoration: none;
}
.currentsubsection a:link, .currentsubsection a:visited {
font-weight: bold;
color: #000099;
}
.currentsubsection {
background-image: url(images/activesubsection.gif) !important;
}
.content {
clear: both;
float: none;
padding: 2px 5px 0 5px;
min-height: 500px;
background-image: none;
font-family: Georgia, Helvetica, sans-serif;
}
.prop {
float: right;
width: 1px;
height: 400px;
}
.bottomsection {
clear: both;
text-align: center;
background-image: none;
margin: 0;
padding: 15px 0 12px 0;
}
.bottombar {
padding: 5px;
background: #3366cc none;
margin: 10px 0 10px 0 !important;
color: #ffffff; height: 26px;
font-size: 0.8em;
}
.bottombar a, .bottombar a:visited {
color: #d0eef0 !important;
}
.bottomtext a:hover, .bottomtext a:visited:hover {
color: #ffffff !important;
}
.ad {
clear: both;
padding: 30px 0 0 0;
text-align: center;
}

+ 265
- 0
extras/audio plugins/How to use this framework.txt View File

@@ -0,0 +1,265 @@

The Juce Audio Plugin project!
==============================

(c) 2005-6 by Raw Material Software, visit www.rawmaterialsoftware.com for more info.

The idea behind this is to create a framework which lets you write a platform-independent
audio plugin using Juce, which can be easily rebuilt to target multiple different plugin
formats and platforms.


How does it work?
=================

There's a generic audio plugin base class defined in juce_AudioFilterBase.h, and to write
your plugin, you just need to create a sub-class of this.

You can then compile your class against one or more of the platform-specific projects,
so that it gets wrapped as a VST, AudioUnit, RTAS, etc. - hopefully without changing any
of your code at all, or having to go anywhere near any platform-specific stuff.


How do I use it?
================

Under the 'wrapper/formats' directory are a bunch of different sets of files containing the
wrapper code for each different plugin type.

There is also a 'demo' folder - this shows an example plugin which can be built in all
the different formats. The demo folder contains:

- a 'src' directory containing the common, platform-independent code that defines this
plugin's behaviour
- a 'build' directory which contains projects for building the demo for each different
platform and format.

Have a look at the demo classes to see how it works, and then to create a real plugin,
you'll need to replace the demo files with your own code.

I've tried to add helpful comments where you might run across common compile errors, to
help describe what you might be doing wrong, as getting a build set-up for some of these
formats can be a bit of a pain. Please let me know if you find there's anything missing
from these instructions or anything I could change to help smooth the build process along
a bit.

I'd recommend NOT putting your own plugin code inside the JuceAudioPlugin directory - it's
much neater to keep it somewhere separate and to alter the projects to point to your
files instead of the demo ones. That way when new versions of this library come out, it'll
make it easier to update to the latest code.

For details about how to create your own projects for the various formats, see below.


Sending feedback:
=================

- if you spot a bug or some kind of host incompatibility, tell me, of course!

- the plan is that no-one should need to change any of the platform-specific code, or the base-class
code.. So if you find that your plugin can't do something you want it to, then rather than just
jumping in and hacking things to get the functionality you need, why not contact me and we'll
figure out a nice generic way of doing it. That way it'll benefit all the users, and you won't
have to hack it all over again when the next version comes out.

- if you're really determined to rewrite large chunks of my code and send it to me to look at,
*please* don't reformat anything in your own preferred style, or change the format of the
comments, etc.. It's bad enough looking at people's code and trying to figure out why they've
done something, but if everything's moved around I can't even diff it..


What are the licensing issues?
==============================

Juce is released under the GPL (Gnu Public License) - this means that you're free to use
and redistribute it as long as your products are also released under the GPL. Basically
this means that if you use it, you also have to give away your source code.
If you want to release a closed-source application, you can buy a commercial license
that lets you avoid this restriction - see http://www.rawmaterialsoftware.com/juce for more info,
or see the comments at the top of all the Juce source files.

If you're building the VST projects or releasing a VST, you'll need have a look at Steinberg's
developer site to see what licensing rules apply these days. Their website's at
http://www.steinberg.net

If you're building an RTAS then you'll need to sign Digidesign's developer license to get
their SDK. Visit http://www.digidesign.com for more info.


-----------------------------------------------------------------------------------------------------

How to create your own VST project
==================================

- Visit http://www.steinberg.net and jump through whatever hoops are necessary to download
and install the VST SDK.
- Make sure your include path contains an entry for the "vstsdk2.4" folder containing
the SDK.
- First try loading the VST demo project in JuceAudioPlugin/demo/build. Hopefully this
should build correctly.
- To create your own project for a VST, the simplest way is to take a copy of
the demo project and go through it carefully, changing any relevent settings to reflect
your own project.

N.B. On the Mac, there's an important point to note about exported symbols.. When XCode builds
the plugin, I've had unpredictable results when trying to stop it from exporting all of
the internal functions as public symbols. There are some flags that are supposed to turn this
off, but sometimes they don't seem to have any effect, and using an explicit exports file also
seems a bit hit-and-miss. (If anyone knows better and can get this working, please let me know!)
Anyway, as well as being wasteful and showing everyone what's inside your plugin, leaving all
the symbols in there will cause fatal crashes when used with Tracktion, or alongside any other
Juce-based plugins. A way of making sure your plugin is stripped is to use the command
"strip -x -S YourPlugin.vst/Contents/MacOS/YourPlugin" after bulding it, which removes the
unnecessary symbols (although in my experience this also doesn't seem to work all the time,
so it's a good idea to check it using the unix "nm" command).


-----------------------------------------------------------------------------------------------------

How to create your own AudioUnit project
========================================

- If you've got XCode installed, the demo project in JuceAudioPlugin/demo/build/AudioUnit
should just build. You may need to tweak a few paths to make sure it can find the
juce.h include file and juce library.
- When copying this project to make your own, a good plan is to open up a view of the settings
for the project and target, viewing the "customised settings" to see those values that
have to be deliberately set for the plugin to work.

N.B. For the Mac there can be an issue with exported symbols - see the note about this for
VSTs, as the same solution can be used for AudioUnits.


-----------------------------------------------------------------------------------------------------

How to create your own RTAS project
===================================


RTAS is a bit more of a pain to build than VSTs or AUs. To begin with:

- Contact Digidesign, ask to become a Digidesign Development Partner, sign the relevent
agreements and NDAs.
- From the Digidesign website, download their latest Plug-In SDK
- Install the SDK and build some of the demo plugins to make sure it all works.

Compiling the juce demo RTAS on the PC:
=======================================

- Using the Digidesign demo projects in the SDK, make sure you've built debug and release
versions of these static libraries: DAE.lib, DigiExt.lib, DSI.lib, PlugInLib.lib.

- In Visual Studio, add all of this lot to your include path:

c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\EffectClasses
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ProcessClasses
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ProcessClasses\Interfaces
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Utilities
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\RTASP_Adapt
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\CoreClasses
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Controls
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Meters
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\ViewClasses
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\DSPClasses
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\PluginLibrary\Interfaces
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\common
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\common\Platform
c:\yourdirectory\PT_711_SDK\AlturaPorts\TDMPlugins\SignalProcessing\Public
c:\yourdirectory\PT_711_SDK\AlturaPorts\SADriver\Interfaces
c:\yourdirectory\PT_711_SDK\AlturaPorts\DigiPublic\Interfaces
c:\yourdirectory\PT_711_SDK\AlturaPorts\Fic\Interfaces\DAEClient
c:\yourdirectory\PT_711_SDK\AlturaPorts\NewFileLibs\Cmn
c:\yourdirectory\PT_711_SDK\AlturaPorts\NewFileLibs\DOA
c:\yourdirectory\PT_711_SDK\AlturaPorts\AlturaSource\PPC_H
c:\yourdirectory\PT_711_SDK\AlturaPorts\AlturaSource\AppSupport

- The Visual Studio juce_RTAS project contains a folder called "libs", with "debug" and
"release" subdirectories - these should contain links to the Digidesign lib files
DAE.lib, DigiExt.lib, DSI.lib, PlugInLib.lib - you'll need to update these links to
point to the correct locations according to where you've installed the SDK.

- Fingers crossed, this should now compile..


Creating a project for your own RTAS on the PC:
=================================================

- start a new empty project in Developer Studio, as a "Windows DLL"
- in the source tree, create the same folders and add to them the same list of
cpp files that are in the demo project's "wrapper code" folder.
- select all the CPP files in the "wrapper code/RTAS specific" folder, and also
the juce_RTASWrapper.cpp file, (but NOT the juce_RTASUtilities.cpp file or any
other files!), and in their properties dialog, under C++/Advanced, change their
"Calling convention" setting to "__stdcall".
Remember to do this for both your debug and release builds!
- in your project's C++/General settings, add an additional include path so that
it will be able find your JucePluginCharacteristics.h file.
- Under "linker settings", change the output file name to have the suffix ".dpm"
instead of ".dll"
- Under "linker settings/input/ignore specific library", you'll probably need to
add "libcmtd.lib" for debug, and "libcmt.lib" for release.
- Under "linkey settings", set the Module definition file to be
JuceAudioPlugin/wrapper/formats/RTAS/juce_RTAS_dlldefs.def
- You might want to change the output directory to "\Program Files\Common Files\Digidesign\DAE\Plug-Ins\"
if you want the built plugin to go directly into the PT plugins folder
- Add a custom build step to copy the dummy resource file "JuceAudioPlugin\wrapper\formats\RTAS\DefaultResourceFile"
to your target directory, renaming to to be the same as your .dpm file, but with
".rsr" on the end of the name. The demo project does this with the command
"copy /Y ..\..\..\wrapper\formats\RTAS\DefaultResourceFile "$(TargetPath)".rsr"
- Under the "general" properties, make sure that the character set is not unicode, as
this seems to stop some of the Digi code building. Hopefully this will be fixed
in future SDK releases
- add a "libs" folder to your project, and copy the set of libraries from the
equivalent folder in the demo project. Make sure you enable the debug/release
versions of these libraries appropriately.

There are quite a few things that you need to get right for an RTAS to compile correctly -
the Digi SDK documentation has a full list of tips on setting up a project, but the
main ones to note are:

- the SDK uses __stdcall as its calling convention, but JUCE uses __cdecl. I've got
around this by leaving the project's default setting as __cdecl, but changing it
specifically for those files that include or build files from the SDK - i.e. for
most of the files in the "wrapper code/RTAS specific" folder of the demo project.
- the default struct alignment for the SDK is 2 bytes, wheras the default as used in
juce is 8 bytes. Again, I've left this at the default setting, and have explicitly
changed it with pragmas when including/building SDK files.
- even though it's not used, each xx.dpm file needs to have a corresponding
xx.dpm.rsr file next to it, or PT will refuse to load it. The demo project currently
does this by using a custom build step to copy and rename a small dummy rsr file called
JuceAudioPlugin/wrapper/formats/RTAS/DefaultResourceFile


Compiling the juce demo RTAS on the Mac:
========================================

- After installing the Digidesign SDK, make sure you've run the config_SDK_for_Mac command in
its root directory. This sets up some of the tools that it needs.
- Load the juce_RTASDemo.xcodeproject and look through the project in XCode to find
all the broken links to Digidesign files. You'll need to repair these to make them
point to the location of the SDK files on your machine.
- Open the project's settings, and look for the "MacBag" setting - this defines the location
of the MacBag folder in the Digidesign SDK. You'll need to update this to point to
its location on your machine.
- It should all compile now, fingers crossed..

- Building a universal binary on the Mac: for this, you'll need to recompile the Digidesign
PluginLibrary project as a universal binary. The easiest way to do this is to add the
following lines to the top of the CommonDebugSettings.xcconfig and CommonReleaseSettings.xcconfig
files (these are found deep in the PT SDK tree somewhere, and are used for config by both the
Digi projects and the juce plugin projects):
ARCHS = ppc i386
SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk
MACOSX_DEPLOYMENT_TARGET_ppc = 10.3


Creating a new project for your own RTAS plugin on the Mac:
===========================================================

It's probably easiest to take a copy of the juce demo project and go through it changing
its settings to those of your plugin.

If you decide to start from scratch, use the juce demo project as a reference to see
what needs to go in there. Looking at its project info for "customised settings" is a good
way to see what values have been set deliberately.


+ 28
- 0
extras/audio plugins/demo/build/AudioUnit/Info-JuceAU.plist View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string></string>
<key>CFBundleGetInfoString</key>
<string></string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>com.rawmaterialsoftware.JuceAUDemo</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>Juce Audio Unit Demo</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string></string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0.0</string>
</dict>
</plist>

+ 9
- 0
extras/audio plugins/demo/build/AudioUnit/JuceAU.exp View File

@@ -0,0 +1,9 @@
#
# This file must contain entries for the two AU entry points.
#
# Your JucePluginCharacteristics.h file must define the prefix used for these function names - for
# more info, see the comments in JucePluginCharacteristics.h
#

_JuceDemoAUEntry
_JuceDemoAUViewEntry

+ 609
- 0
extras/audio plugins/demo/build/AudioUnit/JuceDemoAU.xcodeproj/project.pbxproj View File

@@ -0,0 +1,609 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 42;
objects = {

/* Begin PBXBuildFile section */
3E8BF105079CA60300021B09 /* AUBase.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D199ED03175E1E01CA2136 /* AUBase.h */; };
3E8BF106079CA60300021B09 /* AUDispatch.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D199EF03175E1E01CA2136 /* AUDispatch.h */; };
3E8BF107079CA60300021B09 /* AUInputElement.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D199F103175E1E01CA2136 /* AUInputElement.h */; };
3E8BF108079CA60300021B09 /* AUOutputElement.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D199F303175E1E01CA2136 /* AUOutputElement.h */; };
3E8BF109079CA60300021B09 /* AUScopeElement.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D199F603175E1E01CA2136 /* AUScopeElement.h */; };
3E8BF10A079CA60300021B09 /* ComponentBase.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D199FA03175E1E01CA2136 /* ComponentBase.h */; };
3E8BF10B079CA60300021B09 /* AUEffectBase.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D199FF03175E1E01CA2136 /* AUEffectBase.h */; };
3E8BF10C079CA60300021B09 /* AUBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D19A0F03175E1E01CA2136 /* AUBuffer.h */; };
3E8BF10D079CA60300021B09 /* CAStreamBasicDescription.h in Headers */ = {isa = PBXBuildFile; fileRef = F5D19A6903175E8C01CA2136 /* CAStreamBasicDescription.h */; };
3E8BF10E079CA60300021B09 /* CAAudioChannelLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 7967EF8C04D70E7C00C625F7 /* CAAudioChannelLayout.h */; };
3E8BF113079CA60300021B09 /* AUBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5D199EC03175E1E01CA2136 /* AUBase.cpp */; };
3E8BF114079CA60300021B09 /* AUDispatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5D199EE03175E1E01CA2136 /* AUDispatch.cpp */; };
3E8BF115079CA60300021B09 /* AUInputElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5D199F003175E1E01CA2136 /* AUInputElement.cpp */; };
3E8BF116079CA60300021B09 /* AUOutputElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5D199F203175E1E01CA2136 /* AUOutputElement.cpp */; };
3E8BF117079CA60300021B09 /* AUScopeElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5D199F503175E1E01CA2136 /* AUScopeElement.cpp */; };
3E8BF118079CA60300021B09 /* ComponentBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5D199F903175E1E01CA2136 /* ComponentBase.cpp */; };
3E8BF119079CA60300021B09 /* AUEffectBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5D199FE03175E1E01CA2136 /* AUEffectBase.cpp */; };
3E8BF11A079CA60300021B09 /* AUBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5D19A0E03175E1E01CA2136 /* AUBuffer.cpp */; };
3E8BF11B079CA60300021B09 /* CAAudioChannelLayout.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7967EF8B04D70E7C00C625F7 /* CAAudioChannelLayout.cpp */; };
3E8BF11C079CA60300021B09 /* CAStreamBasicDescription.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7967EF8D04D70E7C00C625F7 /* CAStreamBasicDescription.cpp */; };
3E8BF11F079CA60300021B09 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F5AA9A2F0281AAB901C34293 /* CoreFoundation.framework */; };
3E8BF120079CA60300021B09 /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F5AA9A300281AAB901C34293 /* CoreServices.framework */; };
3E8BF121079CA60300021B09 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F5DA37E702821D04014500A0 /* Carbon.framework */; };
3E8BF122079CA60300021B09 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F5D19ABE0317606901CA2136 /* AudioUnit.framework */; };
845FAE5F0A5C0A6A008C94D8 /* juce.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 845FAE5E0A5C0A6A008C94D8 /* juce.xcconfig */; };
845FAEE10A5C2696008C94D8 /* QuickTime.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 845FAEE00A5C2696008C94D8 /* QuickTime.framework */; };
84CFAEFB090964560053C22C /* AUCarbonViewDispatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5D19AAB03175F3201CA2136 /* AUCarbonViewDispatch.cpp */; };
84CFAEFC090964560053C22C /* AUCarbonViewControl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5D19AA903175F3201CA2136 /* AUCarbonViewControl.cpp */; };
84CFAEFD090964560053C22C /* AUCarbonViewBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5D19AA703175F3201CA2136 /* AUCarbonViewBase.cpp */; };
84CFAF0E090965080053C22C /* CarbonEventHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F5D19AB003175F3201CA2136 /* CarbonEventHandler.cpp */; };
84CFAF10090965080053C22C /* CAAUParameter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EF64FA42057BC39200D99563 /* CAAUParameter.cpp */; };
84CFAFEB0909666C0053C22C /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3E8BF154079CA7A800021B09 /* AudioToolbox.framework */; };
84CFB029090968590053C22C /* DemoJuceAudioUnit.component in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3E8BF126079CA60300021B09 /* DemoJuceAudioUnit.component */; };
84EB400B090A4A2C008FAC1B /* juce_AudioUnitWrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84EB4009090A4A2C008FAC1B /* juce_AudioUnitWrapper.cpp */; };
84EB400C090A4A2C008FAC1B /* juce_AudioUnitWrapper.r in Rez */ = {isa = PBXBuildFile; fileRef = 84EB400A090A4A2C008FAC1B /* juce_AudioUnitWrapper.r */; };
84EB4042090A4F5A008FAC1B /* CAVectorUnit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F4E5DC280898301D00589A5A /* CAVectorUnit.cpp */; };
84EB404E090A5116008FAC1B /* JucePluginCharacteristics.h in Headers */ = {isa = PBXBuildFile; fileRef = 84EB404D090A5116008FAC1B /* JucePluginCharacteristics.h */; };
84F0521E090674BB00AEC8DB /* Info-JuceAU.plist in Resources */ = {isa = PBXBuildFile; fileRef = 84F05215090674BB00AEC8DB /* Info-JuceAU.plist */; };
84F05486090687BF00AEC8DB /* juce_AudioFilterBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F05482090687BF00AEC8DB /* juce_AudioFilterBase.cpp */; };
84F05487090687BF00AEC8DB /* juce_AudioFilterBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F05483090687BF00AEC8DB /* juce_AudioFilterBase.h */; };
84F05488090687BF00AEC8DB /* juce_AudioFilterEditor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F05484090687BF00AEC8DB /* juce_AudioFilterEditor.cpp */; };
84F05489090687BF00AEC8DB /* juce_AudioFilterEditor.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F05485090687BF00AEC8DB /* juce_AudioFilterEditor.h */; };
84F0548F090687F600AEC8DB /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84F0548E090687F600AEC8DB /* CoreAudio.framework */; };
84F054E80906C8DD00AEC8DB /* AUMIDIBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F054E40906C8DD00AEC8DB /* AUMIDIBase.cpp */; };
84F054E90906C8DD00AEC8DB /* AUMIDIBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F054E50906C8DD00AEC8DB /* AUMIDIBase.h */; };
84F054EA0906C8DD00AEC8DB /* AUMIDIEffectBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F054E60906C8DD00AEC8DB /* AUMIDIEffectBase.cpp */; };
84F054EB0906C8DD00AEC8DB /* AUMIDIEffectBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F054E70906C8DD00AEC8DB /* AUMIDIEffectBase.h */; };
84F055010906E9EA00AEC8DB /* DemoEditorComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F054FD0906E9EA00AEC8DB /* DemoEditorComponent.cpp */; };
84F055020906E9EA00AEC8DB /* DemoEditorComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F054FE0906E9EA00AEC8DB /* DemoEditorComponent.h */; };
84F055030906E9EA00AEC8DB /* DemoJuceFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84F054FF0906E9EA00AEC8DB /* DemoJuceFilter.cpp */; };
84F055040906E9EA00AEC8DB /* DemoJuceFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F055000906E9EA00AEC8DB /* DemoJuceFilter.h */; };
84F055260906FBCF00AEC8DB /* AUSilentTimeout.h in Headers */ = {isa = PBXBuildFile; fileRef = 84F055250906FBCF00AEC8DB /* AUSilentTimeout.h */; };
84F87963093B1EDC00225D65 /* AGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84F87962093B1EDC00225D65 /* AGL.framework */; };
84FDAFE90C15B9E200CD0087 /* libjuce.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 84FDAFBD0C15B8F100CD0087 /* libjuce.a */; };
A9E885EA0874B5BF00B2DFE8 /* CAThreadSafeList.h in Headers */ = {isa = PBXBuildFile; fileRef = A9E885E90874B5BF00B2DFE8 /* CAThreadSafeList.h */; };
F4E5DC2C0898301D00589A5A /* CAVectorUnit.h in Headers */ = {isa = PBXBuildFile; fileRef = F4E5DC290898301D00589A5A /* CAVectorUnit.h */; };
F4E5DC2D0898301D00589A5A /* CAVectorUnitTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = F4E5DC2A0898301D00589A5A /* CAVectorUnitTypes.h */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
84FDAFBC0C15B8F100CD0087 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 84F0545A0906865D00AEC8DB /* Juce.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = D2AAC046055464E500DB518D;
remoteInfo = Juce;
};
/* End PBXContainerItemProxy section */

/* Begin PBXCopyFilesBuildPhase section */
84CFB0240909684B0053C22C /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "/Users/jules/Library/Audio/Plug-Ins/Components";
dstSubfolderSpec = 0;
files = (
84CFB029090968590053C22C /* DemoJuceAudioUnit.component in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
3E3AAA740670E29D00C484A8 /* AUResources.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; path = AUResources.r; sourceTree = "<group>"; };
3E8BF126079CA60300021B09 /* DemoJuceAudioUnit.component */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DemoJuceAudioUnit.component; sourceTree = BUILT_PRODUCTS_DIR; };
3E8BF154079CA7A800021B09 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = /System/Library/Frameworks/AudioToolbox.framework; sourceTree = "<absolute>"; };
7967EF8B04D70E7C00C625F7 /* CAAudioChannelLayout.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CAAudioChannelLayout.cpp; sourceTree = "<group>"; };
7967EF8C04D70E7C00C625F7 /* CAAudioChannelLayout.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CAAudioChannelLayout.h; sourceTree = "<group>"; };
7967EF8D04D70E7C00C625F7 /* CAStreamBasicDescription.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CAStreamBasicDescription.cpp; sourceTree = "<group>"; };
845FAE5E0A5C0A6A008C94D8 /* juce.xcconfig */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xcconfig; name = juce.xcconfig; path = ../../../../../build/macosx/juce.xcconfig; sourceTree = SOURCE_ROOT; };
845FAEE00A5C2696008C94D8 /* QuickTime.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = QuickTime.framework; sourceTree = "<group>"; };
84EB4009090A4A2C008FAC1B /* juce_AudioUnitWrapper.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_AudioUnitWrapper.cpp; path = ../../../wrapper/formats/AudioUnit/juce_AudioUnitWrapper.cpp; sourceTree = SOURCE_ROOT; };
84EB400A090A4A2C008FAC1B /* juce_AudioUnitWrapper.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = juce_AudioUnitWrapper.r; path = ../../../wrapper/formats/AudioUnit/juce_AudioUnitWrapper.r; sourceTree = SOURCE_ROOT; };
84EB404D090A5116008FAC1B /* JucePluginCharacteristics.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JucePluginCharacteristics.h; path = ../../src/JucePluginCharacteristics.h; sourceTree = SOURCE_ROOT; };
84F05215090674BB00AEC8DB /* Info-JuceAU.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; path = "Info-JuceAU.plist"; sourceTree = "<group>"; };
84F05217090674BB00AEC8DB /* JuceAU.exp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.exports; path = JuceAU.exp; sourceTree = "<group>"; };
84F0545A0906865D00AEC8DB /* Juce.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Juce.xcodeproj; path = ../../../../../build/macosx/Juce.xcodeproj; sourceTree = SOURCE_ROOT; };
84F05482090687BF00AEC8DB /* juce_AudioFilterBase.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_AudioFilterBase.cpp; path = ../../../wrapper/juce_AudioFilterBase.cpp; sourceTree = SOURCE_ROOT; };
84F05483090687BF00AEC8DB /* juce_AudioFilterBase.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = juce_AudioFilterBase.h; path = ../../../wrapper/juce_AudioFilterBase.h; sourceTree = SOURCE_ROOT; };
84F05484090687BF00AEC8DB /* juce_AudioFilterEditor.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_AudioFilterEditor.cpp; path = ../../../wrapper/juce_AudioFilterEditor.cpp; sourceTree = SOURCE_ROOT; };
84F05485090687BF00AEC8DB /* juce_AudioFilterEditor.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = juce_AudioFilterEditor.h; path = ../../../wrapper/juce_AudioFilterEditor.h; sourceTree = SOURCE_ROOT; };
84F0548E090687F600AEC8DB /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = /System/Library/Frameworks/CoreAudio.framework; sourceTree = "<absolute>"; };
84F054E40906C8DD00AEC8DB /* AUMIDIBase.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AUMIDIBase.cpp; path = /Developer/Examples/CoreAudio/AudioUnits/AUPublic/OtherBases/AUMIDIBase.cpp; sourceTree = "<absolute>"; };
84F054E50906C8DD00AEC8DB /* AUMIDIBase.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AUMIDIBase.h; path = /Developer/Examples/CoreAudio/AudioUnits/AUPublic/OtherBases/AUMIDIBase.h; sourceTree = "<absolute>"; };
84F054E60906C8DD00AEC8DB /* AUMIDIEffectBase.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AUMIDIEffectBase.cpp; path = /Developer/Examples/CoreAudio/AudioUnits/AUPublic/OtherBases/AUMIDIEffectBase.cpp; sourceTree = "<absolute>"; };
84F054E70906C8DD00AEC8DB /* AUMIDIEffectBase.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AUMIDIEffectBase.h; path = /Developer/Examples/CoreAudio/AudioUnits/AUPublic/OtherBases/AUMIDIEffectBase.h; sourceTree = "<absolute>"; };
84F054FD0906E9EA00AEC8DB /* DemoEditorComponent.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DemoEditorComponent.cpp; path = ../../src/DemoEditorComponent.cpp; sourceTree = SOURCE_ROOT; };
84F054FE0906E9EA00AEC8DB /* DemoEditorComponent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = DemoEditorComponent.h; path = ../../src/DemoEditorComponent.h; sourceTree = SOURCE_ROOT; };
84F054FF0906E9EA00AEC8DB /* DemoJuceFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DemoJuceFilter.cpp; path = ../../src/DemoJuceFilter.cpp; sourceTree = SOURCE_ROOT; };
84F055000906E9EA00AEC8DB /* DemoJuceFilter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = DemoJuceFilter.h; path = ../../src/DemoJuceFilter.h; sourceTree = SOURCE_ROOT; };
84F055250906FBCF00AEC8DB /* AUSilentTimeout.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AUSilentTimeout.h; path = /Developer/Examples/CoreAudio/AudioUnits/AUPublic/Utility/AUSilentTimeout.h; sourceTree = "<absolute>"; };
84F87962093B1EDC00225D65 /* AGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AGL.framework; path = /System/Library/Frameworks/AGL.framework; sourceTree = "<absolute>"; };
A3C2CC6105B4A4BE000F141E /* AUViewLocalizedStringKeys.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AUViewLocalizedStringKeys.h; sourceTree = "<group>"; };
A9E885E90874B5BF00B2DFE8 /* CAThreadSafeList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CAThreadSafeList.h; sourceTree = "<group>"; };
EF64FA42057BC39200D99563 /* CAAUParameter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CAAUParameter.cpp; sourceTree = "<group>"; };
EF64FA43057BC39200D99563 /* CAAUParameter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CAAUParameter.h; sourceTree = "<group>"; };
F4E5DC280898301D00589A5A /* CAVectorUnit.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CAVectorUnit.cpp; sourceTree = "<group>"; };
F4E5DC290898301D00589A5A /* CAVectorUnit.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CAVectorUnit.h; sourceTree = "<group>"; };
F4E5DC2A0898301D00589A5A /* CAVectorUnitTypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CAVectorUnitTypes.h; sourceTree = "<group>"; };
F5AA9A2F0281AAB901C34293 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = CoreFoundation.framework; sourceTree = "<group>"; };
F5AA9A300281AAB901C34293 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = CoreServices.framework; sourceTree = "<group>"; };
F5D199EC03175E1E01CA2136 /* AUBase.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AUBase.cpp; sourceTree = "<group>"; };
F5D199ED03175E1E01CA2136 /* AUBase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AUBase.h; sourceTree = "<group>"; };
F5D199EE03175E1E01CA2136 /* AUDispatch.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AUDispatch.cpp; sourceTree = "<group>"; };
F5D199EF03175E1E01CA2136 /* AUDispatch.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AUDispatch.h; sourceTree = "<group>"; };
F5D199F003175E1E01CA2136 /* AUInputElement.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AUInputElement.cpp; sourceTree = "<group>"; };
F5D199F103175E1E01CA2136 /* AUInputElement.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AUInputElement.h; sourceTree = "<group>"; };
F5D199F203175E1E01CA2136 /* AUOutputElement.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AUOutputElement.cpp; sourceTree = "<group>"; };
F5D199F303175E1E01CA2136 /* AUOutputElement.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AUOutputElement.h; sourceTree = "<group>"; };
F5D199F503175E1E01CA2136 /* AUScopeElement.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AUScopeElement.cpp; sourceTree = "<group>"; };
F5D199F603175E1E01CA2136 /* AUScopeElement.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AUScopeElement.h; sourceTree = "<group>"; };
F5D199F903175E1E01CA2136 /* ComponentBase.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ComponentBase.cpp; sourceTree = "<group>"; };
F5D199FA03175E1E01CA2136 /* ComponentBase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ComponentBase.h; sourceTree = "<group>"; };
F5D199FE03175E1E01CA2136 /* AUEffectBase.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AUEffectBase.cpp; sourceTree = "<group>"; };
F5D199FF03175E1E01CA2136 /* AUEffectBase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AUEffectBase.h; sourceTree = "<group>"; };
F5D19A0E03175E1E01CA2136 /* AUBuffer.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AUBuffer.cpp; sourceTree = "<group>"; };
F5D19A0F03175E1E01CA2136 /* AUBuffer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AUBuffer.h; sourceTree = "<group>"; };
F5D19A6903175E8C01CA2136 /* CAStreamBasicDescription.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CAStreamBasicDescription.h; sourceTree = "<group>"; };
F5D19AA703175F3201CA2136 /* AUCarbonViewBase.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AUCarbonViewBase.cpp; sourceTree = "<group>"; };
F5D19AA803175F3201CA2136 /* AUCarbonViewBase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AUCarbonViewBase.h; sourceTree = "<group>"; };
F5D19AA903175F3201CA2136 /* AUCarbonViewControl.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AUCarbonViewControl.cpp; sourceTree = "<group>"; };
F5D19AAA03175F3201CA2136 /* AUCarbonViewControl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AUCarbonViewControl.h; sourceTree = "<group>"; };
F5D19AAB03175F3201CA2136 /* AUCarbonViewDispatch.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AUCarbonViewDispatch.cpp; sourceTree = "<group>"; };
F5D19AB003175F3201CA2136 /* CarbonEventHandler.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CarbonEventHandler.cpp; sourceTree = "<group>"; };
F5D19AB103175F3201CA2136 /* CarbonEventHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CarbonEventHandler.h; sourceTree = "<group>"; };
F5D19ABE0317606901CA2136 /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = AudioUnit.framework; sourceTree = "<group>"; };
F5DA37E702821D04014500A0 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Carbon.framework; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
3E8BF11E079CA60300021B09 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
84FDAFE90C15B9E200CD0087 /* libjuce.a in Frameworks */,
84CFAFEB0909666C0053C22C /* AudioToolbox.framework in Frameworks */,
3E8BF11F079CA60300021B09 /* CoreFoundation.framework in Frameworks */,
3E8BF120079CA60300021B09 /* CoreServices.framework in Frameworks */,
3E8BF121079CA60300021B09 /* Carbon.framework in Frameworks */,
3E8BF122079CA60300021B09 /* AudioUnit.framework in Frameworks */,
84F0548F090687F600AEC8DB /* CoreAudio.framework in Frameworks */,
84F87963093B1EDC00225D65 /* AGL.framework in Frameworks */,
845FAEE10A5C2696008C94D8 /* QuickTime.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
84EB403B090A4ED3008FAC1B /* AU specific */ = {
isa = PBXGroup;
children = (
84EB4009090A4A2C008FAC1B /* juce_AudioUnitWrapper.cpp */,
84EB400A090A4A2C008FAC1B /* juce_AudioUnitWrapper.r */,
);
name = "AU specific";
sourceTree = "<group>";
};
84F0516D09066DB800AEC8DB /* Plugin Code */ = {
isa = PBXGroup;
children = (
84F054FD0906E9EA00AEC8DB /* DemoEditorComponent.cpp */,
84F054FE0906E9EA00AEC8DB /* DemoEditorComponent.h */,
84F054FF0906E9EA00AEC8DB /* DemoJuceFilter.cpp */,
84F055000906E9EA00AEC8DB /* DemoJuceFilter.h */,
84EB404D090A5116008FAC1B /* JucePluginCharacteristics.h */,
84F05215090674BB00AEC8DB /* Info-JuceAU.plist */,
84F05217090674BB00AEC8DB /* JuceAU.exp */,
);
name = "Plugin Code";
sourceTree = "<group>";
};
84F0516E09066DC900AEC8DB /* Wrapper Code */ = {
isa = PBXGroup;
children = (
84F05482090687BF00AEC8DB /* juce_AudioFilterBase.cpp */,
84F05483090687BF00AEC8DB /* juce_AudioFilterBase.h */,
84F05484090687BF00AEC8DB /* juce_AudioFilterEditor.cpp */,
84F05485090687BF00AEC8DB /* juce_AudioFilterEditor.h */,
84EB403B090A4ED3008FAC1B /* AU specific */,
F5AA99C50281A64501C34293 /* Apple AU Code */,
);
name = "Wrapper Code";
sourceTree = "<group>";
};
84FDAFB90C15B8F100CD0087 /* Products */ = {
isa = PBXGroup;
children = (
84FDAFBD0C15B8F100CD0087 /* libjuce.a */,
);
name = Products;
sourceTree = "<group>";
};
A3C2CC6005B4A4BE000F141E /* AUViewBase */ = {
isa = PBXGroup;
children = (
A3C2CC6105B4A4BE000F141E /* AUViewLocalizedStringKeys.h */,
);
path = AUViewBase;
sourceTree = "<group>";
};
F5AA99B60281A61201C34293 = {
isa = PBXGroup;
children = (
F5D199EA03175DB401CA2136 /* Source */,
845FAE5E0A5C0A6A008C94D8 /* juce.xcconfig */,
F5AA99C40281A62C01C34293 /* Products */,
F5AA9E890281AAC901C34293 /* Frameworks */,
);
sourceTree = "<group>";
};
F5AA99C40281A62C01C34293 /* Products */ = {
isa = PBXGroup;
children = (
3E8BF126079CA60300021B09 /* DemoJuceAudioUnit.component */,
);
name = Products;
sourceTree = "<group>";
};
F5AA99C50281A64501C34293 /* Apple AU Code */ = {
isa = PBXGroup;
children = (
F5D199EB03175E1E01CA2136 /* AUBase */,
A3C2CC6005B4A4BE000F141E /* AUViewBase */,
F5D19AA603175F3201CA2136 /* AUCarbonViewBase */,
F5D199FD03175E1E01CA2136 /* OtherBases */,
F5D19A0C03175E1E01CA2136 /* Utility */,
F5D19A3603175E8C01CA2136 /* PublicUtility */,
);
name = "Apple AU Code";
path = /Developer/Examples/CoreAudio/AudioUnits/AUPublic;
sourceTree = "<absolute>";
};
F5AA9E890281AAC901C34293 /* Frameworks */ = {
isa = PBXGroup;
children = (
84F0545A0906865D00AEC8DB /* Juce.xcodeproj */,
F5D19ABE0317606901CA2136 /* AudioUnit.framework */,
3E8BF154079CA7A800021B09 /* AudioToolbox.framework */,
84F0548E090687F600AEC8DB /* CoreAudio.framework */,
F5DA37E702821D04014500A0 /* Carbon.framework */,
F5AA9A2F0281AAB901C34293 /* CoreFoundation.framework */,
F5AA9A300281AAB901C34293 /* CoreServices.framework */,
84F87962093B1EDC00225D65 /* AGL.framework */,
845FAEE00A5C2696008C94D8 /* QuickTime.framework */,
);
name = Frameworks;
path = /System/Library/Frameworks;
sourceTree = "<absolute>";
};
F5D199EA03175DB401CA2136 /* Source */ = {
isa = PBXGroup;
children = (
84F0516D09066DB800AEC8DB /* Plugin Code */,
84F0516E09066DC900AEC8DB /* Wrapper Code */,
);
name = Source;
sourceTree = "<group>";
};
F5D199EB03175E1E01CA2136 /* AUBase */ = {
isa = PBXGroup;
children = (
3E3AAA740670E29D00C484A8 /* AUResources.r */,
F5D199EC03175E1E01CA2136 /* AUBase.cpp */,
F5D199ED03175E1E01CA2136 /* AUBase.h */,
F5D199EE03175E1E01CA2136 /* AUDispatch.cpp */,
F5D199EF03175E1E01CA2136 /* AUDispatch.h */,
F5D199F003175E1E01CA2136 /* AUInputElement.cpp */,
F5D199F103175E1E01CA2136 /* AUInputElement.h */,
F5D199F203175E1E01CA2136 /* AUOutputElement.cpp */,
F5D199F303175E1E01CA2136 /* AUOutputElement.h */,
F5D199F503175E1E01CA2136 /* AUScopeElement.cpp */,
F5D199F603175E1E01CA2136 /* AUScopeElement.h */,
F5D199F903175E1E01CA2136 /* ComponentBase.cpp */,
F5D199FA03175E1E01CA2136 /* ComponentBase.h */,
);
path = AUBase;
sourceTree = "<group>";
};
F5D199FD03175E1E01CA2136 /* OtherBases */ = {
isa = PBXGroup;
children = (
84F054E40906C8DD00AEC8DB /* AUMIDIBase.cpp */,
84F054E50906C8DD00AEC8DB /* AUMIDIBase.h */,
84F054E60906C8DD00AEC8DB /* AUMIDIEffectBase.cpp */,
84F054E70906C8DD00AEC8DB /* AUMIDIEffectBase.h */,
F5D199FE03175E1E01CA2136 /* AUEffectBase.cpp */,
F5D199FF03175E1E01CA2136 /* AUEffectBase.h */,
);
path = OtherBases;
sourceTree = "<group>";
};
F5D19A0C03175E1E01CA2136 /* Utility */ = {
isa = PBXGroup;
children = (
F5D19A0E03175E1E01CA2136 /* AUBuffer.cpp */,
F5D19A0F03175E1E01CA2136 /* AUBuffer.h */,
84F055250906FBCF00AEC8DB /* AUSilentTimeout.h */,
);
path = Utility;
sourceTree = "<group>";
};
F5D19A3603175E8C01CA2136 /* PublicUtility */ = {
isa = PBXGroup;
children = (
F4E5DC280898301D00589A5A /* CAVectorUnit.cpp */,
F4E5DC290898301D00589A5A /* CAVectorUnit.h */,
F4E5DC2A0898301D00589A5A /* CAVectorUnitTypes.h */,
A9E885E90874B5BF00B2DFE8 /* CAThreadSafeList.h */,
7967EF8C04D70E7C00C625F7 /* CAAudioChannelLayout.h */,
7967EF8B04D70E7C00C625F7 /* CAAudioChannelLayout.cpp */,
F5D19A6903175E8C01CA2136 /* CAStreamBasicDescription.h */,
7967EF8D04D70E7C00C625F7 /* CAStreamBasicDescription.cpp */,
EF64FA42057BC39200D99563 /* CAAUParameter.cpp */,
EF64FA43057BC39200D99563 /* CAAUParameter.h */,
);
name = PublicUtility;
path = /Developer/Examples/CoreAudio/PublicUtility;
sourceTree = "<absolute>";
};
F5D19AA603175F3201CA2136 /* AUCarbonViewBase */ = {
isa = PBXGroup;
children = (
F5D19AA703175F3201CA2136 /* AUCarbonViewBase.cpp */,
F5D19AA803175F3201CA2136 /* AUCarbonViewBase.h */,
F5D19AA903175F3201CA2136 /* AUCarbonViewControl.cpp */,
F5D19AAA03175F3201CA2136 /* AUCarbonViewControl.h */,
F5D19AAB03175F3201CA2136 /* AUCarbonViewDispatch.cpp */,
F5D19AB003175F3201CA2136 /* CarbonEventHandler.cpp */,
F5D19AB103175F3201CA2136 /* CarbonEventHandler.h */,
);
path = AUCarbonViewBase;
sourceTree = "<group>";
};
/* End PBXGroup section */

/* Begin PBXHeadersBuildPhase section */
3E8BF103079CA60300021B09 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
3E8BF105079CA60300021B09 /* AUBase.h in Headers */,
3E8BF106079CA60300021B09 /* AUDispatch.h in Headers */,
3E8BF107079CA60300021B09 /* AUInputElement.h in Headers */,
3E8BF108079CA60300021B09 /* AUOutputElement.h in Headers */,
3E8BF109079CA60300021B09 /* AUScopeElement.h in Headers */,
3E8BF10A079CA60300021B09 /* ComponentBase.h in Headers */,
3E8BF10B079CA60300021B09 /* AUEffectBase.h in Headers */,
3E8BF10C079CA60300021B09 /* AUBuffer.h in Headers */,
3E8BF10D079CA60300021B09 /* CAStreamBasicDescription.h in Headers */,
3E8BF10E079CA60300021B09 /* CAAudioChannelLayout.h in Headers */,
A9E885EA0874B5BF00B2DFE8 /* CAThreadSafeList.h in Headers */,
F4E5DC2C0898301D00589A5A /* CAVectorUnit.h in Headers */,
F4E5DC2D0898301D00589A5A /* CAVectorUnitTypes.h in Headers */,
84F05487090687BF00AEC8DB /* juce_AudioFilterBase.h in Headers */,
84F05489090687BF00AEC8DB /* juce_AudioFilterEditor.h in Headers */,
84F054E90906C8DD00AEC8DB /* AUMIDIBase.h in Headers */,
84F054EB0906C8DD00AEC8DB /* AUMIDIEffectBase.h in Headers */,
84F055020906E9EA00AEC8DB /* DemoEditorComponent.h in Headers */,
84F055040906E9EA00AEC8DB /* DemoJuceFilter.h in Headers */,
84F055260906FBCF00AEC8DB /* AUSilentTimeout.h in Headers */,
84EB404E090A5116008FAC1B /* JucePluginCharacteristics.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */

/* Begin PBXNativeTarget section */
3E8BF102079CA60300021B09 /* JuceAU */ = {
isa = PBXNativeTarget;
buildConfigurationList = A9E884AD0874ABE600B2DFE8 /* Build configuration list for PBXNativeTarget "JuceAU" */;
buildPhases = (
3E8BF103079CA60300021B09 /* Headers */,
3E8BF110079CA60300021B09 /* Resources */,
3E8BF111079CA60300021B09 /* Sources */,
3E8BF11E079CA60300021B09 /* Frameworks */,
3E8BF123079CA60300021B09 /* Rez */,
84CFB0240909684B0053C22C /* CopyFiles */,
);
buildRules = (
);
dependencies = (
);
name = JuceAU;
productInstallPath = "$(USER_LIBRARY_DIR)/Bundles";
productName = MultitapAU;
productReference = 3E8BF126079CA60300021B09 /* DemoJuceAudioUnit.component */;
productType = "com.apple.product-type.bundle";
};
/* End PBXNativeTarget section */

/* Begin PBXProject section */
F5AA99BA0281A61201C34293 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = A9E884B90874ABE600B2DFE8 /* Build configuration list for PBXProject "JuceDemoAU" */;
hasScannedForEncodings = 1;
mainGroup = F5AA99B60281A61201C34293;
productRefGroup = F5AA99C40281A62C01C34293 /* Products */;
projectDirPath = "";
projectReferences = (
{
ProductGroup = 84FDAFB90C15B8F100CD0087 /* Products */;
ProjectRef = 84F0545A0906865D00AEC8DB /* Juce.xcodeproj */;
},
);
targets = (
3E8BF102079CA60300021B09 /* JuceAU */,
);
};
/* End PBXProject section */

/* Begin PBXReferenceProxy section */
84FDAFBD0C15B8F100CD0087 /* libjuce.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libjuce.a;
remoteRef = 84FDAFBC0C15B8F100CD0087 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
/* End PBXReferenceProxy section */

/* Begin PBXResourcesBuildPhase section */
3E8BF110079CA60300021B09 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
84F0521E090674BB00AEC8DB /* Info-JuceAU.plist in Resources */,
845FAE5F0A5C0A6A008C94D8 /* juce.xcconfig in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */

/* Begin PBXRezBuildPhase section */
3E8BF123079CA60300021B09 /* Rez */ = {
isa = PBXRezBuildPhase;
buildActionMask = 2147483647;
files = (
84EB400C090A4A2C008FAC1B /* juce_AudioUnitWrapper.r in Rez */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXRezBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
3E8BF111079CA60300021B09 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
3E8BF115079CA60300021B09 /* AUInputElement.cpp in Sources */,
3E8BF116079CA60300021B09 /* AUOutputElement.cpp in Sources */,
3E8BF117079CA60300021B09 /* AUScopeElement.cpp in Sources */,
3E8BF113079CA60300021B09 /* AUBase.cpp in Sources */,
3E8BF119079CA60300021B09 /* AUEffectBase.cpp in Sources */,
3E8BF114079CA60300021B09 /* AUDispatch.cpp in Sources */,
3E8BF11C079CA60300021B09 /* CAStreamBasicDescription.cpp in Sources */,
3E8BF11B079CA60300021B09 /* CAAudioChannelLayout.cpp in Sources */,
84CFAF0E090965080053C22C /* CarbonEventHandler.cpp in Sources */,
84CFAEFB090964560053C22C /* AUCarbonViewDispatch.cpp in Sources */,
84CFAEFC090964560053C22C /* AUCarbonViewControl.cpp in Sources */,
84CFAEFD090964560053C22C /* AUCarbonViewBase.cpp in Sources */,
3E8BF118079CA60300021B09 /* ComponentBase.cpp in Sources */,
84CFAF10090965080053C22C /* CAAUParameter.cpp in Sources */,
3E8BF11A079CA60300021B09 /* AUBuffer.cpp in Sources */,
84F05486090687BF00AEC8DB /* juce_AudioFilterBase.cpp in Sources */,
84F05488090687BF00AEC8DB /* juce_AudioFilterEditor.cpp in Sources */,
84F054E80906C8DD00AEC8DB /* AUMIDIBase.cpp in Sources */,
84F054EA0906C8DD00AEC8DB /* AUMIDIEffectBase.cpp in Sources */,
84F055010906E9EA00AEC8DB /* DemoEditorComponent.cpp in Sources */,
84F055030906E9EA00AEC8DB /* DemoJuceFilter.cpp in Sources */,
84EB400B090A4A2C008FAC1B /* juce_AudioUnitWrapper.cpp in Sources */,
84EB4042090A4F5A008FAC1B /* CAVectorUnit.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */

/* Begin XCBuildConfiguration section */
A9E884AE0874ABE600B2DFE8 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = NO;
EXPORTED_SYMBOLS_FILE = JuceAU.exp;
FRAMEWORK_SEARCH_PATHS = "";
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_FIX_AND_CONTINUE = NO;
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
GCC_USE_GCC3_PFE_SUPPORT = YES;
INFOPLIST_FILE = "Info-JuceAU.plist";
INSTALL_PATH = "/Library/Audio/Plug-Ins/Components/";
OTHER_REZFLAGS = "-d ppc_$ppc -d i386_$i386 -I / -I /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CarbonCore.framework/Versions/A/Headers";
PRODUCT_NAME = "$(AU_NAME)";
SECTORDER_FLAGS = "";
WARNING_CFLAGS = (
"-Wmost",
"-Wno-four-char-constants",
"-Wno-unknown-pragmas",
"-Wno-non-virtual-dtor",
);
WRAPPER_EXTENSION = component;
ZERO_LINK = NO;
};
name = Debug;
};
A9E884AF0874ABE600B2DFE8 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = YES;
EXPORTED_SYMBOLS_FILE = JuceAU.exp;
FRAMEWORK_SEARCH_PATHS = "";
GCC_ENABLE_FIX_AND_CONTINUE = NO;
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_OPTIMIZATION_LEVEL = 3;
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
GCC_USE_GCC3_PFE_SUPPORT = YES;
INFOPLIST_FILE = "Info-JuceAU.plist";
INSTALL_PATH = "/Library/Audio/Plug-Ins/Components/";
OTHER_REZFLAGS = "-d ppc_$ppc -d i386_$i386 -I / -I /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CarbonCore.framework/Versions/A/Headers";
PRODUCT_NAME = "$(AU_NAME)";
SECTORDER_FLAGS = "";
WARNING_CFLAGS = (
"-Wmost",
"-Wno-four-char-constants",
"-Wno-unknown-pragmas",
"-Wno-non-virtual-dtor",
);
WRAPPER_EXTENSION = component;
ZERO_LINK = NO;
};
name = Release;
};
A9E884BA0874ABE600B2DFE8 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 845FAE5E0A5C0A6A008C94D8 /* juce.xcconfig */;
buildSettings = {
AU_NAME = DemoJuceAudioUnit;
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
HEADER_SEARCH_PATHS = ../../../../../;
LIBRARY_SEARCH_PATHS = ../../../../../bin;
};
name = Debug;
};
A9E884BB0874ABE600B2DFE8 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 845FAE5E0A5C0A6A008C94D8 /* juce.xcconfig */;
buildSettings = {
AU_NAME = DemoJuceAudioUnit;
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
HEADER_SEARCH_PATHS = ../../../../../;
LIBRARY_SEARCH_PATHS = ../../../../../bin;
};
name = Release;
};
/* End XCBuildConfiguration section */

/* Begin XCConfigurationList section */
A9E884AD0874ABE600B2DFE8 /* Build configuration list for PBXNativeTarget "JuceAU" */ = {
isa = XCConfigurationList;
buildConfigurations = (
A9E884AE0874ABE600B2DFE8 /* Debug */,
A9E884AF0874ABE600B2DFE8 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
A9E884B90874ABE600B2DFE8 /* Build configuration list for PBXProject "JuceDemoAU" */ = {
isa = XCConfigurationList;
buildConfigurations = (
A9E884BA0874ABE600B2DFE8 /* Debug */,
A9E884BB0874ABE600B2DFE8 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
/* End XCConfigurationList section */
};
rootObject = F5AA99BA0281A61201C34293 /* Project object */;
}

+ 32
- 0
extras/audio plugins/demo/build/RTAS_Mac/Info.plist View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>EXECUTABLE_NAME</string>
<key>CFBundleGetInfoString</key>
<string>VERSION_STR</string>
<key>CFBundleIdentifier</key>
<string>com.rawmaterialsoftware.JuceDemo</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>PRODUCT_NAME</string>
<key>CFBundlePackageType</key>
<string>TDMw</string>
<key>CFBundleShortVersionString</key>
<string>VERSION_STR</string>
<key>CFBundleSignature</key>
<string>PTul</string>
<key>CFBundleVersion</key>
<string>VERSION_NUM</string>
<key>LSMultipleInstancesProhibited</key>
<string>true</string>
<key>LSPrefersCarbon</key>
<true/>
<key>NSAppleScriptEnabled</key>
<string>No</string>
</dict>
</plist>

+ 414
- 0
extras/audio plugins/demo/build/RTAS_Mac/juce_RTASDemo.xcodeproj/project.pbxproj View File

@@ -0,0 +1,414 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 42;
objects = {

/* Begin PBXBuildFile section */
5B521CB1088F264F009C75FE /* System.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5B521CB0088F264F009C75FE /* System.framework */; };
841E07300AF9F015005E6FCC /* DemoEditorComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 841E072B0AF9F015005E6FCC /* DemoEditorComponent.cpp */; };
841E07310AF9F015005E6FCC /* DemoJuceFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 841E072D0AF9F015005E6FCC /* DemoJuceFilter.cpp */; };
841E07390AF9F055005E6FCC /* juce_AudioFilterBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 841E07350AF9F055005E6FCC /* juce_AudioFilterBase.cpp */; };
841E073A0AF9F055005E6FCC /* juce_AudioFilterEditor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 841E07370AF9F055005E6FCC /* juce_AudioFilterEditor.cpp */; };
841E073D0AF9F099005E6FCC /* juce_RTASUtilities.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 841E073B0AF9F099005E6FCC /* juce_RTASUtilities.cpp */; };
841E073E0AF9F099005E6FCC /* juce_RTASWrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 841E073C0AF9F099005E6FCC /* juce_RTASWrapper.cpp */; };
846444EF0AFA005B00E7B2BE /* juce_Wrapper_CEffectGroup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 846444E20AFA005B00E7B2BE /* juce_Wrapper_CEffectGroup.cpp */; };
846444F00AFA005B00E7B2BE /* juce_Wrapper_CEffectGroupMIDI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 846444E30AFA005B00E7B2BE /* juce_Wrapper_CEffectGroupMIDI.cpp */; };
846444F10AFA005B00E7B2BE /* juce_Wrapper_CEffectMIDIUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 846444E40AFA005B00E7B2BE /* juce_Wrapper_CEffectMIDIUtils.cpp */; };
846444F20AFA005B00E7B2BE /* juce_Wrapper_CEffectProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 846444E50AFA005B00E7B2BE /* juce_Wrapper_CEffectProcess.cpp */; };
846444F30AFA005B00E7B2BE /* juce_Wrapper_CEffectProcessAS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 846444E60AFA005B00E7B2BE /* juce_Wrapper_CEffectProcessAS.cpp */; };
846444F40AFA005B00E7B2BE /* juce_Wrapper_CEffectProcessMIDI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 846444E70AFA005B00E7B2BE /* juce_Wrapper_CEffectProcessMIDI.cpp */; };
846444F50AFA005B00E7B2BE /* juce_Wrapper_CEffectType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 846444E80AFA005B00E7B2BE /* juce_Wrapper_CEffectType.cpp */; };
846444F60AFA005B00E7B2BE /* juce_Wrapper_CEffectTypeRTAS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 846444E90AFA005B00E7B2BE /* juce_Wrapper_CEffectTypeRTAS.cpp */; };
846444F70AFA005B00E7B2BE /* juce_Wrapper_ChunkDataParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 846444EA0AFA005B00E7B2BE /* juce_Wrapper_ChunkDataParser.cpp */; };
846444FA0AFA005B00E7B2BE /* juce_Wrapper_PlugInUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 846444EE0AFA005B00E7B2BE /* juce_Wrapper_PlugInUtils.cpp */; };
846445020AFA00D800E7B2BE /* libPluginLibrary.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 841E066C0AF8E7A2005E6FCC /* libPluginLibrary.a */; };
846445060AFA010800E7B2BE /* AGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 846445040AFA010800E7B2BE /* AGL.framework */; };
846445070AFA010800E7B2BE /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 846445050AFA010800E7B2BE /* CoreAudio.framework */; };
8464450A0AFA012100E7B2BE /* QuickTime.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 846445090AFA012100E7B2BE /* QuickTime.framework */; };
84C9D7FB0AFA3C9C00F1348E /* juce_Wrapper_Dispatcher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84C9D7F90AFA3C9C00F1348E /* juce_Wrapper_Dispatcher.cpp */; };
84C9D7FC0AFA3C9C00F1348E /* juce_Wrapper_PluginInitialize.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84C9D7FA0AFA3C9C00F1348E /* juce_Wrapper_PluginInitialize.cpp */; };
84EEB4180AFB6679009655FF /* DummyResourceFile.r in Rez */ = {isa = PBXBuildFile; fileRef = 84EEB4170AFB6679009655FF /* DummyResourceFile.r */; };
84FDB0120C15BBCE00CD0087 /* libjuce.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 84FDB0100C15BBA500CD0087 /* libjuce.a */; };
8D01CCCE0486CAD60068D4B7 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 08EA7FFBFE8413EDC02AAC07 /* Carbon.framework */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
841E066B0AF8E7A2005E6FCC /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 5B521CEB08916D36009C75FE /* PluginLibrary.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = B65B09B30860FB0800FE2E6A;
remoteInfo = "Plugin Library";
};
841E07590AF9F2E7005E6FCC /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 5B521CEB08916D36009C75FE /* PluginLibrary.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = B65B09B20860FB0800FE2E6A;
remoteInfo = "Plugin Library";
};
84FDB00F0C15BBA500CD0087 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 846444D70AF9FFDB00E7B2BE /* Juce.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = D2AAC046055464E500DB518D;
remoteInfo = Juce;
};
/* End PBXContainerItemProxy section */

/* Begin PBXFileReference section */
08EA7FFBFE8413EDC02AAC07 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; };
5B521CB0088F264F009C75FE /* System.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = System.framework; path = /System/Library/Frameworks/System.framework; sourceTree = "<absolute>"; };
5B521CEB08916D36009C75FE /* PluginLibrary.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = PluginLibrary.xcodeproj; path = /Users/jules/stuff/PT_711_SDK/AlturaPorts/TDMPlugIns/PlugInLibrary/MacBuild/PluginLibrary.xcodeproj; sourceTree = "<absolute>"; };
841E072B0AF9F015005E6FCC /* DemoEditorComponent.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DemoEditorComponent.cpp; path = ../../src/DemoEditorComponent.cpp; sourceTree = SOURCE_ROOT; };
841E072C0AF9F015005E6FCC /* DemoEditorComponent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = DemoEditorComponent.h; path = ../../src/DemoEditorComponent.h; sourceTree = SOURCE_ROOT; };
841E072D0AF9F015005E6FCC /* DemoJuceFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DemoJuceFilter.cpp; path = ../../src/DemoJuceFilter.cpp; sourceTree = SOURCE_ROOT; };
841E072E0AF9F015005E6FCC /* DemoJuceFilter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = DemoJuceFilter.h; path = ../../src/DemoJuceFilter.h; sourceTree = SOURCE_ROOT; };
841E072F0AF9F015005E6FCC /* JucePluginCharacteristics.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JucePluginCharacteristics.h; path = ../../src/JucePluginCharacteristics.h; sourceTree = SOURCE_ROOT; };
841E07350AF9F055005E6FCC /* juce_AudioFilterBase.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_AudioFilterBase.cpp; path = ../../../wrapper/juce_AudioFilterBase.cpp; sourceTree = SOURCE_ROOT; };
841E07360AF9F055005E6FCC /* juce_AudioFilterBase.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = juce_AudioFilterBase.h; path = ../../../wrapper/juce_AudioFilterBase.h; sourceTree = SOURCE_ROOT; };
841E07370AF9F055005E6FCC /* juce_AudioFilterEditor.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_AudioFilterEditor.cpp; path = ../../../wrapper/juce_AudioFilterEditor.cpp; sourceTree = SOURCE_ROOT; };
841E07380AF9F055005E6FCC /* juce_AudioFilterEditor.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = juce_AudioFilterEditor.h; path = ../../../wrapper/juce_AudioFilterEditor.h; sourceTree = SOURCE_ROOT; };
841E073B0AF9F099005E6FCC /* juce_RTASUtilities.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_RTASUtilities.cpp; path = ../../../wrapper/formats/RTAS/juce_RTASUtilities.cpp; sourceTree = SOURCE_ROOT; };
841E073C0AF9F099005E6FCC /* juce_RTASWrapper.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_RTASWrapper.cpp; path = ../../../wrapper/formats/RTAS/juce_RTASWrapper.cpp; sourceTree = SOURCE_ROOT; };
841E07420AF9F126005E6FCC /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; path = Info.plist; sourceTree = "<group>"; };
846444D70AF9FFDB00E7B2BE /* Juce.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Juce.xcodeproj; path = ../../../../../build/macosx/Juce.xcodeproj; sourceTree = SOURCE_ROOT; };
846444E20AFA005B00E7B2BE /* juce_Wrapper_CEffectGroup.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Wrapper_CEffectGroup.cpp; path = ../../../wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectGroup.cpp; sourceTree = SOURCE_ROOT; };
846444E30AFA005B00E7B2BE /* juce_Wrapper_CEffectGroupMIDI.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Wrapper_CEffectGroupMIDI.cpp; path = ../../../wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectGroupMIDI.cpp; sourceTree = SOURCE_ROOT; };
846444E40AFA005B00E7B2BE /* juce_Wrapper_CEffectMIDIUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Wrapper_CEffectMIDIUtils.cpp; path = ../../../wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectMIDIUtils.cpp; sourceTree = SOURCE_ROOT; };
846444E50AFA005B00E7B2BE /* juce_Wrapper_CEffectProcess.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Wrapper_CEffectProcess.cpp; path = ../../../wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectProcess.cpp; sourceTree = SOURCE_ROOT; };
846444E60AFA005B00E7B2BE /* juce_Wrapper_CEffectProcessAS.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Wrapper_CEffectProcessAS.cpp; path = ../../../wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectProcessAS.cpp; sourceTree = SOURCE_ROOT; };
846444E70AFA005B00E7B2BE /* juce_Wrapper_CEffectProcessMIDI.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Wrapper_CEffectProcessMIDI.cpp; path = ../../../wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectProcessMIDI.cpp; sourceTree = SOURCE_ROOT; };
846444E80AFA005B00E7B2BE /* juce_Wrapper_CEffectType.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Wrapper_CEffectType.cpp; path = ../../../wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectType.cpp; sourceTree = SOURCE_ROOT; };
846444E90AFA005B00E7B2BE /* juce_Wrapper_CEffectTypeRTAS.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Wrapper_CEffectTypeRTAS.cpp; path = ../../../wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectTypeRTAS.cpp; sourceTree = SOURCE_ROOT; };
846444EA0AFA005B00E7B2BE /* juce_Wrapper_ChunkDataParser.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Wrapper_ChunkDataParser.cpp; path = ../../../wrapper/formats/RTAS/wrappers/juce_Wrapper_ChunkDataParser.cpp; sourceTree = SOURCE_ROOT; };
846444ED0AFA005B00E7B2BE /* juce_Wrapper_Header.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = juce_Wrapper_Header.h; path = ../../../wrapper/formats/RTAS/wrappers/juce_Wrapper_Header.h; sourceTree = SOURCE_ROOT; };
846444EE0AFA005B00E7B2BE /* juce_Wrapper_PlugInUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Wrapper_PlugInUtils.cpp; path = ../../../wrapper/formats/RTAS/wrappers/juce_Wrapper_PlugInUtils.cpp; sourceTree = SOURCE_ROOT; };
846445040AFA010800E7B2BE /* AGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AGL.framework; path = /System/Library/Frameworks/AGL.framework; sourceTree = "<absolute>"; };
846445050AFA010800E7B2BE /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = /System/Library/Frameworks/CoreAudio.framework; sourceTree = "<absolute>"; };
846445090AFA012100E7B2BE /* QuickTime.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuickTime.framework; path = /System/Library/Frameworks/QuickTime.framework; sourceTree = "<absolute>"; };
84C442690B306D39003FCBFF /* CommonReleaseSettings.xcconfig */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xcconfig; name = CommonReleaseSettings.xcconfig; path = /Users/jules/stuff/PT_711_SDK/AlturaPorts/TDMPlugIns/common/Mac/CommonReleaseSettings.xcconfig; sourceTree = "<absolute>"; };
84C4426A0B306D39003FCBFF /* CommonDebugSettings.xcconfig */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xcconfig; name = CommonDebugSettings.xcconfig; path = /Users/jules/stuff/PT_711_SDK/AlturaPorts/TDMPlugIns/common/Mac/CommonDebugSettings.xcconfig; sourceTree = "<absolute>"; };
84C9D7F90AFA3C9C00F1348E /* juce_Wrapper_Dispatcher.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Wrapper_Dispatcher.cpp; path = ../../../wrapper/formats/RTAS/wrappers/juce_Wrapper_Dispatcher.cpp; sourceTree = SOURCE_ROOT; };
84C9D7FA0AFA3C9C00F1348E /* juce_Wrapper_PluginInitialize.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_Wrapper_PluginInitialize.cpp; path = ../../../wrapper/formats/RTAS/wrappers/juce_Wrapper_PluginInitialize.cpp; sourceTree = SOURCE_ROOT; };
84EEB4170AFB6679009655FF /* DummyResourceFile.r */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.rez; name = DummyResourceFile.r; path = ../../../wrapper/formats/RTAS/DummyResourceFile.r; sourceTree = SOURCE_ROOT; };
84F5CF5F0B1B705E00A2E279 /* juce_RTASCompileFlags.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = juce_RTASCompileFlags.h; path = ../../../wrapper/formats/RTAS/juce_RTASCompileFlags.h; sourceTree = SOURCE_ROOT; };
8D01CCD20486CAD60068D4B7 /* JuceRTASDemo.dpm */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = JuceRTASDemo.dpm; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
8D01CCCD0486CAD60068D4B7 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
84FDB0120C15BBCE00CD0087 /* libjuce.a in Frameworks */,
846445020AFA00D800E7B2BE /* libPluginLibrary.a in Frameworks */,
8D01CCCE0486CAD60068D4B7 /* Carbon.framework in Frameworks */,
5B521CB1088F264F009C75FE /* System.framework in Frameworks */,
846445060AFA010800E7B2BE /* AGL.framework in Frameworks */,
846445070AFA010800E7B2BE /* CoreAudio.framework in Frameworks */,
8464450A0AFA012100E7B2BE /* QuickTime.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
089C166AFE841209C02AAC07 /* ProjectTemplate */ = {
isa = PBXGroup;
children = (
84C442690B306D39003FCBFF /* CommonReleaseSettings.xcconfig */,
84C4426A0B306D39003FCBFF /* CommonDebugSettings.xcconfig */,
08FB77ADFE841716C02AAC07 /* Source */,
089C167CFE841241C02AAC07 /* Resources */,
089C1671FE841209C02AAC07 /* External Frameworks and Libraries */,
19C28FB4FE9D528D11CA2CBB /* Products */,
);
name = ProjectTemplate;
sourceTree = "<group>";
};
089C1671FE841209C02AAC07 /* External Frameworks and Libraries */ = {
isa = PBXGroup;
children = (
846445040AFA010800E7B2BE /* AGL.framework */,
846445050AFA010800E7B2BE /* CoreAudio.framework */,
846445090AFA012100E7B2BE /* QuickTime.framework */,
846444D70AF9FFDB00E7B2BE /* Juce.xcodeproj */,
5B521CEB08916D36009C75FE /* PluginLibrary.xcodeproj */,
5B521CB0088F264F009C75FE /* System.framework */,
08EA7FFBFE8413EDC02AAC07 /* Carbon.framework */,
);
name = "External Frameworks and Libraries";
sourceTree = "<group>";
};
089C167CFE841241C02AAC07 /* Resources */ = {
isa = PBXGroup;
children = (
84EEB4170AFB6679009655FF /* DummyResourceFile.r */,
841E07420AF9F126005E6FCC /* Info.plist */,
);
name = Resources;
sourceTree = "<group>";
};
08FB77ADFE841716C02AAC07 /* Source */ = {
isa = PBXGroup;
children = (
841E07270AF9EFE2005E6FCC /* filter */,
841E072A0AF9EFEF005E6FCC /* wrapper */,
);
name = Source;
sourceTree = "<group>";
};
19C28FB4FE9D528D11CA2CBB /* Products */ = {
isa = PBXGroup;
children = (
8D01CCD20486CAD60068D4B7 /* JuceRTASDemo.dpm */,
);
name = Products;
sourceTree = "<group>";
};
841E06680AF8E7A2005E6FCC /* Products */ = {
isa = PBXGroup;
children = (
841E066C0AF8E7A2005E6FCC /* libPluginLibrary.a */,
);
name = Products;
sourceTree = "<group>";
};
841E07270AF9EFE2005E6FCC /* filter */ = {
isa = PBXGroup;
children = (
841E072B0AF9F015005E6FCC /* DemoEditorComponent.cpp */,
841E072C0AF9F015005E6FCC /* DemoEditorComponent.h */,
841E072D0AF9F015005E6FCC /* DemoJuceFilter.cpp */,
841E072E0AF9F015005E6FCC /* DemoJuceFilter.h */,
841E072F0AF9F015005E6FCC /* JucePluginCharacteristics.h */,
);
name = filter;
sourceTree = "<group>";
};
841E072A0AF9EFEF005E6FCC /* wrapper */ = {
isa = PBXGroup;
children = (
841E07350AF9F055005E6FCC /* juce_AudioFilterBase.cpp */,
841E07360AF9F055005E6FCC /* juce_AudioFilterBase.h */,
841E07370AF9F055005E6FCC /* juce_AudioFilterEditor.cpp */,
841E07380AF9F055005E6FCC /* juce_AudioFilterEditor.h */,
841E07340AF9F02D005E6FCC /* rtas specific */,
);
name = wrapper;
sourceTree = "<group>";
};
841E07340AF9F02D005E6FCC /* rtas specific */ = {
isa = PBXGroup;
children = (
846444E10AFA003B00E7B2BE /* Digi code wrappers */,
841E073B0AF9F099005E6FCC /* juce_RTASUtilities.cpp */,
841E073C0AF9F099005E6FCC /* juce_RTASWrapper.cpp */,
84F5CF5F0B1B705E00A2E279 /* juce_RTASCompileFlags.h */,
);
name = "rtas specific";
sourceTree = "<group>";
};
846444E10AFA003B00E7B2BE /* Digi code wrappers */ = {
isa = PBXGroup;
children = (
84C9D7F90AFA3C9C00F1348E /* juce_Wrapper_Dispatcher.cpp */,
84C9D7FA0AFA3C9C00F1348E /* juce_Wrapper_PluginInitialize.cpp */,
846444E20AFA005B00E7B2BE /* juce_Wrapper_CEffectGroup.cpp */,
846444E30AFA005B00E7B2BE /* juce_Wrapper_CEffectGroupMIDI.cpp */,
846444E40AFA005B00E7B2BE /* juce_Wrapper_CEffectMIDIUtils.cpp */,
846444E50AFA005B00E7B2BE /* juce_Wrapper_CEffectProcess.cpp */,
846444E60AFA005B00E7B2BE /* juce_Wrapper_CEffectProcessAS.cpp */,
846444E70AFA005B00E7B2BE /* juce_Wrapper_CEffectProcessMIDI.cpp */,
846444E80AFA005B00E7B2BE /* juce_Wrapper_CEffectType.cpp */,
846444E90AFA005B00E7B2BE /* juce_Wrapper_CEffectTypeRTAS.cpp */,
846444EA0AFA005B00E7B2BE /* juce_Wrapper_ChunkDataParser.cpp */,
846444ED0AFA005B00E7B2BE /* juce_Wrapper_Header.h */,
846444EE0AFA005B00E7B2BE /* juce_Wrapper_PlugInUtils.cpp */,
);
name = "Digi code wrappers";
sourceTree = "<group>";
};
84FDB00C0C15BBA500CD0087 /* Products */ = {
isa = PBXGroup;
children = (
84FDB0100C15BBA500CD0087 /* libjuce.a */,
);
name = Products;
sourceTree = "<group>";
};
/* End PBXGroup section */

/* Begin PBXNativeTarget section */
8D01CCC60486CAD60068D4B7 /* JuceRTASDemo */ = {
isa = PBXNativeTarget;
buildConfigurationList = 5B521C99088F2389009C75FE /* Build configuration list for PBXNativeTarget "JuceRTASDemo" */;
buildPhases = (
8D01CCCB0486CAD60068D4B7 /* Sources */,
8D01CCCD0486CAD60068D4B7 /* Frameworks */,
5B521D370891748B009C75FE /* Rez */,
);
buildRules = (
);
dependencies = (
841E075A0AF9F2E7005E6FCC /* PBXTargetDependency */,
);
name = JuceRTASDemo;
productInstallPath = "$(HOME)/Library/Bundles";
productName = ProjectTemplate;
productReference = 8D01CCD20486CAD60068D4B7 /* JuceRTASDemo.dpm */;
productType = "com.apple.product-type.bundle";
};
/* End PBXNativeTarget section */

/* Begin PBXProject section */
089C1669FE841209C02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 5B521C9D088F2389009C75FE /* Build configuration list for PBXProject "juce_RTASDemo" */;
hasScannedForEncodings = 1;
mainGroup = 089C166AFE841209C02AAC07 /* ProjectTemplate */;
projectDirPath = "";
projectReferences = (
{
ProductGroup = 84FDB00C0C15BBA500CD0087 /* Products */;
ProjectRef = 846444D70AF9FFDB00E7B2BE /* Juce.xcodeproj */;
},
{
ProductGroup = 841E06680AF8E7A2005E6FCC /* Products */;
ProjectRef = 5B521CEB08916D36009C75FE /* PluginLibrary.xcodeproj */;
},
);
targets = (
8D01CCC60486CAD60068D4B7 /* JuceRTASDemo */,
);
};
/* End PBXProject section */

/* Begin PBXReferenceProxy section */
841E066C0AF8E7A2005E6FCC /* libPluginLibrary.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libPluginLibrary.a;
remoteRef = 841E066B0AF8E7A2005E6FCC /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
84FDB0100C15BBA500CD0087 /* libjuce.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libjuce.a;
remoteRef = 84FDB00F0C15BBA500CD0087 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
/* End PBXReferenceProxy section */

/* Begin PBXRezBuildPhase section */
5B521D370891748B009C75FE /* Rez */ = {
isa = PBXRezBuildPhase;
buildActionMask = 2147483647;
files = (
84EEB4180AFB6679009655FF /* DummyResourceFile.r in Rez */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXRezBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
8D01CCCB0486CAD60068D4B7 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
841E07300AF9F015005E6FCC /* DemoEditorComponent.cpp in Sources */,
841E07310AF9F015005E6FCC /* DemoJuceFilter.cpp in Sources */,
841E07390AF9F055005E6FCC /* juce_AudioFilterBase.cpp in Sources */,
841E073A0AF9F055005E6FCC /* juce_AudioFilterEditor.cpp in Sources */,
841E073D0AF9F099005E6FCC /* juce_RTASUtilities.cpp in Sources */,
841E073E0AF9F099005E6FCC /* juce_RTASWrapper.cpp in Sources */,
846444EF0AFA005B00E7B2BE /* juce_Wrapper_CEffectGroup.cpp in Sources */,
846444F00AFA005B00E7B2BE /* juce_Wrapper_CEffectGroupMIDI.cpp in Sources */,
846444F10AFA005B00E7B2BE /* juce_Wrapper_CEffectMIDIUtils.cpp in Sources */,
846444F20AFA005B00E7B2BE /* juce_Wrapper_CEffectProcess.cpp in Sources */,
846444F30AFA005B00E7B2BE /* juce_Wrapper_CEffectProcessAS.cpp in Sources */,
846444F40AFA005B00E7B2BE /* juce_Wrapper_CEffectProcessMIDI.cpp in Sources */,
846444F50AFA005B00E7B2BE /* juce_Wrapper_CEffectType.cpp in Sources */,
846444F60AFA005B00E7B2BE /* juce_Wrapper_CEffectTypeRTAS.cpp in Sources */,
846444F70AFA005B00E7B2BE /* juce_Wrapper_ChunkDataParser.cpp in Sources */,
846444FA0AFA005B00E7B2BE /* juce_Wrapper_PlugInUtils.cpp in Sources */,
84C9D7FB0AFA3C9C00F1348E /* juce_Wrapper_Dispatcher.cpp in Sources */,
84C9D7FC0AFA3C9C00F1348E /* juce_Wrapper_PluginInitialize.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */

/* Begin PBXTargetDependency section */
841E075A0AF9F2E7005E6FCC /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = "Plugin Library";
targetProxy = 841E07590AF9F2E7005E6FCC /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */

/* Begin XCBuildConfiguration section */
5B521C9A088F2389009C75FE /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
};
name = Debug;
};
5B521C9E088F2389009C75FE /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 84C4426A0B306D39003FCBFF /* CommonDebugSettings.xcconfig */;
buildSettings = {
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
MacBag = /Users/jules/stuff/PT_711_SDK/MacBag;
PRODUCT_NAME = JuceRTASDemo;
USER_HEADER_SEARCH_PATHS = "/Users/jules/code/juce $(inherited)";
};
name = Debug;
};
5BEA73AA09E4370600964A97 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
};
name = Release;
};
5BEA73AB09E4370600964A97 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 84C442690B306D39003FCBFF /* CommonReleaseSettings.xcconfig */;
buildSettings = {
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
MacBag = /Users/jules/stuff/PT_711_SDK/MacBag;
PRODUCT_NAME = JuceRTASDemo;
USER_HEADER_SEARCH_PATHS = "/Users/jules/code/juce $(inherited)";
};
name = Release;
};
/* End XCBuildConfiguration section */

/* Begin XCConfigurationList section */
5B521C99088F2389009C75FE /* Build configuration list for PBXNativeTarget "JuceRTASDemo" */ = {
isa = XCConfigurationList;
buildConfigurations = (
5B521C9A088F2389009C75FE /* Debug */,
5BEA73AA09E4370600964A97 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
5B521C9D088F2389009C75FE /* Build configuration list for PBXProject "juce_RTASDemo" */ = {
isa = XCConfigurationList;
buildConfigurations = (
5B521C9E088F2389009C75FE /* Debug */,
5BEA73AB09E4370600964A97 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
/* End XCConfigurationList section */
};
rootObject = 089C1669FE841209C02AAC07 /* Project object */;
}

+ 49
- 0
extras/audio plugins/demo/build/RTAS_Win32/juce_RTAS.sln View File

@@ -0,0 +1,49 @@

Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "juce_RTAS", "juce_RTAS.vcproj", "{2EB09DDD-CF48-45ED-9698-6C5ADF123C98}"
ProjectSection(ProjectDependencies) = postProject
{AE232C11-D91C-4CA1-B24E-8B11A52EFF26} = {AE232C11-D91C-4CA1-B24E-8B11A52EFF26}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JUCE", "..\..\..\..\..\build\win32\vc8\JUCE.vcproj", "{AE232C11-D91C-4CA1-B24E-8B11A52EFF26}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug DLL|Win32 = Debug DLL|Win32
Debug|Win32 = Debug|Win32
DLL Debug|Win32 = DLL Debug|Win32
DLL Release|Win32 = DLL Release|Win32
Release DLL|Win32 = Release DLL|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{2EB09DDD-CF48-45ED-9698-6C5ADF123C98}.Debug DLL|Win32.ActiveCfg = Debug|Win32
{2EB09DDD-CF48-45ED-9698-6C5ADF123C98}.Debug DLL|Win32.Build.0 = Debug|Win32
{2EB09DDD-CF48-45ED-9698-6C5ADF123C98}.Debug|Win32.ActiveCfg = Debug|Win32
{2EB09DDD-CF48-45ED-9698-6C5ADF123C98}.Debug|Win32.Build.0 = Debug|Win32
{2EB09DDD-CF48-45ED-9698-6C5ADF123C98}.DLL Debug|Win32.ActiveCfg = Debug|Win32
{2EB09DDD-CF48-45ED-9698-6C5ADF123C98}.DLL Debug|Win32.Build.0 = Debug|Win32
{2EB09DDD-CF48-45ED-9698-6C5ADF123C98}.DLL Release|Win32.ActiveCfg = Release|Win32
{2EB09DDD-CF48-45ED-9698-6C5ADF123C98}.DLL Release|Win32.Build.0 = Release|Win32
{2EB09DDD-CF48-45ED-9698-6C5ADF123C98}.Release DLL|Win32.ActiveCfg = Release|Win32
{2EB09DDD-CF48-45ED-9698-6C5ADF123C98}.Release DLL|Win32.Build.0 = Release|Win32
{2EB09DDD-CF48-45ED-9698-6C5ADF123C98}.Release|Win32.ActiveCfg = Release|Win32
{2EB09DDD-CF48-45ED-9698-6C5ADF123C98}.Release|Win32.Build.0 = Release|Win32
{AE232C11-D91C-4CA1-B24E-8B11A52EFF26}.Debug DLL|Win32.ActiveCfg = Debug|Win32
{AE232C11-D91C-4CA1-B24E-8B11A52EFF26}.Debug DLL|Win32.Build.0 = Debug|Win32
{AE232C11-D91C-4CA1-B24E-8B11A52EFF26}.Debug|Win32.ActiveCfg = Debug|Win32
{AE232C11-D91C-4CA1-B24E-8B11A52EFF26}.Debug|Win32.Build.0 = Debug|Win32
{AE232C11-D91C-4CA1-B24E-8B11A52EFF26}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32
{AE232C11-D91C-4CA1-B24E-8B11A52EFF26}.DLL Debug|Win32.Build.0 = DLL Debug|Win32
{AE232C11-D91C-4CA1-B24E-8B11A52EFF26}.DLL Release|Win32.ActiveCfg = DLL Release|Win32
{AE232C11-D91C-4CA1-B24E-8B11A52EFF26}.DLL Release|Win32.Build.0 = DLL Release|Win32
{AE232C11-D91C-4CA1-B24E-8B11A52EFF26}.Release DLL|Win32.ActiveCfg = Release|Win32
{AE232C11-D91C-4CA1-B24E-8B11A52EFF26}.Release DLL|Win32.Build.0 = Release|Win32
{AE232C11-D91C-4CA1-B24E-8B11A52EFF26}.Release|Win32.ActiveCfg = Release|Win32
{AE232C11-D91C-4CA1-B24E-8B11A52EFF26}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

+ 649
- 0
extras/audio plugins/demo/build/RTAS_Win32/juce_RTAS.vcproj View File

@@ -0,0 +1,649 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="juce_RTAS"
ProjectGUID="{2EB09DDD-CF48-45ED-9698-6C5ADF123C98}"
RootNamespace="juce_RTAS"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="0"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
CommandLine="copy /Y ..\..\..\wrapper\formats\RTAS\DefaultResourceFile &quot;$(TargetPath)&quot;.rsr&#x0D;&#x0A;"
Outputs="$(TargetPath).rsr"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../src"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;JUCE_RTAS_EXPORTS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)\$(ProjectName).dpm"
LinkIncremental="2"
AdditionalLibraryDirectories=""
IgnoreDefaultLibraryNames="libcmtd.lib"
ModuleDefinitionFile="../../../wrapper/formats/RTAS/juce_RTAS_dlldefs.def"
GenerateDebugInformation="true"
SubSystem="2"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="0"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
CommandLine="copy /Y ..\..\..\wrapper\formats\RTAS\DefaultResourceFile &quot;$(TargetPath)&quot;.rsr&#x0D;&#x0A;"
Outputs="$(TargetPath).rsr"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../src"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;JUCE_RTAS_EXPORTS"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
CallingConvention="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)\$(ProjectName).dpm"
LinkIncremental="1"
IgnoreDefaultLibraryNames="libcmt.lib"
ModuleDefinitionFile="../../../wrapper/formats/RTAS/juce_RTAS_dlldefs.def"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<Filter
Name="filter"
>
<File
RelativePath="..\..\src\DemoEditorComponent.cpp"
>
</File>
<File
RelativePath="..\..\src\DemoEditorComponent.h"
>
</File>
<File
RelativePath="..\..\src\DemoJuceFilter.cpp"
>
</File>
<File
RelativePath="..\..\src\DemoJuceFilter.h"
>
</File>
<File
RelativePath="..\..\src\JucePluginCharacteristics.h"
>
</File>
</Filter>
<Filter
Name="wrapper code"
>
<File
RelativePath="..\..\..\wrapper\juce_AudioFilterBase.cpp"
>
</File>
<File
RelativePath="..\..\..\wrapper\juce_AudioFilterBase.h"
>
</File>
<File
RelativePath="..\..\..\wrapper\juce_AudioFilterEditor.cpp"
>
</File>
<File
RelativePath="..\..\..\wrapper\juce_AudioFilterEditor.h"
>
</File>
<Filter
Name="RTAS specific"
>
<File
RelativePath="..\..\..\wrapper\formats\RTAS\juce_RTASCompileFlags.h"
>
</File>
<File
RelativePath="..\..\..\wrapper\formats\RTAS\juce_RTASUtilities.cpp"
>
</File>
<File
RelativePath="..\..\..\wrapper\formats\RTAS\juce_RTASWrapper.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
CallingConvention="2"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CallingConvention="2"
/>
</FileConfiguration>
</File>
<Filter
Name="cpp wrappers"
>
<File
RelativePath="..\..\..\wrapper\formats\RTAS\juce_RTAS_dlldefs.def"
>
</File>
<File
RelativePath="..\..\..\wrapper\formats\RTAS\wrappers\juce_Wrapper_CEffectGroup.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
CallingConvention="2"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CallingConvention="2"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\..\wrapper\formats\RTAS\wrappers\juce_Wrapper_CEffectGroupMIDI.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
CallingConvention="2"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CallingConvention="2"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\..\wrapper\formats\RTAS\wrappers\juce_Wrapper_CEffectMIDIUtils.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
CallingConvention="2"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CallingConvention="2"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\..\wrapper\formats\RTAS\wrappers\juce_Wrapper_CEffectProcess.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
CallingConvention="2"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CallingConvention="2"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\..\wrapper\formats\RTAS\wrappers\juce_Wrapper_CEffectProcessAS.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
CallingConvention="2"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CallingConvention="2"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\..\wrapper\formats\RTAS\wrappers\juce_Wrapper_CEffectProcessMIDI.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
CallingConvention="2"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CallingConvention="2"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\..\wrapper\formats\RTAS\wrappers\juce_Wrapper_CEffectType.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
CallingConvention="2"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CallingConvention="2"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\..\wrapper\formats\RTAS\wrappers\juce_Wrapper_CEffectTypeRTAS.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
CallingConvention="2"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CallingConvention="2"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\..\wrapper\formats\RTAS\wrappers\juce_Wrapper_ChunkDataParser.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
CallingConvention="2"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CallingConvention="2"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\..\wrapper\formats\RTAS\wrappers\juce_Wrapper_DefaultSwap.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
CallingConvention="2"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CallingConvention="2"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\..\wrapper\formats\RTAS\wrappers\juce_Wrapper_DLLMain.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
CallingConvention="2"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CallingConvention="2"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\..\wrapper\formats\RTAS\wrappers\juce_Wrapper_Header.h"
>
</File>
<File
RelativePath="..\..\..\wrapper\formats\RTAS\wrappers\juce_Wrapper_PlugInUtils.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
CallingConvention="2"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CallingConvention="2"
/>
</FileConfiguration>
</File>
</Filter>
</Filter>
</Filter>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\resource.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
<File
RelativePath=".\juce_RTASDemo.rc"
>
</File>
</Filter>
<Filter
Name="libs"
>
<Filter
Name="debug"
>
<File
RelativePath="..\..\..\..\..\..\..\essentials\PT_711_SDK\WinBag\Debug\lib\DAE.lib"
>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCustomBuildTool"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\..\..\..\..\..\essentials\PT_711_SDK\WinBag\Debug\lib\DigiExt.lib"
>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCustomBuildTool"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\..\..\..\..\..\essentials\PT_711_SDK\WinBag\Debug\lib\DSI.lib"
>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCustomBuildTool"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\..\..\..\..\..\essentials\PT_711_SDK\WinBag\Debug\lib\PlugInLib.lib"
>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCustomBuildTool"
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="release"
>
<File
RelativePath="..\..\..\..\..\..\..\essentials\PT_711_SDK\WinBag\Release\lib\DAE.lib"
>
<FileConfiguration
Name="Debug|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCustomBuildTool"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\..\..\..\..\..\essentials\PT_711_SDK\WinBag\Release\lib\DigiExt.lib"
>
<FileConfiguration
Name="Debug|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCustomBuildTool"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\..\..\..\..\..\essentials\PT_711_SDK\WinBag\Release\lib\DSI.lib"
>
<FileConfiguration
Name="Debug|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCustomBuildTool"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\..\..\..\..\..\essentials\PT_711_SDK\WinBag\Release\lib\PlugInLib.lib"
>
<FileConfiguration
Name="Debug|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCustomBuildTool"
/>
</FileConfiguration>
</File>
</Filter>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

+ 112
- 0
extras/audio plugins/demo/build/RTAS_Win32/juce_RTASDemo.rc View File

@@ -0,0 +1,112 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// English (U.K.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,1
PRODUCTVERSION 1,0,0,1
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "080904b0"
BEGIN
VALUE "FileDescription", "Juce Audio Plugin RTAS Demo"
VALUE "FileVersion", "1, 0, 0, 1"
VALUE "InternalName", "Juce RTAS Demo"
VALUE "LegalCopyright", "Copyright (C) 2006"
VALUE "ProductName", "Juce RTAS Demo"
VALUE "ProductVersion", "1, 0, 0, 1"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x809, 1200
END
END
#endif // English (U.K.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

+ 14
- 0
extras/audio plugins/demo/build/RTAS_Win32/resource.h View File

@@ -0,0 +1,14 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by juce_RTASDemo.rc
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 101
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

+ 28
- 0
extras/audio plugins/demo/build/VST_Mac/Info.plist View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>JuceVST</string>
<key>CFBundleGetInfoString</key>
<string>Juce VST Demo plugin</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>com.rawmaterialsoftware.JuceVSTDemo</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>JuceVST</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string></string>
<key>CFBundleSignature</key>
<string>JUCE</string>
<key>CFBundleVersion</key>
<string>0.0.1</string>
</dict>
</plist>

+ 22
- 0
extras/audio plugins/demo/build/VST_Mac/JuceVST-Info.plist View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>JuceVST</string>
<key>CFBundleIdentifier</key>
<string>com.rawmaterialsoftware.JuceVST</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>1.0</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>CSResourcesFileMapped</key>
<string>yes</string>
</dict>
</plist>

+ 301
- 0
extras/audio plugins/demo/build/VST_Mac/JuceVST.xcodeproj/project.pbxproj View File

@@ -0,0 +1,301 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 42;
objects = {

/* Begin PBXBuildFile section */
8456E9D008A29AE60087C412 /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8456E9CF08A29AE60087C412 /* CoreServices.framework */; };
845FAE4C0A5C09FA008C94D8 /* juce.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 845FAE4B0A5C09FA008C94D8 /* juce.xcconfig */; };
84BACBD20987847C0073300C /* juce_VstWrapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84BACBD10987847C0073300C /* juce_VstWrapper.cpp */; };
84E1AE51089EBAAA00E85E4F /* DemoEditorComponent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84E1AE4D089EBAAA00E85E4F /* DemoEditorComponent.cpp */; };
84E1AE52089EBAAA00E85E4F /* DemoJuceFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84E1AE4F089EBAAA00E85E4F /* DemoJuceFilter.cpp */; };
84E1AE59089EBAEA00E85E4F /* juce_AudioFilterBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84E1AE55089EBAEA00E85E4F /* juce_AudioFilterBase.cpp */; };
84E1AE5A089EBAEA00E85E4F /* juce_AudioFilterEditor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84E1AE57089EBAEA00E85E4F /* juce_AudioFilterEditor.cpp */; };
84E1AF2B089EBE4C00E85E4F /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84E1AF2A089EBE4C00E85E4F /* Carbon.framework */; };
84E1AF30089EBE5A00E85E4F /* QuickTime.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84E1AF2F089EBE5A00E85E4F /* QuickTime.framework */; };
84E1AF34089EBE6C00E85E4F /* AGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84E1AF33089EBE6C00E85E4F /* AGL.framework */; };
84E1AF38089EBF1300E85E4F /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84E1AF37089EBF1300E85E4F /* CoreAudio.framework */; };
84E1AF42089EBFD900E85E4F /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 84E1AF41089EBFD900E85E4F /* Info.plist */; };
84F5CF040B1B66B100A2E279 /* How to use this framework.txt in Resources */ = {isa = PBXBuildFile; fileRef = 84F5CF030B1B66B100A2E279 /* How to use this framework.txt */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
84551AA009BDB8F3009C9F3E /* JucePluginCharacteristics.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JucePluginCharacteristics.h; path = ../../src/JucePluginCharacteristics.h; sourceTree = SOURCE_ROOT; };
8456E9CF08A29AE60087C412 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = /System/Library/Frameworks/CoreServices.framework; sourceTree = "<absolute>"; };
845FAE4B0A5C09FA008C94D8 /* juce.xcconfig */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xcconfig; name = juce.xcconfig; path = ../../../../../build/macosx/juce.xcconfig; sourceTree = SOURCE_ROOT; };
84BACBD10987847C0073300C /* juce_VstWrapper.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_VstWrapper.cpp; path = ../../../wrapper/formats/VST/juce_VstWrapper.cpp; sourceTree = SOURCE_ROOT; };
84E1AE47089EBA6A00E85E4F /* JuceVST.vst */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = JuceVST.vst; sourceTree = BUILT_PRODUCTS_DIR; };
84E1AE4D089EBAAA00E85E4F /* DemoEditorComponent.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DemoEditorComponent.cpp; path = ../../src/DemoEditorComponent.cpp; sourceTree = SOURCE_ROOT; };
84E1AE4E089EBAAA00E85E4F /* DemoEditorComponent.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = DemoEditorComponent.h; path = ../../src/DemoEditorComponent.h; sourceTree = SOURCE_ROOT; };
84E1AE4F089EBAAA00E85E4F /* DemoJuceFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = DemoJuceFilter.cpp; path = ../../src/DemoJuceFilter.cpp; sourceTree = SOURCE_ROOT; };
84E1AE50089EBAAA00E85E4F /* DemoJuceFilter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = DemoJuceFilter.h; path = ../../src/DemoJuceFilter.h; sourceTree = SOURCE_ROOT; };
84E1AE55089EBAEA00E85E4F /* juce_AudioFilterBase.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_AudioFilterBase.cpp; path = ../../../wrapper/juce_AudioFilterBase.cpp; sourceTree = SOURCE_ROOT; };
84E1AE56089EBAEA00E85E4F /* juce_AudioFilterBase.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = juce_AudioFilterBase.h; path = ../../../wrapper/juce_AudioFilterBase.h; sourceTree = SOURCE_ROOT; };
84E1AE57089EBAEA00E85E4F /* juce_AudioFilterEditor.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = juce_AudioFilterEditor.cpp; path = ../../../wrapper/juce_AudioFilterEditor.cpp; sourceTree = SOURCE_ROOT; };
84E1AE58089EBAEA00E85E4F /* juce_AudioFilterEditor.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = juce_AudioFilterEditor.h; path = ../../../wrapper/juce_AudioFilterEditor.h; sourceTree = SOURCE_ROOT; };
84E1AF2A089EBE4C00E85E4F /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; };
84E1AF2F089EBE5A00E85E4F /* QuickTime.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuickTime.framework; path = /System/Library/Frameworks/QuickTime.framework; sourceTree = "<absolute>"; };
84E1AF33089EBE6C00E85E4F /* AGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AGL.framework; path = /System/Library/Frameworks/AGL.framework; sourceTree = "<absolute>"; };
84E1AF37089EBF1300E85E4F /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = /System/Library/Frameworks/CoreAudio.framework; sourceTree = "<absolute>"; };
84E1AF41089EBFD900E85E4F /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; path = Info.plist; sourceTree = SOURCE_ROOT; };
84F5CF030B1B66B100A2E279 /* How to use this framework.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; name = "How to use this framework.txt"; path = "../../../How to use this framework.txt"; sourceTree = SOURCE_ROOT; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
84E1AE45089EBA6A00E85E4F /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
84E1AF2B089EBE4C00E85E4F /* Carbon.framework in Frameworks */,
84E1AF30089EBE5A00E85E4F /* QuickTime.framework in Frameworks */,
84E1AF34089EBE6C00E85E4F /* AGL.framework in Frameworks */,
84E1AF38089EBF1300E85E4F /* CoreAudio.framework in Frameworks */,
8456E9D008A29AE60087C412 /* CoreServices.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
089C166AFE841209C02AAC07 /* JuceVST */ = {
isa = PBXGroup;
children = (
08FB77ADFE841716C02AAC07 /* Source */,
84F5CF030B1B66B100A2E279 /* How to use this framework.txt */,
089C167CFE841241C02AAC07 /* Resources */,
089C1671FE841209C02AAC07 /* External Frameworks and Libraries */,
19C28FB4FE9D528D11CA2CBB /* Products */,
);
name = JuceVST;
sourceTree = "<group>";
};
089C1671FE841209C02AAC07 /* External Frameworks and Libraries */ = {
isa = PBXGroup;
children = (
84E1AF2A089EBE4C00E85E4F /* Carbon.framework */,
8456E9CF08A29AE60087C412 /* CoreServices.framework */,
84E1AF37089EBF1300E85E4F /* CoreAudio.framework */,
84E1AF33089EBE6C00E85E4F /* AGL.framework */,
84E1AF2F089EBE5A00E85E4F /* QuickTime.framework */,
);
name = "External Frameworks and Libraries";
sourceTree = "<group>";
};
089C167CFE841241C02AAC07 /* Resources */ = {
isa = PBXGroup;
children = (
84E1AF41089EBFD900E85E4F /* Info.plist */,
);
name = Resources;
sourceTree = "<group>";
};
08FB77ADFE841716C02AAC07 /* Source */ = {
isa = PBXGroup;
children = (
84E1AE4C089EBA9300E85E4F /* filter */,
84E1AE53089EBACA00E85E4F /* wrapper code */,
845FAE4B0A5C09FA008C94D8 /* juce.xcconfig */,
);
name = Source;
sourceTree = "<group>";
};
19C28FB4FE9D528D11CA2CBB /* Products */ = {
isa = PBXGroup;
children = (
84E1AE47089EBA6A00E85E4F /* JuceVST.vst */,
);
name = Products;
sourceTree = "<group>";
};
84E1AE4C089EBA9300E85E4F /* filter */ = {
isa = PBXGroup;
children = (
84E1AE4D089EBAAA00E85E4F /* DemoEditorComponent.cpp */,
84E1AE4E089EBAAA00E85E4F /* DemoEditorComponent.h */,
84E1AE4F089EBAAA00E85E4F /* DemoJuceFilter.cpp */,
84E1AE50089EBAAA00E85E4F /* DemoJuceFilter.h */,
84551AA009BDB8F3009C9F3E /* JucePluginCharacteristics.h */,
);
name = filter;
sourceTree = "<group>";
};
84E1AE53089EBACA00E85E4F /* wrapper code */ = {
isa = PBXGroup;
children = (
84E1AE55089EBAEA00E85E4F /* juce_AudioFilterBase.cpp */,
84E1AE56089EBAEA00E85E4F /* juce_AudioFilterBase.h */,
84E1AE57089EBAEA00E85E4F /* juce_AudioFilterEditor.cpp */,
84E1AE58089EBAEA00E85E4F /* juce_AudioFilterEditor.h */,
84E1AE54089EBAD200E85E4F /* VST specific */,
);
name = "wrapper code";
sourceTree = "<group>";
};
84E1AE54089EBAD200E85E4F /* VST specific */ = {
isa = PBXGroup;
children = (
84BACBD10987847C0073300C /* juce_VstWrapper.cpp */,
);
name = "VST specific";
sourceTree = "<group>";
};
/* End PBXGroup section */

/* Begin PBXNativeTarget section */
84E1AE46089EBA6A00E85E4F /* JuceVST */ = {
isa = PBXNativeTarget;
buildConfigurationList = 84E1AE48089EBA8900E85E4F /* Build configuration list for PBXNativeTarget "JuceVST" */;
buildPhases = (
84E1AE43089EBA6A00E85E4F /* Resources */,
84E1AE44089EBA6A00E85E4F /* Sources */,
84E1AE45089EBA6A00E85E4F /* Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = JuceVST;
productName = JuceVST;
productReference = 84E1AE47089EBA6A00E85E4F /* JuceVST.vst */;
productType = "com.apple.product-type.bundle";
};
/* End PBXNativeTarget section */

/* Begin PBXProject section */
089C1669FE841209C02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 84E1ADD2089EB1BA00E85E4F /* Build configuration list for PBXProject "JuceVST" */;
hasScannedForEncodings = 1;
mainGroup = 089C166AFE841209C02AAC07 /* JuceVST */;
projectDirPath = "";
targets = (
84E1AE46089EBA6A00E85E4F /* JuceVST */,
);
};
/* End PBXProject section */

/* Begin PBXResourcesBuildPhase section */
84E1AE43089EBA6A00E85E4F /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
84E1AF42089EBFD900E85E4F /* Info.plist in Resources */,
845FAE4C0A5C09FA008C94D8 /* juce.xcconfig in Resources */,
84F5CF040B1B66B100A2E279 /* How to use this framework.txt in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
84E1AE44089EBA6A00E85E4F /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
84E1AE51089EBAAA00E85E4F /* DemoEditorComponent.cpp in Sources */,
84E1AE52089EBAAA00E85E4F /* DemoJuceFilter.cpp in Sources */,
84E1AE59089EBAEA00E85E4F /* juce_AudioFilterBase.cpp in Sources */,
84E1AE5A089EBAEA00E85E4F /* juce_AudioFilterEditor.cpp in Sources */,
84BACBD20987847C0073300C /* juce_VstWrapper.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */

/* Begin XCBuildConfiguration section */
84E1ADD3089EB1BA00E85E4F /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 845FAE4B0A5C09FA008C94D8 /* juce.xcconfig */;
buildSettings = {
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = DEBUG;
HEADER_SEARCH_PATHS = (
../../../../..,
"~/stuff/vstsdk2.4/",
);
LIBRARY_SEARCH_PATHS = ../../../../../bin;
OTHER_LDFLAGS = "-ljucedebug";
};
name = Debug;
};
84E1ADD4089EB1BA00E85E4F /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 845FAE4B0A5C09FA008C94D8 /* juce.xcconfig */;
buildSettings = {
GCC_PREPROCESSOR_DEFINITIONS = NDEBUG;
HEADER_SEARCH_PATHS = (
../../../../..,
"~/stuff/vstsdk2.4/",
);
LIBRARY_SEARCH_PATHS = ../../../../../bin;
OTHER_LDFLAGS = "-ljuce";
};
name = Release;
};
84E1AE49089EBA8900E85E4F /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = NO;
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
GENERATE_PKGINFO_FILE = YES;
INFOPLIST_FILE = info.plist;
PRODUCT_NAME = JuceVST;
SYMROOT = "$(HOME)/Library/Audio/Plug-Ins/VST";
WARNING_CFLAGS = (
"-Wmost",
"-Wno-four-char-constants",
"-Wno-unknown-pragmas",
);
WRAPPER_EXTENSION = vst;
};
name = Debug;
};
84E1AE4A089EBA8900E85E4F /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = YES;
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
GENERATE_PKGINFO_FILE = YES;
INFOPLIST_FILE = info.plist;
PRODUCT_NAME = JuceVST;
SYMROOT = "$(HOME)/Library/Audio/Plug-Ins/VST";
WARNING_CFLAGS = (
"-Wmost",
"-Wno-four-char-constants",
"-Wno-unknown-pragmas",
);
WRAPPER_EXTENSION = vst;
};
name = Release;
};
/* End XCBuildConfiguration section */

/* Begin XCConfigurationList section */
84E1ADD2089EB1BA00E85E4F /* Build configuration list for PBXProject "JuceVST" */ = {
isa = XCConfigurationList;
buildConfigurations = (
84E1ADD3089EB1BA00E85E4F /* Debug */,
84E1ADD4089EB1BA00E85E4F /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
84E1AE48089EBA8900E85E4F /* Build configuration list for PBXNativeTarget "JuceVST" */ = {
isa = XCConfigurationList;
buildConfigurations = (
84E1AE49089EBA8900E85E4F /* Debug */,
84E1AE4A089EBA8900E85E4F /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
/* End XCConfigurationList section */
};
rootObject = 089C1669FE841209C02AAC07 /* Project object */;
}

+ 16
- 0
extras/audio plugins/demo/build/VST_Mac/version.plist View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildVersion</key>
<string>38</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>ProjectName</key>
<string>CarbonProjectTemplates</string>
<key>SourceVersion</key>
<string>140000</string>
</dict>
</plist>

+ 39
- 0
extras/audio plugins/demo/build/VST_Win32/juce_vst.sln View File

@@ -0,0 +1,39 @@

Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JuceAudioPlugin Demo", "juce_vst.vcproj", "{6F0F1E35-EAF8-431A-83D9-F0340921E560}"
ProjectSection(ProjectDependencies) = postProject
{AE232C11-D91C-4CA1-B24E-8B11A52EFF26} = {AE232C11-D91C-4CA1-B24E-8B11A52EFF26}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JUCE", "..\..\..\..\..\build\win32\vc8\JUCE.vcproj", "{AE232C11-D91C-4CA1-B24E-8B11A52EFF26}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
DLL Debug|Win32 = DLL Debug|Win32
DLL Release|Win32 = DLL Release|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{6F0F1E35-EAF8-431A-83D9-F0340921E560}.Debug|Win32.ActiveCfg = Debug|Win32
{6F0F1E35-EAF8-431A-83D9-F0340921E560}.Debug|Win32.Build.0 = Debug|Win32
{6F0F1E35-EAF8-431A-83D9-F0340921E560}.DLL Debug|Win32.ActiveCfg = Debug|Win32
{6F0F1E35-EAF8-431A-83D9-F0340921E560}.DLL Debug|Win32.Build.0 = Debug|Win32
{6F0F1E35-EAF8-431A-83D9-F0340921E560}.DLL Release|Win32.ActiveCfg = Release|Win32
{6F0F1E35-EAF8-431A-83D9-F0340921E560}.DLL Release|Win32.Build.0 = Release|Win32
{6F0F1E35-EAF8-431A-83D9-F0340921E560}.Release|Win32.ActiveCfg = Release|Win32
{6F0F1E35-EAF8-431A-83D9-F0340921E560}.Release|Win32.Build.0 = Release|Win32
{AE232C11-D91C-4CA1-B24E-8B11A52EFF26}.Debug|Win32.ActiveCfg = Debug|Win32
{AE232C11-D91C-4CA1-B24E-8B11A52EFF26}.Debug|Win32.Build.0 = Debug|Win32
{AE232C11-D91C-4CA1-B24E-8B11A52EFF26}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32
{AE232C11-D91C-4CA1-B24E-8B11A52EFF26}.DLL Debug|Win32.Build.0 = DLL Debug|Win32
{AE232C11-D91C-4CA1-B24E-8B11A52EFF26}.DLL Release|Win32.ActiveCfg = DLL Release|Win32
{AE232C11-D91C-4CA1-B24E-8B11A52EFF26}.DLL Release|Win32.Build.0 = DLL Release|Win32
{AE232C11-D91C-4CA1-B24E-8B11A52EFF26}.Release|Win32.ActiveCfg = Release|Win32
{AE232C11-D91C-4CA1-B24E-8B11A52EFF26}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

+ 288
- 0
extras/audio plugins/demo/build/VST_Win32/juce_vst.vcproj View File

@@ -0,0 +1,288 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="JuceAudioPlugin Demo"
ProjectGUID="{6F0F1E35-EAF8-431A-83D9-F0340921E560}"
RootNamespace="JuceAudioPlugin Demo"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC70.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="true"
SuppressStartupBanner="true"
TargetEnvironment="1"
TypeLibraryName=".\Debug/juce_vst.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../src"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;JUCE_VST_EXPORTS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
RuntimeTypeInfo="true"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Debug/juce_vst.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="2057"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Debug/juce_vst.dll"
LinkIncremental="2"
SuppressStartupBanner="true"
GenerateManifest="false"
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug/juce_vst.pdb"
ImportLibrary=".\Debug/juce_vst.lib"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\Debug/juce_vst.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="2"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC70.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="true"
SuppressStartupBanner="true"
TargetEnvironment="1"
TypeLibraryName=".\Release/juce_vst.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="3"
InlineFunctionExpansion="1"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
WholeProgramOptimization="true"
AdditionalIncludeDirectories="../../src"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;JUCE_VST_EXPORTS"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
RuntimeTypeInfo="true"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Release/juce_vst.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
WarningLevel="3"
SuppressStartupBanner="true"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="2057"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Release/juce_vst.dll"
LinkIncremental="1"
SuppressStartupBanner="true"
GenerateManifest="false"
ProgramDatabaseFile=".\Release/juce_vst.pdb"
ImportLibrary=".\Release/juce_vst.lib"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
SuppressStartupBanner="true"
OutputFile=".\Release/juce_vst.bsc"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
>
<Filter
Name="filter"
>
<File
RelativePath="..\..\src\DemoEditorComponent.cpp"
>
</File>
<File
RelativePath="..\..\src\DemoEditorComponent.h"
>
</File>
<File
RelativePath="..\..\src\DemoJuceFilter.cpp"
>
</File>
<File
RelativePath="..\..\src\DemoJuceFilter.h"
>
</File>
<File
RelativePath="..\..\src\JucePluginCharacteristics.h"
>
</File>
</Filter>
<Filter
Name="wrapper_code"
>
<File
RelativePath="..\..\..\wrapper\juce_AudioFilterBase.cpp"
>
</File>
<File
RelativePath="..\..\..\wrapper\juce_AudioFilterBase.h"
>
</File>
<File
RelativePath="..\..\..\wrapper\juce_AudioFilterEditor.cpp"
>
</File>
<File
RelativePath="..\..\..\wrapper\juce_AudioFilterEditor.h"
>
</File>
<Filter
Name="VST specific"
>
<File
RelativePath="..\..\..\wrapper\formats\VST\juce_VstWrapper.cpp"
>
</File>
</Filter>
</Filter>
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
>
</Filter>
<File
RelativePath="..\..\readme.txt"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

+ 210
- 0
extras/audio plugins/demo/src/DemoEditorComponent.cpp View File

@@ -0,0 +1,210 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "DemoEditorComponent.h"
//==============================================================================
// quick-and-dirty function to format a timecode string
static const String timeToTimecodeString (const double seconds)
{
const double absSecs = fabs (seconds);
const tchar* const sign = (seconds < 0) ? T("-") : T("");
const int hours = (int) (absSecs / (60.0 * 60.0));
const int mins = ((int) (absSecs / 60.0)) % 60;
const int secs = ((int) absSecs) % 60;
return String::formatted (T("%s%02d:%02d:%02d:%03d"),
sign, hours, mins, secs,
roundDoubleToInt (absSecs * 1000) % 1000);
}
// quick-and-dirty function to format a bars/beats string
static const String ppqToBarsBeatsString (const double ppq,
const double lastBarPPQ,
const int numerator,
const int denominator)
{
if (numerator == 0 || denominator == 0)
return T("1|1|0");
const int ppqPerBar = (numerator * 4 / denominator);
const double beats = (fmod (ppq, ppqPerBar) / ppqPerBar) * numerator;
const int bar = ((int) ppq) / ppqPerBar + 1;
const int beat = ((int) beats) + 1;
const int ticks = ((int) (fmod (beats, 1.0) * 960.0));
String s;
s << bar << T('|') << beat << T('|') << ticks;
return s;
}
//==============================================================================
// just a quick way of using a single static look and feel object without
// it getting leaked when the plugin is deleted..
class AutoDeletedLookAndFeel : public ShinyLookAndFeel,
public DeletedAtShutdown
{
public:
AutoDeletedLookAndFeel() {}
};
//==============================================================================
DemoEditorComponent::DemoEditorComponent (DemoJuceFilter* const ownerFilter)
: AudioFilterEditor (ownerFilter)
{
static ShinyLookAndFeel* shinyLook = 0;
if (shinyLook == 0)
shinyLook = new AutoDeletedLookAndFeel();
LookAndFeel::setDefaultLookAndFeel (shinyLook);
// create our gain slider..
addAndMakeVisible (gainSlider = new Slider (T("gain")));
gainSlider->addListener (this);
gainSlider->setRange (0.0, 1.0, 0.01);
gainSlider->setTooltip (T("changes the volume of the audio that runs through the plugin.."));
// get the gain parameter from the filter and use it to set up our slider
gainSlider->setValue (ownerFilter->getParameter (0), false);
// create and add the midi keyboard component..
addAndMakeVisible (midiKeyboard
= new MidiKeyboardComponent (ownerFilter->keyboardState,
MidiKeyboardComponent::horizontalKeyboard));
// add a label that will display the current timecode and status..
addAndMakeVisible (infoLabel = new Label (String::empty, String::empty));
// add the triangular resizer component for the bottom-right of the UI
addAndMakeVisible (resizer = new ResizableCornerComponent (this, &resizeLimits));
resizeLimits.setSizeLimits (150, 150, 800, 300);
// set our component's initial size to be the last one that was stored in the filter's settings
setSize (ownerFilter->lastUIWidth,
ownerFilter->lastUIHeight);
// register ourselves with the filter - it will use its ChangeBroadcaster base
// class to tell us when something has changed, and this will call our changeListenerCallback()
// method.
ownerFilter->addChangeListener (this);
}
DemoEditorComponent::~DemoEditorComponent()
{
getFilter()->removeChangeListener (this);
deleteAllChildren();
}
//==============================================================================
void DemoEditorComponent::paint (Graphics& g)
{
// just clear the window
g.fillAll (Colour::greyLevel (0.9f));
}
void DemoEditorComponent::resized()
{
gainSlider->setBounds (10, 10, 200, 22);
infoLabel->setBounds (10, 35, 450, 20);
const int keyboardHeight = 70;
midiKeyboard->setBounds (4, getHeight() - keyboardHeight - 4,
getWidth() - 8, keyboardHeight);
resizer->setBounds (getWidth() - 16, getHeight() - 16, 16, 16);
// if we've been resized, tell the filter so that it can store the new size
// in its settings
getFilter()->lastUIWidth = getWidth();
getFilter()->lastUIHeight = getHeight();
}
//==============================================================================
void DemoEditorComponent::changeListenerCallback (void* source)
{
// this is the filter telling us that it's changed, so we'll update our
// display of the time, midi message, etc.
updateParametersFromFilter();
}
void DemoEditorComponent::sliderValueChanged (Slider*)
{
getFilter()->setParameterNotifyingHost (0, (float) gainSlider->getValue());
}
//==============================================================================
void DemoEditorComponent::updateParametersFromFilter()
{
DemoJuceFilter* const filter = getFilter();
// we use this lock to make sure the processBlock() method isn't writing to the
// lastMidiMessage variable while we're trying to read it, but be extra-careful to
// only hold the lock for a minimum amount of time..
filter->getCallbackLock().enter();
// take a local copy of the info we need while we've got the lock..
const AudioFilterBase::CurrentPositionInfo positionInfo (filter->lastPosInfo);
const float newGain = filter->getParameter (0);
// ..release the lock ASAP
filter->getCallbackLock().exit();
// ..and after releasing the lock, we're free to do the time-consuming UI stuff..
String infoText;
infoText << String (positionInfo.bpm, 2) << T(" bpm, ")
<< positionInfo.timeSigNumerator << T("/") << positionInfo.timeSigDenominator
<< T(" - ") << timeToTimecodeString (positionInfo.timeInSeconds)
<< T(" - ") << ppqToBarsBeatsString (positionInfo.ppqPosition,
positionInfo.ppqPositionOfLastBarStart,
positionInfo.timeSigNumerator,
positionInfo.timeSigDenominator);
if (positionInfo.isPlaying)
infoText << T(" (playing)");
infoLabel->setText (infoText, false);
/* Update our slider.
(note that it's important here to tell the slider not to send a change
message, because that would cause it to call the filter with a parameter
change message again, and the values would drift out.
*/
gainSlider->setValue (newGain, false);
setSize (filter->lastUIWidth,
filter->lastUIHeight);
}

+ 99
- 0
extras/audio plugins/demo/src/DemoEditorComponent.h View File

@@ -0,0 +1,99 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#ifndef DEMOJUCEPLUGINEDITOR_H
#define DEMOJUCEPLUGINEDITOR_H
#include "DemoJuceFilter.h"
//==============================================================================
/**
This is the Component that our filter will use as its UI.
One or more of these is created by the DemoJuceFilter::createEditor() method,
and they will be deleted at some later time by the wrapper code.
To demonstrate the correct way of connecting a filter to its UI, this
class is a ChangeListener, and our demo filter is a ChangeBroadcaster. The
editor component registers with the filter when it's created and deregisters
when it's destroyed. When the filter's parameters are changed, it broadcasts
a message and this editor responds by updating its display.
*/
class DemoEditorComponent : public AudioFilterEditor,
public ChangeListener,
public SliderListener
{
public:
/** Constructor.
When created, this will register itself with the filter for changes. It's
safe to assume that the filter won't be deleted before this object is.
*/
DemoEditorComponent (DemoJuceFilter* const ownerFilter);
/** Destructor. */
~DemoEditorComponent();
//==============================================================================
/** Our demo filter is a ChangeBroadcaster, and will call us back when one of
its parameters changes.
*/
void changeListenerCallback (void* source);
void sliderValueChanged (Slider*);
//==============================================================================
/** Standard Juce paint callback. */
void paint (Graphics& g);
/** Standard Juce resize callback. */
void resized();
private:
//==============================================================================
Slider* gainSlider;
MidiKeyboardComponent* midiKeyboard;
Label* infoLabel;
ResizableCornerComponent* resizer;
ComponentBoundsConstrainer resizeLimits;
TooltipWindow tooltipWindow;
void updateParametersFromFilter();
// handy wrapper method to avoid having to cast the filter to a DemoJuceFilter
// every time we need it..
DemoJuceFilter* getFilter() const throw() { return (DemoJuceFilter*) getOwnerFilter(); }
};
#endif

+ 254
- 0
extras/audio plugins/demo/src/DemoJuceFilter.cpp View File

@@ -0,0 +1,254 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "DemoJuceFilter.h"
#include "DemoEditorComponent.h"
//==============================================================================
/**
This function must be implemented to create the actual plugin object that
you want to use.
*/
AudioFilterBase* createPluginFilter()
{
return new DemoJuceFilter();
}
//==============================================================================
DemoJuceFilter::DemoJuceFilter()
{
gain = 1.0f;
lastUIWidth = 400;
lastUIHeight = 140;
zeromem (&lastPosInfo, sizeof (lastPosInfo));
lastPosInfo.timeSigNumerator = 4;
lastPosInfo.timeSigDenominator = 4;
lastPosInfo.bpm = 120;
}
DemoJuceFilter::~DemoJuceFilter()
{
}
//==============================================================================
int DemoJuceFilter::getNumParameters()
{
return 1;
}
float DemoJuceFilter::getParameter (int index)
{
return (index == 0) ? gain
: 0.0f;
}
void DemoJuceFilter::setParameter (int index, float newValue)
{
if (index == 0)
{
if (gain != newValue)
{
gain = newValue;
// if this is changing the gain, broadcast a change message which
// our editor will pick up.
sendChangeMessage (this);
}
}
}
const String DemoJuceFilter::getParameterName (int index)
{
if (index == 0)
return T("gain");
return String::empty;
}
const String DemoJuceFilter::getParameterText (int index)
{
if (index == 0)
return String (gain, 2);
return String::empty;
}
//==============================================================================
void DemoJuceFilter::prepareToPlay (double sampleRate, int samplesPerBlock)
{
// do your pre-playback setup stuff here..
keyboardState.reset();
}
void DemoJuceFilter::releaseResources()
{
// when playback stops, you can use this as an opportunity to free up any
// spare memory, etc.
}
void DemoJuceFilter::processBlock (const AudioSampleBuffer& input,
AudioSampleBuffer& output,
const bool accumulateOutput,
MidiBuffer& midiMessages)
{
if (accumulateOutput)
{
// if we're accumulating, we should add our results to the existing contents of the
// output buffer..
if (input.getNumChannels() > 0)
{
for (int channel = 0; channel < output.getNumChannels(); ++channel)
{
// for each output channel, add the contents of the corresponding
// input channel (or if there are more outputs than inputs, just
// keep using the last input channel)
output.addFrom (channel,
0,
input,
jmin (channel, input.getNumChannels() - 1),
0,
input.getNumSamples(),
gain);
}
}
}
else
{
// if we're not accumulating, the output buffer's contents are undefined
// (don't assume they're zero!) and we should overwrite it.
if (input.getNumChannels() > 0)
{
for (int channel = 0; channel < output.getNumChannels(); ++channel)
{
// for each output channel, copy the contents of the corresponding
// input channel (or if there are more outputs than inputs, just
// keep using the last input channel)
output.copyFrom (channel,
0,
input,
jmin (channel, input.getNumChannels() - 1),
0,
input.getNumSamples());
}
output.applyGain (0, output.getNumSamples(), gain);
}
else
{
// when not accumulating, you always have to put something into
// the output buffer, even if in this case we have no inputs to copy.
output.clear();
}
}
// if any midi messages come in, use them to update the keyboard state object. This
// object sends notification to the UI component about key up/down changes
keyboardState.processNextMidiBuffer (midiMessages,
0, output.getNumSamples(),
true);
// have a go at getting the current time from the host, and if it's changed, tell
// our UI to update itself.
CurrentPositionInfo pos;
if (getCurrentPositionInfo (pos))
{
if (memcmp (&pos, &lastPosInfo, sizeof (pos)) != 0)
{
lastPosInfo = pos;
sendChangeMessage (this);
}
}
else
{
zeromem (&lastPosInfo, sizeof (lastPosInfo));
lastPosInfo.timeSigNumerator = 4;
lastPosInfo.timeSigDenominator = 4;
lastPosInfo.bpm = 120;
}
}
//==============================================================================
AudioFilterEditor* DemoJuceFilter::createEditor()
{
return new DemoEditorComponent (this);
}
//==============================================================================
void DemoJuceFilter::getStateInformation (JUCE_NAMESPACE::MemoryBlock& destData)
{
// you can store your parameters as binary data if you want to or if you've got
// a load of binary to put in there, but if you're not doing anything too heavy,
// XML is a much cleaner way of doing it - here's an example of how to store your
// params as XML..
// create an outer XML element..
XmlElement xmlState (T("MYPLUGINSETTINGS"));
// add some attributes to it..
xmlState.setAttribute (T("pluginVersion"), 1);
xmlState.setAttribute (T("gainLevel"), gain);
xmlState.setAttribute (T("uiWidth"), lastUIWidth);
xmlState.setAttribute (T("uiHeight"), lastUIHeight);
// you could also add as many child elements as you need to here..
// then use this helper function to stuff it into the binary blob and return it..
copyXmlToBinary (xmlState, destData);
}
void DemoJuceFilter::setStateInformation (const void* data, int sizeInBytes)
{
// use this helper function to get the XML from this binary blob..
XmlElement* const xmlState = getXmlFromBinary (data, sizeInBytes);
if (xmlState != 0)
{
// check that it's the right type of xml..
if (xmlState->hasTagName (T("MYPLUGINSETTINGS")))
{
// ok, now pull out our parameters..
gain = (float) xmlState->getDoubleAttribute (T("gainLevel"), gain);
lastUIWidth = xmlState->getIntAttribute (T("uiWidth"), lastUIWidth);
lastUIHeight = xmlState->getIntAttribute (T("uiHeight"), lastUIHeight);
sendChangeMessage (this);
}
delete xmlState;
}
}

+ 111
- 0
extras/audio plugins/demo/src/DemoJuceFilter.h View File

@@ -0,0 +1,111 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#ifndef DEMOJUCEPLUGINFILTER_H
#define DEMOJUCEPLUGINFILTER_H
#include "../../wrapper/juce_AudioFilterBase.h"
//==============================================================================
/**
A simple plugin filter that just applies a gain change to the audio
passing through it.
*/
class DemoJuceFilter : public AudioFilterBase,
public ChangeBroadcaster
{
public:
//==============================================================================
DemoJuceFilter();
~DemoJuceFilter();
//==============================================================================
void JUCE_CALLTYPE prepareToPlay (double sampleRate, int samplesPerBlock);
void JUCE_CALLTYPE releaseResources();
void JUCE_CALLTYPE processBlock (const AudioSampleBuffer& input,
AudioSampleBuffer& output,
const bool accumulateOutput,
MidiBuffer& midiMessages);
//==============================================================================
AudioFilterEditor* JUCE_CALLTYPE createEditor();
//==============================================================================
int JUCE_CALLTYPE getNumParameters();
float JUCE_CALLTYPE getParameter (int index);
void JUCE_CALLTYPE setParameter (int index, float newValue);
const String JUCE_CALLTYPE getParameterName (int index);
const String JUCE_CALLTYPE getParameterText (int index);
//==============================================================================
int JUCE_CALLTYPE getNumPrograms() { return 0; }
int JUCE_CALLTYPE getCurrentProgram() { return 0; }
void JUCE_CALLTYPE setCurrentProgram (int index) { }
const String JUCE_CALLTYPE getProgramName (int index) { return String::empty; }
void JUCE_CALLTYPE changeProgramName (int index, const String& newName) { }
//==============================================================================
void JUCE_CALLTYPE getStateInformation (JUCE_NAMESPACE::MemoryBlock& destData);
void JUCE_CALLTYPE setStateInformation (const void* data, int sizeInBytes);
//==============================================================================
// These properties are public so that our editor component can access them
// - a bit of a hacky way to do it, but it's only a demo!
// this is kept up to date with the midi messages that arrive, and the UI component
// registers with it so it can represent the incoming messages
MidiKeyboardState keyboardState;
// this keeps a copy of the last set of time info that was acquired during an audio
// callback - the UI component will read this and display it.
AudioFilterBase::CurrentPositionInfo lastPosInfo;
// these are used to persist the UI's size - the values are stored along with the
// filter's other parameters, and the UI component will update them when it gets
// resized.
int lastUIWidth, lastUIHeight;
//==============================================================================
juce_UseDebuggingNewOperator
private:
// this is our gain - the UI and the host can access this by getting/setting
// parameter 0.
float gain;
};
#endif

+ 274
- 0
extras/audio plugins/demo/src/JucePluginCharacteristics.h View File

@@ -0,0 +1,274 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#ifndef __JUCE_PLUGIN_CHARACTERISTICS_H__
#define __JUCE_PLUGIN_CHARACTERISTICS_H__
//==============================================================================
/* All of the following settings need to be defined for your plugin.
Go through each of these definitions and check that it's correctly
set-up before trying to do a build.
*/
//==============================================================================
/* Generic settings */
/** The name of your plugin. (Try to keep this as short as possible)
*/
#define JucePlugin_Name "Juce Demo Plugin"
/** A longer decription of your plugin.
*/
#define JucePlugin_Desc "A Demo Plugin demonstrating Juce"
/** The name of your company. (Try to keep this as short as possible)
*/
#define JucePlugin_Manufacturer "Raw Material Software"
/** A four-character code for your company.
Use single quotes - this isn't a string!
*/
#define JucePlugin_ManufacturerCode 'RawM'
/** A unique four-character code for your plugin.
Use single quotes - this isn't a string!
Note that for AU compatibility, this must contain at least one
upper-case letter.
*/
#define JucePlugin_PluginCode 'JcDm'
//==============================================================================
/** The maximum number of channels of audio input that the plugin can handle.
The actual number of channels supplied may be less than this, depending on the host.
For VSTs, you specify a maximum number of channels, for AUs and RTAS a set
of channel configurations is specified in JucePlugin_PreferredChannelConfigurations
and the host will choose one of these, but you should still set the max number of
channels correctly.
As soon as a plugin's prepareToPlay() method is called, you can find out the actual
number of channels that will be used with the AudioFilterBase::getNumInputChannels()
method.
*/
#define JucePlugin_MaxNumInputChannels 2
/** The maximum number of channels of audio output that the plugin can handle.
The actual number of channels supplied may be less than this, depending on the host.
For VSTs, you specify a maximum number of channels, for AUs and RTAS a set
of channel configurations is specified in JucePlugin_PreferredChannelConfigurations
and the host will choose one of these, but you should still set the max number of
channels correctly.
As soon as a plugin's prepareToPlay() method is called, you can find out the actual
number of channels that will be used with the AudioFilterBase::getNumOutputChannels()
method.
*/
#define JucePlugin_MaxNumOutputChannels 2
/** This allows the plugin to specify the configurations of input/output channels that
they can support.
AU and RTAS hosts will use this information, although VSTs only have a concept of
a maximum number of channels.
The list is a set of pairs of values in the form { numInputs, numOutputs }, and each
pair indicates a valid configuration that the plugin can handle.
So for example, {1, 1}, {2, 2} means that the plugin can be used in just two
configurations: either with 1 input and 1 output, or with 2 inputs and 2 outputs. If
you used this in Pro-Tools, the plugin could be placed on a mono or stereo track.
If the list was just {1, 1}, then Pro-Tools would only allow it to be used as a mono
plugin.
As soon as a plugin's prepareToPlay() method is called, you can find out the actual
number of channels that the host has connected to the plugin by using the
AudioFilterBase::getNumOutputChannels() and AudioFilterBase::getNumInputChannels()
methods.
*/
#define JucePlugin_PreferredChannelConfigurations { 1, 1 }, { 2, 2 }
//==============================================================================
/** The plugin's internal latency, as a number of samples.
*/
#define JucePlugin_Latency 0
/** Set this value to 1 if your plugin is a synth, or 0 if it isn't.
*/
#define JucePlugin_IsSynth 1
/** Set this to 1 if your plugin needs to receive midi messages, or 0 if
it doesn't.
*/
#define JucePlugin_WantsMidiInput 1
/** Set this to 1 if your plugin wants to output midi messages, or 0 if
it doesn't.
*/
#define JucePlugin_ProducesMidiOutput 1
/** If this is 1, it means that when the plugins input buffers are
silent, it's output will be too.
Some hosts may use this to avoid calling the plugin when no audio
would be produced.
*/
#define JucePlugin_SilenceInProducesSilenceOut 0
/** If set to 1, this hints that the host should ignore any keys that are pressed
when the plugin has keyboard focus. If 0, then the host should still execute
any shortcut keys that are pressed, even if the plugin does have focus.
Various hosts/platforms may deal with this differently, or ignore it.
*/
#define JucePlugin_EditorRequiresKeyboardFocus 1
//==============================================================================
/** A version number
*/
#define JucePlugin_VersionCode 0x00010100
#define JucePlugin_VersionString "1.1"
//==============================================================================
/* VST settings */
/** For VSTs, if you're compiling against the V2.3 SDK, set this to zero. If
you're using V2.4 or later, make sure it's set to 1.
*/
#define JUCE_USE_VSTSDK_2_4 1
/** Defines a UID for your VST plugin.
The default setting here is probably fine, unless you specifically need
a custom value. It's passed to the setUniqueID() method of the plugin class.
*/
#define JucePlugin_VSTUniqueID JucePlugin_PluginCode
/** Defines the type of plugin. For most pursposes, you don't need to change this
setting.
*/
#if JucePlugin_IsSynth
#define JucePlugin_VSTCategory kPlugCategSynth
#else
#define JucePlugin_VSTCategory kPlugCategEffect
#endif
//==============================================================================
/* AudioUnit settings */
/** Defines the major type of plugin - see AUComponent.h for the available options.
If it's an effect, you should use kAudioUnitType_Effect. For a synth, you'll
need to use kAudioUnitType_MusicEffect or kAudioUnitType_MusicDevice.
*/
#if JucePlugin_IsSynth
#define JucePlugin_AUMainType kAudioUnitType_MusicEffect
#else
#define JucePlugin_AUMainType kAudioUnitType_Effect
#endif
/** A 4-character plugin ID code that should be unique.
You can leave this using the generic value JucePlugin_PluginCode, or
override it if necessary.
Note that for AU, this must contain at least one upper-case letter.
*/
#define JucePlugin_AUSubType JucePlugin_PluginCode
/** A prefix for the names of exported entry-point functions that the component exposes.
It's very important that your plugin's .exp file contains two entries that correspond to
this name. So for example if you set the prefix to "abc" then your exports
file must contain:
_abcEntry
_abcViewEntry
*/
#define JucePlugin_AUExportPrefix JuceDemoAU
/** This is the same as JucePlugin_AUExportPrefix, but in quotes
(needed for the resource compiler...)
*/
#define JucePlugin_AUExportPrefixQuoted "JuceDemoAU"
/** A 4-character manufacturer code - this is your company name.
You can leave this using the generic value JucePlugin_ManufacturerCode, or
override it if necessary.
*/
#define JucePlugin_AUManufacturerCode JucePlugin_ManufacturerCode
/** If you define this value to be the same as the CFBundleIdentifier in your
plugin's plist, it allows the plugin to work out its own path, which is
needed if you want to use File::getSpecialLocation (currentExecutableFile)
*/
#define JucePlugin_CFBundleIdentifier "com.rawmaterialsoftware.JuceDemo"
//==============================================================================
/* RTAS settings */
/** How to categorise this plugin.
For a synth you probably want to set this to ePlugInCategory_SWGenerators.
For an effect, you could choose one of:
ePlugInCategory_None, ePlugInCategory_EQ, ePlugInCategory_Dynamics,
ePlugInCategory_PitchShift, ePlugInCategory_Reverb, ePlugInCategory_Delay,
ePlugInCategory_Modulation, ePlugInCategory_Harmonic, ePlugInCategory_NoiseReduction,
ePlugInCategory_Dither, ePlugInCategory_SoundField
(All values are listed in FicPluginEnums.h)
*/
#if JucePlugin_IsSynth
#define JucePlugin_RTASCategory ePlugInCategory_SWGenerators
#else
#define JucePlugin_RTASCategory ePlugInCategory_None
#endif
/** A 4-character manufacturer code - this is your company name.
You can leave this using the generic value JucePlugin_ManufacturerCode, or
override it if necessary.
*/
#define JucePlugin_RTASManufacturerCode JucePlugin_ManufacturerCode
/** A 4-character plugin ID code that should be unique.
You can leave this using the generic value JucePlugin_PluginCode, or
override it if necessary.
*/
#define JucePlugin_RTASProductId JucePlugin_PluginCode
//==============================================================================
#endif

+ 827
- 0
extras/audio plugins/wrapper/formats/AudioUnit/juce_AudioUnitWrapper.cpp View File

@@ -0,0 +1,827 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include <AudioUnit/AudioUnit.h>
#include "AUMIDIEffectBase.h"
#include "AUCarbonViewBase.h"
#include "../../juce_AudioFilterBase.h"
#include "../../juce_IncludeCharacteristics.h"
//==============================================================================
#define juceFilterObjectPropertyID 0x1a45ffe9
static VoidArray activePlugins;
static const short channelConfigs[][2] = { JucePlugin_PreferredChannelConfigurations };
static const int numChannelConfigs = numElementsInArray (channelConfigs);
BEGIN_JUCE_NAMESPACE
extern void juce_setCurrentExecutableFileNameFromBundleId (const String& bundleId);
END_JUCE_NAMESPACE
//==============================================================================
class JuceAU : public AUMIDIEffectBase,
public AudioFilterBase::FilterNativeCallbacks
{
public:
//==============================================================================
JuceAU (AudioUnit component)
: AUMIDIEffectBase (component),
juceFilter (0),
bufferSpace (2, 16),
prepared (false)
{
CreateElements();
if (activePlugins.size() == 0)
{
initialiseJuce_GUI();
#ifdef JucePlugin_CFBundleIdentifier
juce_setCurrentExecutableFileNameFromBundleId (JucePlugin_CFBundleIdentifier);
#endif
MessageManager::getInstance()->setTimeBeforeShowingWaitCursor (0);
}
juceFilter = createPluginFilter();
juceFilter->initialiseInternal (this);
jassert (juceFilter != 0);
Globals()->UseIndexedParameters (juceFilter->getNumParameters());
activePlugins.add (this);
}
~JuceAU()
{
delete juceFilter;
juceFilter = 0;
jassert (activePlugins.contains (this));
activePlugins.removeValue (this);
if (activePlugins.size() == 0)
shutdownJuce_GUI();
}
//==============================================================================
ComponentResult GetPropertyInfo (AudioUnitPropertyID inID,
AudioUnitScope inScope,
AudioUnitElement inElement,
UInt32& outDataSize,
Boolean& outWritable)
{
if (inScope == kAudioUnitScope_Global)
{
if (inID == juceFilterObjectPropertyID)
{
outWritable = false;
outDataSize = sizeof (void*);
return noErr;
}
}
return AUMIDIEffectBase::GetPropertyInfo (inID, inScope, inElement, outDataSize, outWritable);
}
ComponentResult GetProperty (AudioUnitPropertyID inID,
AudioUnitScope inScope,
AudioUnitElement inElement,
void* outData)
{
if (inScope == kAudioUnitScope_Global)
{
if (inID == juceFilterObjectPropertyID)
{
*((void**) outData) = (void*) juceFilter;
return noErr;
}
}
return AUMIDIEffectBase::GetProperty (inID, inScope, inElement, outData);
}
ComponentResult SaveState (CFPropertyListRef* outData)
{
ComponentResult err = AUMIDIEffectBase::SaveState (outData);
if (err != noErr)
return err;
jassert (CFGetTypeID (*outData) == CFDictionaryGetTypeID());
CFMutableDictionaryRef dict = (CFMutableDictionaryRef) *outData;
if (juceFilter != 0)
{
JUCE_NAMESPACE::MemoryBlock state;
juceFilter->getStateInformation (state);
if (state.getSize() > 0)
{
CFDataRef ourState = CFDataCreate (kCFAllocatorDefault, (const uint8*) state, state.getSize());
CFDictionarySetValue (dict, CFSTR("jucePluginState"), ourState);
CFRelease (ourState);
}
}
return noErr;
}
ComponentResult RestoreState (CFPropertyListRef inData)
{
ComponentResult err = AUMIDIEffectBase::RestoreState (inData);
if (err != noErr)
return err;
if (juceFilter != 0)
{
CFDictionaryRef dict = (CFDictionaryRef) inData;
CFDataRef data = 0;
if (CFDictionaryGetValueIfPresent (dict, CFSTR("jucePluginState"),
(const void**) &data))
{
if (data != 0)
{
const int numBytes = (int) CFDataGetLength (data);
const uint8* const rawBytes = CFDataGetBytePtr (data);
if (numBytes > 0)
juceFilter->setStateInformation (rawBytes, numBytes);
}
}
}
return noErr;
}
UInt32 SupportedNumChannels (const AUChannelInfo** outInfo)
{
if (juceFilter == 0)
return 0;
// You need to actually add some configurations to the JucePlugin_PreferredChannelConfigurations
// value in your JucePluginCharacteristics.h file..
jassert (numChannelConfigs > 0);
if (outInfo != 0)
{
for (int i = 0; i < numChannelConfigs; ++i)
{
channelInfo[i].inChannels = channelConfigs[i][0];
channelInfo[i].outChannels = channelConfigs[i][1];
outInfo[i] = channelInfo + i;
}
}
return numChannelConfigs;
}
//==============================================================================
ComponentResult GetParameterInfo (AudioUnitScope inScope,
AudioUnitParameterID inParameterID,
AudioUnitParameterInfo& outParameterInfo)
{
if (inScope == kAudioUnitScope_Global && juceFilter != 0)
{
outParameterInfo.flags = kAudioUnitParameterFlag_IsWritable
| kAudioUnitParameterFlag_IsReadable
| kAudioUnitParameterFlag_HasCFNameString;
outParameterInfo.name[0] = 0;
outParameterInfo.cfNameString = PlatformUtilities::juceStringToCFString (juceFilter->getParameterName ((int) inParameterID));
outParameterInfo.minValue = 0.0f;
outParameterInfo.maxValue = 1.0f;
outParameterInfo.defaultValue = 0.0f;
outParameterInfo.unit = kAudioUnitParameterUnit_Generic;
return noErr;
}
else
{
return kAudioUnitErr_InvalidParameter;
}
}
ComponentResult GetParameter (AudioUnitParameterID inID,
AudioUnitScope inScope,
AudioUnitElement inElement,
Float32& outValue)
{
if (inScope == kAudioUnitScope_Global && juceFilter != 0)
{
outValue = juceFilter->getParameter ((int) inID);
return noErr;
}
return AUBase::GetParameter (inID, inScope, inElement, outValue);
}
ComponentResult SetParameter (AudioUnitParameterID inID,
AudioUnitScope inScope,
AudioUnitElement inElement,
Float32 inValue,
UInt32 inBufferOffsetInFrames)
{
if (inScope == kAudioUnitScope_Global && juceFilter != 0)
{
juceFilter->setParameter ((int) inID, inValue);
return noErr;
}
return AUBase::SetParameter (inID, inScope, inElement, inValue, inBufferOffsetInFrames);
}
//==============================================================================
ComponentResult Version() { return JucePlugin_VersionCode; }
bool SupportsTail() { return true; }
Float64 GetTailTime() { return 0; }
Float64 GetLatency()
{
jassert (GetSampleRate() > 0);
if (GetSampleRate() <= 0)
return 0.0;
return (JucePlugin_Latency) / GetSampleRate();
}
//==============================================================================
int GetNumCustomUIComponents() { return 1; }
void GetUIComponentDescs (ComponentDescription* inDescArray)
{
inDescArray[0].componentType = kAudioUnitCarbonViewComponentType;
inDescArray[0].componentSubType = JucePlugin_AUSubType;
inDescArray[0].componentManufacturer = JucePlugin_AUManufacturerCode;
inDescArray[0].componentFlags = 0;
inDescArray[0].componentFlagsMask = 0;
}
//==============================================================================
bool getCurrentPositionInfo (AudioFilterBase::CurrentPositionInfo& info)
{
info.timeSigNumerator = 0;
info.timeSigDenominator = 0;
info.timeInSeconds = 0;
info.editOriginTime = 0;
info.ppqPositionOfLastBarStart = 0;
info.isPlaying = false;
info.isRecording = false;
switch (lastSMPTETime.mType)
{
case kSMPTETimeType24:
info.frameRate = AudioFilterBase::CurrentPositionInfo::fps24;
break;
case kSMPTETimeType25:
info.frameRate = AudioFilterBase::CurrentPositionInfo::fps25;
break;
case kSMPTETimeType30Drop:
info.frameRate = AudioFilterBase::CurrentPositionInfo::fps30drop;
break;
case kSMPTETimeType30:
info.frameRate = AudioFilterBase::CurrentPositionInfo::fps30;
break;
case kSMPTETimeType2997:
info.frameRate = AudioFilterBase::CurrentPositionInfo::fps2997;
break;
case kSMPTETimeType2997Drop:
info.frameRate = AudioFilterBase::CurrentPositionInfo::fps2997drop;
break;
//case kSMPTETimeType60:
//case kSMPTETimeType5994:
default:
info.frameRate = AudioFilterBase::CurrentPositionInfo::fpsUnknown;
break;
}
if (CallHostBeatAndTempo (&info.ppqPosition, &info.bpm) != noErr)
{
info.ppqPosition = 0;
info.bpm = 0;
}
UInt32 outDeltaSampleOffsetToNextBeat;
double outCurrentMeasureDownBeat;
float num;
UInt32 den;
if (CallHostMusicalTimeLocation (&outDeltaSampleOffsetToNextBeat, &num, &den,
&outCurrentMeasureDownBeat) == noErr)
{
info.timeSigNumerator = (int) num;
info.timeSigDenominator = den;
info.ppqPositionOfLastBarStart = outCurrentMeasureDownBeat;
}
double outCurrentSampleInTimeLine, outCycleStartBeat, outCycleEndBeat;
Boolean playing, playchanged, looping;
if (CallHostTransportState (&playing,
&playchanged,
&outCurrentSampleInTimeLine,
&looping,
&outCycleStartBeat,
&outCycleEndBeat) == noErr)
{
info.isPlaying = playing;
info.timeInSeconds = outCurrentSampleInTimeLine / GetSampleRate();
}
return true;
}
void informHostOfParameterChange (int index, float newValue)
{
if (juceFilter != 0)
{
juceFilter->setParameter (index, newValue);
if (AUEventListenerNotify != 0)
{
AudioUnitEvent e;
e.mEventType = kAudioUnitEvent_ParameterValueChange;
e.mArgument.mParameter.mAudioUnit = GetComponentInstance();
e.mArgument.mParameter.mParameterID = (AudioUnitParameterID) index;
e.mArgument.mParameter.mScope = kAudioUnitScope_Global;
e.mArgument.mParameter.mElement = 0;
AUEventListenerNotify (0, 0, &e);
}
}
}
//==============================================================================
ComponentResult Initialize()
{
AUMIDIEffectBase::Initialize();
prepareToPlay();
return noErr;
}
void Cleanup()
{
AUMIDIEffectBase::Cleanup();
if (juceFilter != 0)
juceFilter->releaseResources();
bufferSpace.setSize (2, 16);
midiEvents.clear();
prepared = false;
}
ComponentResult Reset (AudioUnitScope inScope, AudioUnitElement inElement)
{
if (! prepared)
prepareToPlay();
return AUMIDIEffectBase::Reset (inScope, inElement);
}
void prepareToPlay()
{
if (juceFilter != 0)
{
juceFilter->numInputChannels = GetInput(0)->GetStreamFormat().mChannelsPerFrame;
juceFilter->numOutputChannels = GetOutput(0)->GetStreamFormat().mChannelsPerFrame;
bufferSpace.setSize (juceFilter->numInputChannels + juceFilter->numOutputChannels,
GetMaxFramesPerSlice() + 32);
juceFilter->prepareToPlay (GetSampleRate(),
GetMaxFramesPerSlice());
midiEvents.clear();
prepared = true;
}
}
ComponentResult Render (AudioUnitRenderActionFlags &ioActionFlags,
const AudioTimeStamp& inTimeStamp,
UInt32 nFrames)
{
lastSMPTETime = inTimeStamp.mSMPTETime;
return AUMIDIEffectBase::Render (ioActionFlags, inTimeStamp, nFrames);
}
OSStatus ProcessBufferLists (AudioUnitRenderActionFlags& ioActionFlags,
const AudioBufferList& inBuffer,
AudioBufferList& outBuffer,
UInt32 inFramesToProcess)
{
if (juceFilter != 0)
{
jassert (prepared);
float* inChans [64];
int numInChans = 0;
float* outChans [64];
int numOutChans = 0;
int nextSpareBufferChan = 0;
bool needToReinterleave = false;
unsigned int i;
for (i = 0; i < inBuffer.mNumberBuffers; ++i)
{
const AudioBuffer& buf = inBuffer.mBuffers[i];
if (buf.mNumberChannels == 1)
{
inChans [numInChans++] = (float*) buf.mData;
}
else
{
// need to de-interleave..
for (unsigned int subChan = 0; subChan < buf.mNumberChannels; ++subChan)
{
float* dest = bufferSpace.getSampleData (nextSpareBufferChan++);
inChans [numInChans++] = dest;
const float* src = ((const float*) buf.mData) + subChan;
for (int j = inFramesToProcess; --j >= 0;)
{
*dest++ = *src;
src += buf.mNumberChannels;
}
}
}
if (numInChans >= juceFilter->numInputChannels)
break;
}
const int firstBufferedOutChan = nextSpareBufferChan;
for (i = 0; i < outBuffer.mNumberBuffers; ++i)
{
AudioBuffer& buf = outBuffer.mBuffers[i];
if (buf.mNumberChannels == 1)
{
outChans [numOutChans++] = (float*) buf.mData;
}
else
{
needToReinterleave = true;
for (unsigned int subChan = 0; subChan < buf.mNumberChannels; ++subChan)
{
float* dest = bufferSpace.getSampleData (nextSpareBufferChan++);
outChans [numOutChans++] = dest;
}
}
if (numOutChans >= juceFilter->numOutputChannels)
break;
}
const bool accumulate = false;
{
const AudioSampleBuffer input (inChans, numInChans, inFramesToProcess);
AudioSampleBuffer output (outChans, numOutChans, inFramesToProcess);
const ScopedLock sl (juceFilter->getCallbackLock());
if (juceFilter->suspended)
output.clear();
else
juceFilter->processBlock (input, output, accumulate, midiEvents);
}
if (! midiEvents.isEmpty())
{
#if JucePlugin_ProducesMidiOutput
const uint8* midiEventData;
int midiEventSize, midiEventPosition;
MidiBuffer::Iterator i (midiEvents);
while (i.getNextEvent (midiEventData, midiEventSize, midiEventPosition))
{
jassert (midiEventPosition >= 0 && midiEventPosition < (int) inFramesToProcess);
//xxx
}
#else
// if your plugin creates midi messages, you'll need to set
// the JucePlugin_ProducesMidiOutput macro to 1 in your
// JucePluginCharacteristics.h file
//jassert (midiEvents.getNumEvents() <= numMidiEventsComingIn);
#endif
midiEvents.clear();
}
if (needToReinterleave)
{
nextSpareBufferChan = firstBufferedOutChan;
for (i = 0; i < outBuffer.mNumberBuffers; ++i)
{
AudioBuffer& buf = outBuffer.mBuffers[i];
if (buf.mNumberChannels > 1)
{
for (unsigned int subChan = 0; subChan < buf.mNumberChannels; ++subChan)
{
const float* src = bufferSpace.getSampleData (nextSpareBufferChan++);
float* dest = ((float*) buf.mData) + subChan;
for (int j = inFramesToProcess; --j >= 0;)
{
*dest = *src++;
dest += buf.mNumberChannels;
}
}
}
}
}
#if ! JucePlugin_SilenceInProducesSilenceOut
ioActionFlags &= ~kAudioUnitRenderAction_OutputIsSilence;
#endif
}
return noErr;
}
protected:
OSStatus HandleMidiEvent (UInt8 nStatus,
UInt8 inChannel,
UInt8 inData1,
UInt8 inData2,
long inStartFrame)
{
#if JucePlugin_WantsMidiInput
uint8 data [4];
data[0] = nStatus | inChannel;
data[1] = inData1;
data[2] = inData2;
midiEvents.addEvent (data, 3, inStartFrame);
#endif
return noErr;
}
//==============================================================================
private:
AudioFilterBase* juceFilter;
AudioSampleBuffer bufferSpace;
MidiBuffer midiEvents;
bool prepared;
SMPTETime lastSMPTETime;
AUChannelInfo channelInfo [numChannelConfigs];
};
//==============================================================================
class JuceAUComponentHolder : public Component
{
public:
JuceAUComponentHolder (Component* const editorComp)
{
addAndMakeVisible (editorComp);
setOpaque (true);
setVisible (true);
setBroughtToFrontOnMouseClick (true);
#if ! JucePlugin_EditorRequiresKeyboardFocus
setWantsKeyboardFocus (false);
#endif
}
~JuceAUComponentHolder()
{
}
void resized()
{
if (getNumChildComponents() > 0)
getChildComponent (0)->setBounds (0, 0, getWidth(), getHeight());
}
void paint (Graphics& g)
{
}
};
//==============================================================================
class JuceAUView : public AUCarbonViewBase,
public ComponentListener,
public MouseListener,
public Timer
{
AudioFilterBase* juceFilter;
AudioFilterEditor* editorComp;
Component* windowComp;
bool recursive;
int mx, my;
public:
JuceAUView (AudioUnitCarbonView auview)
: AUCarbonViewBase (auview),
juceFilter (0),
editorComp (0),
windowComp (0),
recursive (false),
mx (0),
my (0)
{
}
~JuceAUView()
{
deleteUI();
}
ComponentResult CreateUI (Float32 inXOffset, Float32 inYOffset)
{
if (juceFilter == 0)
{
UInt32 propertySize = sizeof (&juceFilter);
AudioUnitGetProperty (GetEditAudioUnit(),
juceFilterObjectPropertyID,
kAudioUnitScope_Global,
0,
&juceFilter,
&propertySize);
}
if (juceFilter != 0)
{
deleteUI();
editorComp = juceFilter->createEditorIfNeeded();
const int w = editorComp->getWidth();
const int h = editorComp->getHeight();
editorComp->setOpaque (true);
editorComp->setVisible (true);
windowComp = new JuceAUComponentHolder (editorComp);
windowComp->setBounds ((int) inXOffset, (int) inYOffset, w, h);
windowComp->addToDesktop (0, (void*) mCarbonPane);
SizeControl (mCarbonPane, w, h);
editorComp->addComponentListener (this);
windowComp->addMouseListener (this, true);
startTimer (20);
}
else
{
jassertfalse // can't get a pointer to our effect
}
return noErr;
}
void componentMovedOrResized (Component& component,
bool wasMoved,
bool wasResized)
{
if (! recursive)
{
recursive = true;
if (editorComp != 0 && wasResized)
{
const int w = jmax (32, editorComp->getWidth());
const int h = jmax (32, editorComp->getHeight());
SizeControl (mCarbonPane, w, h);
if (windowComp->getWidth() != w
|| windowComp->getHeight() != h)
{
windowComp->setSize (w, h);
}
editorComp->repaint();
}
recursive = false;
}
}
void timerCallback()
{
// for some stupid Apple-related reason, mouse move events just don't seem to get sent
// to the windows in an AU, so we have to bodge it here and simulate them with a
// timer..
if (false && editorComp != 0)
{
int x, y;
Desktop::getInstance().getMousePosition (x, y);
if (x != mx || y != my)
{
mx = x;
my = y;
if (! ModifierKeys::getCurrentModifiers().isAnyMouseButtonDown())
{
for (int i = ComponentPeer::getNumPeers(); --i >= 0;)
{
ComponentPeer* const peer = ComponentPeer::getPeer (i);
const int rx = x - peer->getComponent()->getX();
const int ry = y - peer->getComponent()->getY();
if (peer->contains (rx, ry, false) && peer->getComponent()->isShowing())
{
peer->handleMouseMove (rx, ry, Time::currentTimeMillis());
break;
}
}
}
}
}
}
void mouseMove (const MouseEvent& e)
{
Desktop::getInstance().getMousePosition (mx, my);
startTimer (20);
}
private:
void deleteUI()
{
PopupMenu::dismissAllActiveMenus();
// there's some kind of component currently modal, but the host
// is trying to delete our plugin..
jassert (Component::getCurrentlyModalComponent() == 0);
if (editorComp != 0)
juceFilter->editorBeingDeleted (editorComp);
deleteAndZero (editorComp);
deleteAndZero (windowComp);
}
};
//==============================================================================
#define JUCE_COMPONENT_ENTRYX(Class, Name, Suffix) \
extern "C" __attribute__((visibility("default"))) ComponentResult Name ## Suffix (ComponentParameters* params, Class* obj); \
extern "C" __attribute__((visibility("default"))) ComponentResult Name ## Suffix (ComponentParameters* params, Class* obj) \
{ \
return ComponentEntryPoint<Class>::Dispatch(params, obj); \
}
#define JUCE_COMPONENT_ENTRY(Class, Name, Suffix) JUCE_COMPONENT_ENTRYX(Class, Name, Suffix)
JUCE_COMPONENT_ENTRY (JuceAU, JucePlugin_AUExportPrefix, Entry)
JUCE_COMPONENT_ENTRY (JuceAUView, JucePlugin_AUExportPrefix, ViewEntry)

+ 70
- 0
extras/audio plugins/wrapper/formats/AudioUnit/juce_AudioUnitWrapper.r View File

@@ -0,0 +1,70 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include <AudioUnit/AudioUnit.r>
#include <AudioUnit/AudioUnitCarbonView.r>
//==============================================================================
/* The JucePluginCharacteristics.h file is supposed to live in your plugin-specific
project directory, and has to contain info describing its name, type, etc. For
more info, see the JucePluginCharacteristics.h that is included in the demo plugin.
You may need to adjust the include path of your project to make sure it can be
found by this include statement. (Don't hack this file to change the include path)
*/
#include "JucePluginCharacteristics.h"
//==============================================================================
// component resources for Audio Unit
#define RES_ID 1000
#define COMP_TYPE JucePlugin_AUMainType
#define COMP_SUBTYPE JucePlugin_AUSubType
#define COMP_MANUF JucePlugin_AUManufacturerCode
#define VERSION JucePlugin_VersionCode
#define NAME JucePlugin_Manufacturer ": " JucePlugin_Name
#define DESCRIPTION JucePlugin_Desc
#define ENTRY_POINT JucePlugin_AUExportPrefixQuoted "Entry"
#include "/Developer/Examples/CoreAudio/AudioUnits/AUPublic/AUBase/AUResources.r"
//==============================================================================
// component resources for Audio Unit Carbon View
#define RES_ID 2000
#define COMP_TYPE kAudioUnitCarbonViewComponentType
#define COMP_SUBTYPE JucePlugin_AUSubType
#define COMP_MANUF JucePlugin_AUManufacturerCode
#define VERSION JucePlugin_VersionCode
#define NAME JucePlugin_Manufacturer ": " JucePlugin_Name " View"
#define DESCRIPTION NAME
#define ENTRY_POINT JucePlugin_AUExportPrefixQuoted "ViewEntry"
#include "/Developer/Examples/CoreAudio/AudioUnits/AUPublic/AUBase/AUResources.r"

BIN
extras/audio plugins/wrapper/formats/RTAS/DefaultResourceFile View File

Before After

+ 4
- 0
extras/audio plugins/wrapper/formats/RTAS/DummyResourceFile.r View File

@@ -0,0 +1,4 @@

// This dummy file is added to the resources section of the project to
// force XCode to create some resources for the dpm. If there aren't any
// resources, PT would refuse to load the plugin..

+ 63
- 0
extras/audio plugins/wrapper/formats/RTAS/juce_RTASCompileFlags.h View File

@@ -0,0 +1,63 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#ifndef __JUCE_RTASCOMPILEFLAGS_JUCEHEADER__
#define __JUCE_RTASCOMPILEFLAGS_JUCEHEADER__
#ifdef _MSC_VER
#define kCompileAsCodeResource 0
#define kBuildStandAlone 0
#define kNoDSP 0
#define kNoDAE 0
#define kNoSDS 0
#define kNoViews 0
#define kUseDSPCodeDecode 0
#define WINDOWS_VERSION 1
#define PLUGIN_SDK_BUILD 1
#define PLUGIN_SDK_DIRECTMIDI 1
#else
#define kCompileAsCodeResource 0
#define kNoDSP 1
#define kNoDAE 0
#define kNoSDS 0
#define kNoViews 0
#define kUseDSPCodeDecode 0
#define PLUGIN_SDK_BUILD 1
#define PLUGIN_SDK_DIRECTMIDI 1
#endif
#endif // __JUCE_RTASCOMPILEFLAGS_JUCEHEADER__

+ 131
- 0
extras/audio plugins/wrapper/formats/RTAS/juce_RTASUtilities.cpp View File

@@ -0,0 +1,131 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#if _MSC_VER
// (these functions are in a separate file because of problems including windows.h
// at the same time as the Digi headers)
#include <windows.h>
#include "../../juce_AudioFilterBase.h"
#include "../../juce_AudioFilterEditor.h"
//==============================================================================
void JUCE_CALLTYPE attachSubWindow (void* hostWindow,
int& titleW, int& titleH,
Component* comp)
{
RECT clientRect;
GetClientRect ((HWND) hostWindow, &clientRect);
titleW = clientRect.right - clientRect.left;
titleH = jmax (0, (clientRect.bottom - clientRect.top) - comp->getHeight());
comp->setTopLeftPosition (0, titleH);
comp->addToDesktop (0);
HWND plugWnd = (HWND) comp->getWindowHandle();
SetParent (plugWnd, (HWND) hostWindow);
DWORD val = GetWindowLong (plugWnd, GWL_STYLE);
val = (val & ~WS_POPUP) | WS_CHILD;
SetWindowLong (plugWnd, GWL_STYLE, val);
}
void JUCE_CALLTYPE resizeHostWindow (void* hostWindow,
int& titleW, int& titleH,
Component* comp)
{
RECT clientRect, windowRect;
GetClientRect ((HWND) hostWindow, &clientRect);
GetWindowRect ((HWND) hostWindow, &windowRect);
const int borderW = (windowRect.right - windowRect.left) - (clientRect.right - clientRect.left);
const int borderH = (windowRect.bottom - windowRect.top) - (clientRect.bottom - clientRect.top);
SetWindowPos ((HWND) hostWindow, 0, 0, 0,
borderW + jmax (titleW, comp->getWidth()),
borderH + comp->getHeight() + titleH,
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOOWNERZORDER);
}
#if ! JucePlugin_EditorRequiresKeyboardFocus
static HWND findMDIParentOf (HWND w)
{
const int frameThickness = GetSystemMetrics (SM_CYFIXEDFRAME);
while (w != 0)
{
HWND parent = GetParent (w);
if (parent == 0)
break;
TCHAR windowType [32];
zeromem (windowType, sizeof (windowType));
GetClassName (parent, windowType, 31);
if (String (windowType).equalsIgnoreCase (T("MDIClient")))
{
w = parent;
break;
}
RECT windowPos;
GetWindowRect (w, &windowPos);
RECT parentPos;
GetWindowRect (parent, &parentPos);
int dw = (parentPos.right - parentPos.left) - (windowPos.right - windowPos.left);
int dh = (parentPos.bottom - parentPos.top) - (windowPos.bottom - windowPos.top);
if (dw > 100 || dh > 100)
break;
w = parent;
if (dw == 2 * frameThickness)
break;
}
return w;
}
void JUCE_CALLTYPE passFocusToHostWindow (void* hostWindow)
{
SetFocus (findMDIParentOf ((HWND) hostWindow));
}
#endif
#endif

+ 1011
- 0
extras/audio plugins/wrapper/formats/RTAS/juce_RTASWrapper.cpp
File diff suppressed because it is too large
View File


+ 5
- 0
extras/audio plugins/wrapper/formats/RTAS/juce_RTAS_dlldefs.def View File

@@ -0,0 +1,5 @@
EXPORTS
NewPlugIn @1
_PI_GetRoutineDescriptor @2

+ 44
- 0
extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectGroup.cpp View File

@@ -0,0 +1,44 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "juce_Wrapper_Header.h"
/*
This file is used to include and build a digidesign CPP file without your project needing to
reference the file directly. Because the file will be located via the include path, this means
that the project doesn't have to change to cope with people's SDKs being in different locations.
Note about include paths
If you get an error including this file, check your paths - there's a full list of
Digidesign paths in juce_RTASWrapper.cpp
*/
#include "CEffectGroup.cpp"

+ 44
- 0
extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectGroupMIDI.cpp View File

@@ -0,0 +1,44 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "juce_Wrapper_Header.h"
/*
This file is used to include and build a digidesign CPP file without your project needing to
reference the file directly. Because the file will be located via the include path, this means
that the project doesn't have to change to cope with people's SDKs being in different locations.
Note about include paths
If you get an error including this file, check your paths - there's a full list of
Digidesign paths in juce_RTASWrapper.cpp
*/
#include "CEffectGroupMIDI.cpp"

+ 44
- 0
extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectMIDIUtils.cpp View File

@@ -0,0 +1,44 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "juce_Wrapper_Header.h"
/*
This file is used to include and build a digidesign CPP file without your project needing to
reference the file directly. Because the file will be located via the include path, this means
that the project doesn't have to change to cope with people's SDKs being in different locations.
Note about include paths
If you get an error including this file, check your paths - there's a full list of
Digidesign paths in juce_RTASWrapper.cpp
*/
#include "CEffectMIDIUtils.cpp"

+ 44
- 0
extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectProcess.cpp View File

@@ -0,0 +1,44 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "juce_Wrapper_Header.h"
/*
This file is used to include and build a digidesign CPP file without your project needing to
reference the file directly. Because the file will be located via the include path, this means
that the project doesn't have to change to cope with people's SDKs being in different locations.
Note about include paths
If you get an error including this file, check your paths - there's a full list of
Digidesign paths in juce_RTASWrapper.cpp
*/
#include "CEffectProcess.cpp"

+ 44
- 0
extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectProcessAS.cpp View File

@@ -0,0 +1,44 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "juce_Wrapper_Header.h"
/*
This file is used to include and build a digidesign CPP file without your project needing to
reference the file directly. Because the file will be located via the include path, this means
that the project doesn't have to change to cope with people's SDKs being in different locations.
Note about include paths
If you get an error including this file, check your paths - there's a full list of
Digidesign paths in juce_RTASWrapper.cpp
*/
#include "CEffectProcessAS.cpp"

+ 44
- 0
extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectProcessMIDI.cpp View File

@@ -0,0 +1,44 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "juce_Wrapper_Header.h"
/*
This file is used to include and build a digidesign CPP file without your project needing to
reference the file directly. Because the file will be located via the include path, this means
that the project doesn't have to change to cope with people's SDKs being in different locations.
Note about include paths
If you get an error including this file, check your paths - there's a full list of
Digidesign paths in juce_RTASWrapper.cpp
*/
#include "CEffectProcessMIDI.cpp"

+ 44
- 0
extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectType.cpp View File

@@ -0,0 +1,44 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "juce_Wrapper_Header.h"
/*
This file is used to include and build a digidesign CPP file without your project needing to
reference the file directly. Because the file will be located via the include path, this means
that the project doesn't have to change to cope with people's SDKs being in different locations.
Note about include paths
If you get an error including this file, check your paths - there's a full list of
Digidesign paths in juce_RTASWrapper.cpp
*/
#include "CEffectType.cpp"

+ 44
- 0
extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_CEffectTypeRTAS.cpp View File

@@ -0,0 +1,44 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "juce_Wrapper_Header.h"
/*
This file is used to include and build a digidesign CPP file without your project needing to
reference the file directly. Because the file will be located via the include path, this means
that the project doesn't have to change to cope with people's SDKs being in different locations.
Note about include paths
If you get an error including this file, check your paths - there's a full list of
Digidesign paths in juce_RTASWrapper.cpp
*/
#include "CEffectTypeRTAS.cpp"

+ 44
- 0
extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_ChunkDataParser.cpp View File

@@ -0,0 +1,44 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "juce_Wrapper_Header.h"
/*
This file is used to include and build a digidesign CPP file without your project needing to
reference the file directly. Because the file will be located via the include path, this means
that the project doesn't have to change to cope with people's SDKs being in different locations.
Note about include paths
If you get an error including this file, check your paths - there's a full list of
Digidesign paths in juce_RTASWrapper.cpp
*/
#include "ChunkDataParser.cpp"

+ 46
- 0
extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_DLLMain.cpp View File

@@ -0,0 +1,46 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "juce_Wrapper_Header.h"
/*
This file is used to include and build a digidesign CPP file without your project needing to
reference the file directly. Because the file will be located via the include path, this means
that the project doesn't have to change to cope with people's SDKs being in different locations.
Note about include paths
If you get an error including this file, check your paths - there's a full list of
Digidesign paths in juce_RTASWrapper.cpp
*/
#if WINDOWS_VERSION
#include "DLLMain.cpp"
#endif

+ 46
- 0
extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_DefaultSwap.cpp View File

@@ -0,0 +1,46 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "juce_Wrapper_Header.h"
/*
This file is used to include and build a digidesign CPP file without your project needing to
reference the file directly. Because the file will be located via the include path, this means
that the project doesn't have to change to cope with people's SDKs being in different locations.
Note about include paths
If you get an error including this file, check your paths - there's a full list of
Digidesign paths in juce_RTASWrapper.cpp
*/
#if WINDOWS_VERSION
#include "DefaultSwap.cpp"
#endif

+ 40
- 0
extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_Dispatcher.cpp View File

@@ -0,0 +1,40 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
/* This file is used to include and build a digidesign CPP file without your project needing to
reference the file directly. Because the file will be located via the include path, this means
that the project doesn't have to change to cope with people's SDKs being in different locations.
*/
#include "juce_Wrapper_Header.h"
#if ! WINDOWS_VERSION
#include "Dispatcher.cpp"
#endif

+ 45
- 0
extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_Header.h View File

@@ -0,0 +1,45 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#ifndef __JUCE_WRAPPER_HEADER_JUCEHEADER__
#define __JUCE_WRAPPER_HEADER_JUCEHEADER__
#include "../juce_RTASCompileFlags.h"
#ifdef _MSC_VER
// the Digidesign projects all use a struct alignment of 2..
#pragma pack (2)
#pragma warning (disable: 4267 4996 4311 4312 4103)
#include "ForcedInclude.h"
#endif
#endif // __JUCE_WRAPPER_HEADER_JUCEHEADER__

+ 44
- 0
extras/audio plugins/wrapper/formats/RTAS/wrappers/juce_Wrapper_PlugInUtils.cpp View File

@@ -0,0 +1,44 @@
/*
==============================================================================
This file is part of the JUCE library - "Jules' Utility Class Extensions"
Copyright 2004-7 by Raw Material Software ltd.
------------------------------------------------------------------------------
JUCE can be redistributed and/or modified 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.
JUCE is distributed in the hope that 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 JUCE; if not, visit www.gnu.org/licenses or write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
------------------------------------------------------------------------------
If you'd like to release a closed-source product which uses JUCE, commercial
licenses are also available: visit www.rawmaterialsoftware.com/juce for
more information.
==============================================================================
*/
#include "juce_Wrapper_Header.h"
/*
This file is used to include and build a digidesign CPP file without your project needing to
reference the file directly. Because the file will be located via the include path, this means
that the project doesn't have to change to cope with people's SDKs being in different locations.
Note about include paths
If you get an error including this file, check your paths - there's a full list of
Digidesign paths in juce_RTASWrapper.cpp
*/
#include "PlugInUtils.cpp"

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save