updating mac osx itunes native visualizer plugin

This commit is contained in:
Mischa S
2013-08-11 19:53:15 -07:00
parent 6f0078bcd4
commit 3a1fdbdf65
16 changed files with 2991 additions and 1960 deletions

View File

@ -1,20 +0,0 @@
#
# projectM -- Milkdrop-esque visualisation SDK
# Copyright (C)2003-2007 projectM Team
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# See 'LICENSE.txt' included within this release
clean:

View File

@ -0,0 +1,95 @@
//
// File: getConfigFilename.cpp
//
// Author: fatray
//
// Created on 05 December 2007, 23:39
//
// FIXME: portability
// I hacked include<string> on to silence my compiler, is it valid?
#include <string>
#include <cstring>
#include <cstdlib>
#include "getConfigFilename.h"
#include <fcntl.h>
#include <sys/stat.h>
#include <cstdio>
#define PROJECTM_PREFIX ""
// get the full pathname of a configfile
std::string getConfigFilename()
{
char num[512];
FILE *in;
FILE *out;
char* home;
// FIXME: fixed length buffers are not ideal.
char projectM_home[1024];
char projectM_config[1024];
strcpy(projectM_config, PROJECTM_PREFIX);
strcpy(projectM_config + strlen(PROJECTM_PREFIX), CONFIG_FILE);
projectM_config[strlen(PROJECTM_PREFIX) + strlen(CONFIG_FILE)] = '\0';
printf("dir:%s \n", projectM_config);
home = getenv("HOME");
strcpy(projectM_home, home);
strcpy(projectM_home + strlen(home), "/.projectM/config.inp");
projectM_home[strlen(home) + strlen("/.projectM/config.inp")] = '\0';
if ((in = fopen(projectM_home, "r")))
{
printf("reading ~/.projectM/config.inp \n");
fclose(in);
return std::string(projectM_home);
}
printf("trying to create ~/.projectM/config.inp \n");
projectM_home[strlen(home) + strlen("/.projectM")] = '\0';
mkdir(projectM_home, 0755);
strcpy(projectM_home + strlen(home), "/.projectM/config.inp");
projectM_home[strlen(home) + strlen("/.projectM/config.inp")] = '\0';
if((out = fopen(projectM_home, "w")))
{
if ((in = fopen(projectM_config, "r")))
{
while(fgets(num, 80, in)!=NULL)
{
fputs(num, out);
}
fclose(in);
fclose(out);
if ((in = fopen(projectM_home, "r")))
{
printf("created ~/.projectM/config.inp successfully\n");
fclose(in);
return std::string(projectM_home);
}
printf("This shouldn't happen, using implementation defaults\n");
abort();
}
printf("Cannot find projectM default config, using implementation defaults\n");
abort();
}
printf("Cannot create ~/.projectM/config.inp, using default config file\n");
if ((in = fopen(projectM_config, "r")))
{
printf("Successfully opened default config file\n");
fclose(in);
return std::string(projectM_config);
}
printf("Using implementation defaults, your system is really messed up, I'm suprised we even got this far\n");
abort();
}

View File

@ -0,0 +1,18 @@
//
// File: getConfigFilename.h
//
// Author: fatray
//
// Created on 05 December 2007, 23:39
//
#ifndef _GETCONFIGFILENAME_H
#define _GETCONFIGFILENAME_H
//FIXME: define this here? in .cpp? or somewhere else?
#define CONFIG_FILE "/share/projectM/config.inp"
// get the full pathname of a configfile
std::string getConfigFilename();
#endif /* _GETCONFIGFILENAME_H */

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//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>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>biz.int80.${PRODUCT_NAME:rfc1034identifier}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>hvpl</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>hook</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2013 projectM. All rights reserved.</string>
</dict>
</plist>

View File

@ -0,0 +1,299 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
C3F9D7B317B82CC3009E58CB /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C3F9D7B217B82CC3009E58CB /* Cocoa.framework */; };
C3F9D7CF17B831F3009E58CB /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C3F9D7CE17B831F3009E58CB /* OpenGL.framework */; };
C3F9D7D317B83CCB009E58CB /* iprojectM_mac.mm in Sources */ = {isa = PBXBuildFile; fileRef = C3F9D7D017B83CCB009E58CB /* iprojectM_mac.mm */; };
C3F9D7D417B83CCB009E58CB /* iprojectM.mm in Sources */ = {isa = PBXBuildFile; fileRef = C3F9D7D217B83CCB009E58CB /* iprojectM.mm */; };
C3F9D7D917B83CF1009E58CB /* iTunesAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C3F9D7D617B83CF1009E58CB /* iTunesAPI.cpp */; };
C3F9D7DB17B84081009E58CB /* libprojectM.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C3F9D7DA17B84081009E58CB /* libprojectM.a */; };
C3FAE59217B87D8700F4B110 /* getConfigFilename.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C3FAE59017B87D8700F4B110 /* getConfigFilename.cpp */; };
C3FAE59617B884FC00F4B110 /* iProjectM-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = C3FAE59517B884FC00F4B110 /* iProjectM-Info.plist */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
C3F9D7AF17B82CC3009E58CB /* iProjectM.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = iProjectM.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
C3F9D7B217B82CC3009E58CB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
C3F9D7B517B82CC3009E58CB /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
C3F9D7B617B82CC3009E58CB /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
C3F9D7B717B82CC3009E58CB /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
C3F9D7CE17B831F3009E58CB /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; };
C3F9D7D017B83CCB009E58CB /* iprojectM_mac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = iprojectM_mac.mm; sourceTree = "<group>"; };
C3F9D7D117B83CCB009E58CB /* iprojectM.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = iprojectM.hpp; sourceTree = "<group>"; };
C3F9D7D217B83CCB009E58CB /* iprojectM.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = iprojectM.mm; sourceTree = "<group>"; };
C3F9D7D617B83CF1009E58CB /* iTunesAPI.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = iTunesAPI.cpp; sourceTree = "<group>"; };
C3F9D7D717B83CF1009E58CB /* iTunesAPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iTunesAPI.h; sourceTree = "<group>"; };
C3F9D7D817B83CF1009E58CB /* iTunesVisualAPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iTunesVisualAPI.h; sourceTree = "<group>"; };
C3F9D7DA17B84081009E58CB /* libprojectM.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libprojectM.a; path = ../libprojectM/libprojectM.a; sourceTree = "<group>"; };
C3FAE59017B87D8700F4B110 /* getConfigFilename.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = getConfigFilename.cpp; sourceTree = "<group>"; };
C3FAE59117B87D8700F4B110 /* getConfigFilename.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = getConfigFilename.h; sourceTree = "<group>"; };
C3FAE59517B884FC00F4B110 /* iProjectM-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "iProjectM-Info.plist"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
C3F9D7AC17B82CC3009E58CB /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
C3F9D7CF17B831F3009E58CB /* OpenGL.framework in Frameworks */,
C3F9D7B317B82CC3009E58CB /* Cocoa.framework in Frameworks */,
C3F9D7DB17B84081009E58CB /* libprojectM.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
C3F9D7A617B82CC3009E58CB = {
isa = PBXGroup;
children = (
C3F9D7DA17B84081009E58CB /* libprojectM.a */,
C3FAE59017B87D8700F4B110 /* getConfigFilename.cpp */,
C3FAE59117B87D8700F4B110 /* getConfigFilename.h */,
C3F9D7D017B83CCB009E58CB /* iprojectM_mac.mm */,
C3F9D7D117B83CCB009E58CB /* iprojectM.hpp */,
C3F9D7D217B83CCB009E58CB /* iprojectM.mm */,
C3FAE59517B884FC00F4B110 /* iProjectM-Info.plist */,
C3F9D7D517B83CF1009E58CB /* iTunesVisualAPI */,
C3F9D7B117B82CC3009E58CB /* Frameworks */,
C3F9D7B017B82CC3009E58CB /* Products */,
);
sourceTree = "<group>";
};
C3F9D7B017B82CC3009E58CB /* Products */ = {
isa = PBXGroup;
children = (
C3F9D7AF17B82CC3009E58CB /* iProjectM.bundle */,
);
name = Products;
sourceTree = "<group>";
};
C3F9D7B117B82CC3009E58CB /* Frameworks */ = {
isa = PBXGroup;
children = (
C3F9D7CE17B831F3009E58CB /* OpenGL.framework */,
C3F9D7B217B82CC3009E58CB /* Cocoa.framework */,
C3F9D7B417B82CC3009E58CB /* Other Frameworks */,
);
name = Frameworks;
sourceTree = "<group>";
};
C3F9D7B417B82CC3009E58CB /* Other Frameworks */ = {
isa = PBXGroup;
children = (
C3F9D7B517B82CC3009E58CB /* AppKit.framework */,
C3F9D7B617B82CC3009E58CB /* CoreData.framework */,
C3F9D7B717B82CC3009E58CB /* Foundation.framework */,
);
name = "Other Frameworks";
sourceTree = "<group>";
};
C3F9D7D517B83CF1009E58CB /* iTunesVisualAPI */ = {
isa = PBXGroup;
children = (
C3F9D7D617B83CF1009E58CB /* iTunesAPI.cpp */,
C3F9D7D717B83CF1009E58CB /* iTunesAPI.h */,
C3F9D7D817B83CF1009E58CB /* iTunesVisualAPI.h */,
);
name = iTunesVisualAPI;
path = macos;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
C3F9D7AE17B82CC3009E58CB /* iProjectM */ = {
isa = PBXNativeTarget;
buildConfigurationList = C3F9D7C117B82CC3009E58CB /* Build configuration list for PBXNativeTarget "iProjectM" */;
buildPhases = (
C3F9D7AB17B82CC3009E58CB /* Sources */,
C3F9D7AC17B82CC3009E58CB /* Frameworks */,
C3F9D7AD17B82CC3009E58CB /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = iProjectM;
productName = iProjectM;
productReference = C3F9D7AF17B82CC3009E58CB /* iProjectM.bundle */;
productType = "com.apple.product-type.bundle";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
C3F9D7A717B82CC3009E58CB /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0460;
ORGANIZATIONNAME = projectM;
};
buildConfigurationList = C3F9D7AA17B82CC3009E58CB /* Build configuration list for PBXProject "iProjectM" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = C3F9D7A617B82CC3009E58CB;
productRefGroup = C3F9D7B017B82CC3009E58CB /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
C3F9D7AE17B82CC3009E58CB /* iProjectM */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
C3F9D7AD17B82CC3009E58CB /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C3FAE59617B884FC00F4B110 /* iProjectM-Info.plist in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
C3F9D7AB17B82CC3009E58CB /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C3F9D7D317B83CCB009E58CB /* iprojectM_mac.mm in Sources */,
C3F9D7D417B83CCB009E58CB /* iprojectM.mm in Sources */,
C3F9D7D917B83CF1009E58CB /* iTunesAPI.cpp in Sources */,
C3FAE59217B87D8700F4B110 /* getConfigFilename.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
C3F9D7BF17B82CC3009E58CB /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(ARCHS_STANDARD_64_BIT)";
CLANG_CXX_LANGUAGE_STANDARD = "compiler-default";
CLANG_CXX_LIBRARY = "compiler-default";
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEPLOYMENT_LOCATION = YES;
GCC_C_LANGUAGE_STANDARD = "compiler-default";
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = "${SRCROOT}/..";
MACOSX_DEPLOYMENT_TARGET = 10.8;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
};
name = Debug;
};
C3F9D7C017B82CC3009E58CB /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ARCHS = "$(ARCHS_STANDARD_64_BIT)";
CLANG_CXX_LANGUAGE_STANDARD = "compiler-default";
CLANG_CXX_LIBRARY = "compiler-default";
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEPLOYMENT_LOCATION = YES;
GCC_C_LANGUAGE_STANDARD = "compiler-default";
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
HEADER_SEARCH_PATHS = "${SRCROOT}/..";
MACOSX_DEPLOYMENT_TARGET = 10.8;
SDKROOT = macosx;
};
name = Release;
};
C3F9D7C217B82CC3009E58CB /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
GCC_PRECOMPILE_PREFIX_HEADER = NO;
GENERATE_PKGINFO_FILE = YES;
INFOPLIST_FILE = "iProjectM/iProjectM-Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/iTunes/iTunes Plug-ins";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"\"$(SRCROOT)/../libprojectM\"",
);
PRODUCT_NAME = "$(TARGET_NAME)";
WRAPPER_EXTENSION = bundle;
};
name = Debug;
};
C3F9D7C317B82CC3009E58CB /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
GCC_PRECOMPILE_PREFIX_HEADER = NO;
GENERATE_PKGINFO_FILE = YES;
INFOPLIST_FILE = "iProjectM/iProjectM-Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/iTunes/iTunes Plug-ins";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"\"$(SRCROOT)/../libprojectM\"",
);
PRODUCT_NAME = "$(TARGET_NAME)";
WRAPPER_EXTENSION = bundle;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
C3F9D7AA17B82CC3009E58CB /* Build configuration list for PBXProject "iProjectM" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C3F9D7BF17B82CC3009E58CB /* Debug */,
C3F9D7C017B82CC3009E58CB /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
C3F9D7C117B82CC3009E58CB /* Build configuration list for PBXNativeTarget "iProjectM" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C3F9D7C217B82CC3009E58CB /* Debug */,
C3F9D7C317B82CC3009E58CB /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = C3F9D7A717B82CC3009E58CB /* Project object */;
}

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:iProjectM.xcodeproj">
</FileRef>
</Workspace>

View File

@ -1,890 +0,0 @@
/**
* projectM -- Milkdrop-esque visualisation SDK
* Copyright (C)2003-2007 projectM Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* See 'LICENSE.txt' included within this release
*
*/
/**
* $Id: iprojectM.c,v 1.10 2004/11/07 17:29:04 cvs Exp $
*
* iTunes Plugin Wrapper for projectM
*/
#include <string.h>
#ifdef WIN32
#include <windows.h>
#endif
#include <libprojectM/carbontoprojectM.hpp>
#include <libprojectM/Common.hpp>
#include <libprojectM/Renderer/BeatDetect.hpp>
#include <libprojectM/Renderer/PCM.hpp>
#include <libprojectM/projectM.hpp>
#ifdef WIN32
#include "win32/iTunesVisualAPI.h"
#else
#ifdef MACOS
#include "macos/iTunesVisualAPI.h"
#include <agl.h>
#endif /** MACOS */
#endif /** WIN32 */
#ifdef WIN32
// window information
HWND windowHandle;
HDC windowDC;
HGLRC windowRC;
#endif /** WIN32 */
#ifdef MACOS
CGrafPtr port = NULL;
AGLContext context = NULL;
int frameCount = 0;
CFDictionaryRef desktopMode = NULL;
CFDictionaryRef fullscreenMode = NULL;
int inFullScreenMode = 0;
int displayCaptured = 0;
boolean_t exactMatch;
int fullscreenWidth, fullscreenHeight;
#endif /** MACOS */
#ifdef MACOS
#define kTVisualPluginName "\pprojectM"
#define kTVisualPluginCreator 'hook'
#define kTVisualPluginMajorVersion 1
#define kTVisualPluginMinorVersion 0
#define kTVisualPluginReleaseStage finalStage
#define kTVisualPluginNonFinalRelease 0
#endif /** MACOS */
/** Port dimensions */
int windowWidth;
int windowHeight;
/** projectM info */
projectM *globalPM = NULL;
#ifdef DEBUG
FILE *debugFile = NULL;
#endif
// iTunes information
RenderVisualData renderData;
int playing;
void *appCookie;
ITAppProcPtr appProc;
#ifdef WIN32
ITTrackInfoV1 trackInfo;
ITStreamInfoV1 streamInfo;
#else
#ifdef MACOS
ITTrackInfo trackInfo;
ITStreamInfo streamInfo;
FSSpec pluginSpec;
#endif /** MACOS */
#endif /** WIN32 */
#ifdef MACOS
void CleanupGL();
#endif
#ifdef MACOS
/** fss2path takes the FSSpec of the plugin and returns the filename */
void fss2path( FSSpec *fss, char *path ) {
int l;
for ( l = 0 ; l < (fss->name[0]) ; l++ ) {
path[l] = fss->name[l + 1];
}
path[l] = '\0';
DWRITE( "fss2path: '%s'\n", path );
if ( fss->parID != fsRtParID) {
int i, len;
CInfoPBRec pb;
pb.dirInfo.ioNamePtr = fss->name;
pb.dirInfo.ioVRefNum = fss->vRefNum;
pb.dirInfo.ioDrParID = fss->parID;
do {
pb.dirInfo.ioFDirIndex = -1;
pb.dirInfo.ioDrDirID = pb.dirInfo.ioDrParID;
if ( PBGetCatInfoSync( &pb ) != noErr ) {
break;
}
len = fss->name[0] + 1;
for ( i = l ; i >= 0 ; i-- ) path[i + len] = path[i];
for ( i = 1 ; i < len ; i++ ) path[i - 1] = fss->name[i];
path[i - 1] = '/';
l += len;
} while ( pb.dirInfo.ioDrDirID != fsRtDirID );
len = 9;
for ( i = l ; i >= 0 ; i-- ) path[i + len] = path[i];
path[0] = '/';
path[1] = 'V';
path[2] = 'o';
path[3] = 'l';
path[4] = 'u';
path[5] = 'm';
path[6] = 'e';
path[7] = 's';
path[8] = '/';
}
}
#endif
// create OpenGL rendering context for the specified window
#ifdef WIN32
void InitializeGL(HWND hwnd)
{
int pixelFormat;
PIXELFORMATDESCRIPTOR pfd = {
sizeof (PIXELFORMATDESCRIPTOR), /* struct size */
1, /* Version number */
PFD_DRAW_TO_WINDOW /* Flags, draw to a window, */
| PFD_DOUBLEBUFFER /* Requires Doublebuffer hw */
| PFD_SUPPORT_OPENGL, /* use OpenGL */
PFD_TYPE_RGBA, /* RGBA pixel values */
32, /* 24-bit color */
0, 0, 0, /* RGB bits & shift sizes. */
0, 0, 0, /* Don't care about them */
0, 0, /* No alpha buffer info */
0, 0, 0, 0, 0, /* No accumulation buffer */
16, /* depth buffer */
1, /* stencil buffer */
0, /* No auxiliary buffers */
PFD_MAIN_PLANE, /* Layer type */
0, /* Reserved (must be 0) */
0, /* No layer mask */
0, /* No visible mask */
0 /* No damage mask */
};
windowHandle = hwnd;
windowDC = GetDC(windowHandle);
// memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
pixelFormat = ChoosePixelFormat(windowDC, &pfd);
if (pixelFormat == 0)
return;
if (SetPixelFormat(windowDC, pixelFormat, &pfd) == 0)
return;
windowRC = wglCreateContext(windowDC);
if (windowRC == NULL)
return;
if (!wglMakeCurrent(windowDC, windowRC))
return;
#ifdef PANTS
// enable v-sync if WGL_EXT_swap_control is supported
PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = NULL;
wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
if (wglSwapIntervalEXT != NULL)
wglSwapIntervalEXT(1);
#endif
/** Initialise projectM */
#ifdef DEBUG
debugFile = fopen( "c:\\iprojectM.txt", "wb" );
#endif
globalPM = (projectM_t *)malloc( sizeof( projectM_t ) );
projectM_reset( globalPM );
globalPM->fullscreen = 0;
globalPM->usePbuffers = 1;
globalPM->renderTarget->texsize = 1024;
globalPM->showfps = 1;
/** Initialise font and preset paths */
globalPM->fontURL = (char *)malloc( sizeof( char ) * 1024 );
strcpy( globalPM->fontURL, "c:\\Program Files\\iTunes\\Plug-ins\\projectM\\fonts" );
globalPM->presetURL = (char *)malloc( sizeof( char ) * 1024 );
strcpy( globalPM->presetURL, "c:\\Program Files\\iTunes\\Plug-ins\\projectM\\presets" );
projectM_init( globalPM );
}
#else
#ifdef MACOS
void InitializeGL( CGrafPtr destPort, int isFullScreen ) {
AGLPixelFormat pixelFormat;
GLint attrib[64];
DWRITE( "InitializeGL(): in: %d\n", isFullScreen );
/** Stash the target port */
port = destPort;
#ifdef PANTS
if ( isFullScreen ) {
CGCaptureAllDisplays();
displayCaptured = 1;
if ( fullscreenMode != NULL ) {
if ( CGDisplaySwitchToMode( kCGDirectMainDisplay, fullscreenMode ) != CGDisplayNoErr ) {
DWRITE( "%s\n", "failed to switch display to fullscreen" );
} else {
DWRITE( "%s\n", "display switch to fullscreen ok\n" );
}
}
} else {
/** Switch back to the previous desktop mode */
if ( desktopMode != NULL ) {
if ( CGDisplaySwitchToMode( kCGDirectMainDisplay, desktopMode ) != CGDisplayNoErr ) {
DWRITE( "%s\n", "failed to switch display" );
} else {
DWRITE( "%s\n", "display switch OK" );
}
}
}
#endif
/** Chuck out the old context if one exists */
if ( context != NULL ) {
aglDestroyContext( context );
context = NULL;
}
/** Choose the OpenGL pixel format */
#ifdef PANTS
if ( isFullScreen ) {
attrib[0] = AGL_RGBA;
attrib[1] = AGL_DOUBLEBUFFER;
attrib[2] = AGL_PIXEL_SIZE;
attrib[3] = 32;
attrib[4] = AGL_FULLSCREEN;
attrib[5] = AGL_NO_RECOVERY;
attrib[6] = AGL_SINGLE_RENDERER;
attrib[6] = AGL_NONE;
} else {
#endif
attrib[0] = AGL_RGBA;
attrib[1] = AGL_DOUBLEBUFFER;
attrib[2] = AGL_ACCELERATED;
attrib[3] = AGL_PIXEL_SIZE;
attrib[4] = 32;
attrib[5] = AGL_NO_RECOVERY;
attrib[6] = AGL_SINGLE_RENDERER;
attrib[5] = AGL_NONE;
// }
GDHandle mainDevice = GetMainDevice();
pixelFormat = aglChoosePixelFormat( &mainDevice, 1, attrib );
if ( pixelFormat == 0 ) {
DWRITE( "failed to select pixel format\n" );
exit( 1 );
CleanupGL();
isFullScreen = 0;
return;
} else {
DWRITE( "selected pixel format OK\n" );
}
context = aglCreateContext( pixelFormat, NULL );
if ( context == NULL ) {
DWRITE( "failed to create context\n" );
} else {
DWRITE( "created context OK\n" );
}
// if ( !isFullScreen ) {
if ( !aglSetDrawable( context, destPort ) ) {
DWRITE( "failed to set drawable\n" );
} else {
DWRITE( "set drawable OK\n" );
}
// } else {
// aglSetDrawable( context, NULL );
// }
if ( !aglSetCurrentContext( context ) ) {
DWRITE( "failed to make context current\n" );
} else {
DWRITE( "set current context OK\n" );
}
// if ( !isFullScreen ) {
if ( !aglUpdateContext( context ) ) {
DWRITE( "failed to update context\n" );
} else {
DWRITE( "updated context OK\n" );
}
if ( globalPM != NULL ) {
globalPM->fullscreen = 0;
}
#ifdef PANTS
} else {
aglSetFullScreen( context, 800, 600, 0, 0 );
if ( globalPM != NULL ) {
globalPM->fullscreen = 1;
}
GLint displayCaps[3];
aglGetInteger( context, AGL_FULLSCREEN, displayCaps );
DWRITE( "dcaps: %d\t%d\t%d\n",
displayCaps[0], displayCaps[1], displayCaps[2] );
fullscreenWidth = displayCaps[0];
fullscreenHeight = displayCaps[1];
}
#endif
#ifdef WIN32
// enable v-sync if WGL_EXT_swap_control is supported
PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = NULL;
wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
if (wglSwapIntervalEXT != NULL)
wglSwapIntervalEXT(1);
#endif
#ifdef MACOS
/** Setup VSYNC */
GLint sync = 1;
aglSetInteger ( context, AGL_SWAP_INTERVAL, &sync );
#endif
/** Initialise projectM */
globalPM->projectM_init();
}
#endif /** MACOS */
#endif /** WIN32 */
// render visualization data
void RenderGL()
{
#ifdef WIN32
if (windowDC == NULL || globalPM == NULL ) return;
#else
#ifdef MACOS
if ( port == NULL || context == NULL ) {
return;
}
#endif /** MACOS */
#endif /** WIN32 */
/** Stuff the PCM data into projectM */
globalPM->beatDetect->pcm->addPCM8( renderData.waveformData );
/** Render a frame via projectM */
globalPM->renderFrame();
#if defined(DEBUG2) && defined(MACOS)
fprintf( debugFile, "port: %X\tcontext: %X\n", port, context );
fflush( debugFile );
#endif
#ifdef WIN32
/** Buffer swap to display the results */
SwapBuffers( windowDC );
#else
#ifdef MACOS
aglSwapBuffers( context );
#endif /** MACOS */
#endif /** WIN32 */
}
// resize rendering viewport
void ResizeGL( CGrafPtr destPort, Rect windowRect, int isFullScreen ) {
#ifdef MACOS
GLint bufferRect[4];
#endif
DWRITE( "ResizeGL(): in: %d\n", isFullScreen );
#ifdef PANTS
if ( isFullScreen ) {
#ifdef MACOS
aglDisable( context, AGL_BUFFER_RECT );
#endif /** MACOS */
/** Reset projectM */
if ( globalPM != NULL ) {
globalPM->projectM_resetGL( fullscreenWidth, fullscreenHeight );
}
} else {
#endif
windowWidth = windowRect.right - windowRect.left;
windowHeight = windowRect.bottom - windowRect.top;
if (windowHeight == 0) windowHeight = 1;
/** Re-initialise OpenGL */
if ( globalPM != NULL ) {
#ifdef MACOS
/**
* Grab the dimensions of the main window itself. This is required
* to accurately locate the port since OpenGL is "upside-down" from
* Carbon window coordinates...
*/
WindowRef itWindowRef;
Rect mwindowRect;
itWindowRef = GetWindowFromPort(port);
GetWindowPortBounds(itWindowRef, &mwindowRect);
DWRITE( "rect: (%d, %d) -> (%d, %d)\n",
windowRect.left, windowRect.top,
windowRect.right, windowRect.bottom );
DWRITE( "window-rect: (%d, %d) -> (%d, %d)\n",
mwindowRect.left, mwindowRect.top,
mwindowRect.right, mwindowRect.bottom );
/** Update the buffer rect */
bufferRect[0] = windowRect.left;
bufferRect[1] = mwindowRect.bottom - windowRect.bottom;
bufferRect[2] = windowWidth;
bufferRect[3] = windowHeight;
aglSetInteger( context, AGL_BUFFER_RECT, bufferRect );
aglEnable( context, AGL_BUFFER_RECT );
if ( !aglUpdateContext( context ) ) {
DWRITE( "failed to update context\n" );
} else {
DWRITE( "updated context OK\n" );
}
#endif
globalPM->projectM_resetGL( windowWidth, windowHeight );
}
// }
}
// cleanup OpenGL rendering context
void CleanupGL()
{
#ifdef WIN32
wglMakeCurrent(NULL, NULL);
if (windowRC != NULL)
{
wglDeleteContext(windowRC);
windowRC = NULL;
}
if (windowDC)
{
ReleaseDC(windowHandle, windowDC);
windowDC = NULL;
}
#else
#ifdef MACOS
/** Release the held main display */
#ifdef PANTS
if ( displayCaptured ) {
DWRITE( "%s\n", "switching to non-fullscreen" );
CGDisplaySwitchToMode( kCGDirectMainDisplay, desktopMode );
DWRITE( "%s\n", "releasing displays" );
CGReleaseAllDisplays();
}
#endif
DWRITE( "pre-context destroy\n" );
if ( context != NULL ) {
aglSetCurrentContext( NULL );
aglDestroyContext( context );
context = NULL;
}
#endif /** MACOS */
#endif /** WIN32 */
}
// handle messages sent by iTunes
OSStatus pluginMessageHandler( OSType message,
VisualPluginMessageInfo *messageInfo,
void *refCon) {
OSStatus status = noErr;
switch (message) {
// sent when the plugin is loaded/unloaded
case kVisualPluginInitMessage: {
DWRITE( "*** %s\n", "kVisualPluginInitMessage" );
break;
}
case kVisualPluginCleanupMessage: {
DWRITE( "*** %s\n", "kVisualPluginCleanupMessage" );
// CleanupGL();
break;
}
// sent when plugin is enabled/disabled, plugin should handle these messages and do nothing
case kVisualPluginEnableMessage: {
DWRITE( "*** %s\n", "kVisualPluginEnableMessage" );
break;
}
case kVisualPluginDisableMessage: {
DWRITE( "*** %s\n", "kVisualPluginDisableMessage" );
break;
}
// redraw the screne while idle
case kVisualPluginIdleMessage: {
DWRITE( "*** %s\n", "kVisualPluginIdleMessage" );
if (playing == false) {
RenderGL();
}
break;
}
// sent when the visualizer is shown
case kVisualPluginShowWindowMessage: {
DWRITE( "*** kVisualPluginShowWindowMessage( %d )\n",
messageInfo->u.showWindowMessage.options );
#ifdef WIN32
InitializeGL(messageInfo->u.showWindowMessage.window,
messageInfo->u.showWindowMessage.options );
#else
#ifdef MACOS
InitializeGL( messageInfo->u.showWindowMessage.port,
/* messageInfo->u.showWindowMessage.options */ 0 );
#endif /** MACOS */
#endif /** WIN32 */
ResizeGL( messageInfo->u.showWindowMessage.port,
messageInfo->u.setWindowMessage.drawRect,
/* messageInfo->u.setWindowMessage.options */ 0 );
RenderGL();
break;
}
// sent when the visualizer is hidden
case kVisualPluginHideWindowMessage: {
DWRITE( "*** %s\n", "kVisualPluginHideWindowMessage" );
CleanupGL();
break;
}
#ifdef PANTS
// sent when visualizer viewport size is changed
case kVisualPluginSetWindowMessage: {
DWRITE( "*** kVisualPluginSetWindowMessage( %d )\n",
messageInfo->u.setWindowMessage.options );
ResizeGL(messageInfo->u.setWindowMessage.port,
messageInfo->u.setWindowMessage.drawRect,
messageInfo->u.setWindowMessage.options);
RenderGL();
break;
}
#endif
// sent when visualizer should render a frame
case kVisualPluginRenderMessage: {
DWRITE( "*** %s\n", "kVisualPluginRenderMessage" );
renderData = *messageInfo->u.renderMessage.renderData;
RenderGL();
break;
}
// sent when visualizer should update itself
case kVisualPluginUpdateMessage: {
DWRITE( "*** %s\n", "kVisualPluginUpdateMessage" );
RenderGL();
break;
}
// sent when player is stopped or paused
case kVisualPluginStopMessage: {
DWRITE( "*** %s\n", "kVisualPluginStopMessage" );
break;
}
case kVisualPluginPauseMessage: {
DWRITE( "*** %s\n", "kVisualPluginPauseMessage" );
playing = false;
break;
}
// sent when player is started or unpaused
case kVisualPluginPlayMessage: {
DWRITE( "*** %s\n", "kVisualPluginPlayMessage" );
break;
}
case kVisualPluginUnpauseMessage: {
DWRITE( "*** %s\n", "kVisualPluginPauseMessage" );
/** Grab the track or stream title from iTunes */
if (messageInfo->u.changeTrackMessage.trackInfo != nil) {
trackInfo = *messageInfo->u.changeTrackMessage.trackInfo;
} else {
memset( &trackInfo, sizeof( trackInfo ) * sizeof( char ), 0 );
}
if (messageInfo->u.changeTrackMessage.streamInfo != nil) {
streamInfo = *messageInfo->u.changeTrackMessage.streamInfo;
} else {
memset( &streamInfo, sizeof( streamInfo ) * sizeof( char ), 0 );
}
/** Pass this info into projectM */
if ( globalPM != NULL ) {
globalPM->drawtitle = 1;
if ( strlen( (const char *)trackInfo.name ) > 0 ) {
globalPM->projectM_setTitle( (char *)trackInfo.name );
} else {
if ( strlen( (const char *)streamInfo.streamTitle ) > 0 ) {
globalPM->projectM_setTitle( (char *)streamInfo.streamTitle );
}
}
}
playing = true;
break;
}
/** Sent when the track changes */
case kVisualPluginChangeTrackMessage: {
DWRITE( "*** %s\n", "kVisualPluginChangeTrackMessage" );
/** Grab the track or stream title from iTunes */
if (messageInfo->u.changeTrackMessage.trackInfo != nil) {
trackInfo = *messageInfo->u.changeTrackMessage.trackInfo;
} else {
memset( &trackInfo, sizeof( trackInfo ) * sizeof( char ), 0 );
}
if (messageInfo->u.changeTrackMessage.streamInfo != nil) {
streamInfo = *messageInfo->u.changeTrackMessage.streamInfo;
} else {
memset( &streamInfo, sizeof( streamInfo ) * sizeof( char ), 0 );
}
/** Pass this info into projectM */
globalPM->drawtitle = 1;
if ( strlen( (const char *)trackInfo.name ) > 0 ) {
globalPM->projectM_setTitle( (char *)trackInfo.name );
} else {
if ( strlen( (const char *)streamInfo.streamTitle ) > 0 ) {
globalPM->projectM_setTitle( (char *)streamInfo.streamTitle );
}
}
RenderGL();
break;
}
case kVisualPluginEventMessage: {
projectMEvent event;
projectMKeycode keycode;
projectMModifier mod;
DWRITE( "*** %s\n", "kVisualPluginEventMessage" );
#ifdef MACOS
event = carbon2pmEvent( messageInfo->u.eventMessage.event );
keycode = carbon2pmKeycode( messageInfo->u.eventMessage.event );
#else
#ifdef WIN32
#endif /** WIN32 */
#endif /** MACOS */
DWRITE( "keycode: %d\n", keycode );
if ( keycode == ' ' ) {
status = unimpErr;
}
globalPM->key_handler( event, keycode, mod );
break;
}
default: {
status = unimpErr;
break;
}
}
return status;
}
// register plugin with iTunes
OSStatus registerPlugin(PluginMessageInfo *messageInfo) {
OSStatus status;
// plugin constants
#ifdef WIN32
const char *pluginTitle = "projectM";
const UInt32 pluginCreator = '\?\?\?\?';
#else
#ifdef MACOS
const char *pluginTitle = "projectM";
const UInt32 pluginCreator = 'hook';
#endif /** MACOS */
#endif /** WIN32 */
const UInt8 pluginMajorVersion = 10;
const UInt8 pluginMinorVersion = 9;
PlayerMessageInfo playerMessageInfo;
memset( &playerMessageInfo.u.registerVisualPluginMessage,
0, sizeof(playerMessageInfo.u.registerVisualPluginMessage));
// copy in name length byte first
playerMessageInfo.u.registerVisualPluginMessage.name[0] =
(UInt8)strlen( pluginTitle );
// now copy in actual name
memcpy( &playerMessageInfo.u.registerVisualPluginMessage.name[1],
pluginTitle, strlen( pluginTitle ));
SetNumVersion( &playerMessageInfo.u.registerVisualPluginMessage.pluginVersion,
pluginMajorVersion, pluginMinorVersion, 0x80, 0);
playerMessageInfo.u.registerVisualPluginMessage.options =
kVisualWantsIdleMessages;
#ifdef WIN32
playerMessageInfo.u.registerVisualPluginMessage.handler =
pluginMessageHandler;
#else
playerMessageInfo.u.registerVisualPluginMessage.handler =
(VisualPluginProcPtr)pluginMessageHandler;
#endif
playerMessageInfo.u.registerVisualPluginMessage.registerRefCon = 0;
playerMessageInfo.u.registerVisualPluginMessage.creator = pluginCreator;
playerMessageInfo.u.registerVisualPluginMessage.timeBetweenDataInMS = 0xFFFFFFFF; // 16 milliseconds = 1 Tick, 0xFFFFFFFF = Often as possible.
playerMessageInfo.u.registerVisualPluginMessage.numWaveformChannels = 2;
playerMessageInfo.u.registerVisualPluginMessage.numSpectrumChannels = 2;
playerMessageInfo.u.registerVisualPluginMessage.minWidth = 64;
playerMessageInfo.u.registerVisualPluginMessage.minHeight = 64;
playerMessageInfo.u.registerVisualPluginMessage.maxWidth = 32767;
playerMessageInfo.u.registerVisualPluginMessage.maxHeight = 32767;
playerMessageInfo.u.registerVisualPluginMessage.minFullScreenBitDepth = 0;
playerMessageInfo.u.registerVisualPluginMessage.maxFullScreenBitDepth = 0;
playerMessageInfo.u.registerVisualPluginMessage.windowAlignmentInBytes = 0;
status = PlayerRegisterVisualPlugin(messageInfo->u.initMessage.appCookie,
messageInfo->u.initMessage.appProc,
&playerMessageInfo);
appCookie = messageInfo->u.initMessage.appCookie;
appProc = messageInfo->u.initMessage.appProc;
return status;
}
#ifdef WIN32
#define IMPEXP __declspec(dllexport)
#define MAIN iTunesPluginMain
#else
#ifdef MACOS
#define IMPEXP
#define MAIN iTunesPluginMainMachO
#endif /** MACOS */
#endif /** WIN32 */
#ifdef MACOS
extern "C"
#endif
IMPEXP OSStatus MAIN (OSType message, PluginMessageInfo *messageInfo, void *refCon)
{
OSStatus status = noErr;
char fname[1024];
char fontURL[1024];
char presetURL[1024];
switch (message) {
case kPluginInitMessage: {
#ifdef DEBUG
#ifdef MACOS
debugFile = fopen( "/Users/descarte/iprojectM.txt", "wb" );
fprintf( debugFile, "registerPlugin: %d\n", status );
fflush( debugFile );
#endif /** MACOS */
#endif /** DEBUG */
DWRITE( "%s: %d\t%d\n",
"kPluginInitMessage",
messageInfo->u.initMessage.majorVersion,
messageInfo->u.initMessage.minorVersion );
status = registerPlugin(messageInfo);
if ( status == noErr ) {
#ifdef MACOS
desktopMode = CGDisplayCurrentMode( kCGDirectMainDisplay );
fullscreenMode =
CGDisplayBestModeForParameters( kCGDirectMainDisplay,
32, 800, 600, NULL );
#ifdef DEBUG
if ( debugFile != NULL ) {
long dwidth = 0, dheight = 0;
/** Get the desktop mode */
/* Get the height, width, bpp, and refresh rate of this display mode. Print them out. */
CFNumberRef number ;
number = (CFNumberRef)CFDictionaryGetValue( desktopMode, kCGDisplayWidth ) ;
CFNumberGetValue( number, kCFNumberLongType, &dwidth ) ;
number = (CFNumberRef)CFDictionaryGetValue( desktopMode, kCGDisplayHeight ) ;
CFNumberGetValue( number, kCFNumberLongType, &dheight ) ;
DWRITE( "stashing desktop mode: %d x %d -> %d\n",
dwidth, dheight, exactMatch );
}
#endif
#endif
/** Initialise projectM */
if (globalPM != 0)
delete(globalPM);
globalPM = new projectM();
globalPM->projectM_reset();
/** Set basic rendering options */
globalPM->renderTarget->usePbuffers = 1;
globalPM->fullscreen = 0;
globalPM->renderTarget->texsize = 1024;
globalPM->showfps = 1;
/** Get the font and preset locations */
PlayerGetPluginFileSpec( appCookie, appProc, &pluginSpec );
fss2path( &pluginSpec, fname );
DWRITE( "fsspace name: %s\n", fname );
sprintf( fontURL, "%s/Contents/Resources/fonts", fname );
globalPM->fontURL = (char *)malloc( sizeof( char ) * 1024 );
strncpy( globalPM->fontURL, fontURL, strlen( fontURL ) + 1 );
DWRITE( "fontURL: %s\n", globalPM->fontURL );
sprintf( presetURL, "%s/Contents/Resources/presets", fname );
globalPM->presetURL = (char *)malloc( sizeof( char ) * 1024 );
strncpy( globalPM->presetURL, presetURL, strlen( presetURL ) + 1 );
DWRITE( "presetURL: %s\n", globalPM->presetURL );
}
break;
}
case kPluginCleanupMessage: {
DWRITE( "%s\n", "kPluginCleanupMessage" );
#ifdef DEBUG
if ( debugFile != NULL ) {
fclose( debugFile );
}
#endif
status = noErr;
break;
}
default: {
status = unimpErr;
break;
}
}
DWRITE( "status: %d\n", status );
return status;
}

View File

@ -1,125 +0,0 @@
# Microsoft Developer Studio Project File - Name="iprojectM" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=iprojectM - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "iprojectM.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "iprojectM.mak" CFG="iprojectM - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "iprojectM - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "iprojectM - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "iprojectM - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "IPROJECTM_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I ".." /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "IPROJECTM_EXPORTS" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib opengl32.lib glu32.lib projectM.lib /nologo /dll /machine:I386 /libpath:"..\projectM\Release"
# Begin Special Build Tool
SOURCE="$(InputPath)"
PostBuild_Cmds=copy Release\iprojectM.dll c:\Progra~1\iTunes\Plug-ins
# End Special Build Tool
!ELSEIF "$(CFG)" == "iprojectM - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "IPROJECTM_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I ".." /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "IPROJECTM_EXPORTS" /D "DEBUG" /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib opengl32.lib glu32.lib projectM.lib /nologo /dll /debug /machine:I386 /pdbtype:sept /libpath:"..\projectM\Debug"
# Begin Special Build Tool
SOURCE="$(InputPath)"
PostBuild_Cmds=copy Debug\iprojectM.dll C:\Progra~1\iTunes\Plug-ins
# End Special Build Tool
!ENDIF
# Begin Target
# Name "iprojectM - Win32 Release"
# Name "iprojectM - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\iprojectM.c
# End Source File
# Begin Source File
SOURCE=.\win32\iTunesAPI.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\win32\iTunesAPI.h
# End Source File
# Begin Source File
SOURCE=.\win32\iTunesVisualAPI.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

View File

@ -0,0 +1,165 @@
//
// File: iTunesPlugIn.h
//
// Abstract: Visual plug-in for iTunes
//
// Version: 2.0
//
// Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. ( "Apple" )
// in consideration of your agreement to the following terms, and your use,
// installation, modification or redistribution of this Apple software
// constitutes acceptance of these terms. If you do not agree with these
// terms, please do not use, install, modify or redistribute this Apple
// software.
//
// In consideration of your agreement to abide by the following terms, and
// subject to these terms, Apple grants you a personal, non - exclusive
// license, under Apple's copyrights in this original Apple software ( the
// "Apple Software" ), to use, reproduce, modify and redistribute the Apple
// Software, with or without modifications, in source and / or binary forms;
// provided that if you redistribute the Apple Software in its entirety and
// without modifications, you must retain this notice and the following text
// and disclaimers in all such redistributions of the Apple Software. Neither
// the name, trademarks, service marks or logos of Apple Inc. may be used to
// endorse or promote products derived from the Apple Software without specific
// prior written permission from Apple. Except as expressly stated in this
// notice, no other rights or licenses, express or implied, are granted by
// Apple herein, including but not limited to any patent rights that may be
// infringed by your derivative works or by other works in which the Apple
// Software may be incorporated.
//
// The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
// WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
// WARRANTIES OF NON - INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION
// ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
//
// IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
// CONSEQUENTIAL DAMAGES ( INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION ) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION
// AND / OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER
// UNDER THEORY OF CONTRACT, TORT ( INCLUDING NEGLIGENCE ), STRICT LIABILITY OR
// OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Copyright © 2001-2011 Apple Inc. All Rights Reserved.
//
#ifndef ITUNESPLUGIN_H
#define ITUNESPLUGIN_H
#include "iTunesVisualAPI.h"
#include "libprojectM/projectM.hpp"
#include "getConfigFilename.h"
#include <time.h>
#include <OpenGL/gl.h>
#if TARGET_OS_MAC
#import <Cocoa/Cocoa.h>
#endif
#if TARGET_OS_WIN32
#include <Gdiplus.h>
#endif // TARGET_OS_WIN32
//-------------------------------------------------------------------------------------------------
// build flags
//-------------------------------------------------------------------------------------------------
#define USE_SUBVIEW (TARGET_OS_MAC && 1) // use a custom NSView subview on the Mac
//-------------------------------------------------------------------------------------------------
// typedefs, structs, enums, etc.
//-------------------------------------------------------------------------------------------------
#define kTVisualPluginCreator 'hook'
#define kTVisualPluginMajorVersion 2
#define kTVisualPluginMinorVersion 0
#define kTVisualPluginReleaseStage developStage
#define kTVisualPluginNonFinalRelease 0
struct VisualPluginData;
#if TARGET_OS_MAC
#import <Cocoa/Cocoa.h>
#import <AppKit/AppKit.h>
// "namespace" our ObjC classname to avoid load conflicts between multiple visualizer plugins
#define VisualView iProjectM_VisualView
#define GLVisualView iProjectM_GLVisualView
@class VisualView;
@class GLVisualView;
#endif
#define kInfoTimeOutInSeconds 10 // draw info/artwork for N seconds when it changes or playback starts
#define kPlayingPulseRateInHz 30 // when iTunes is playing, draw N times a second
#define kStoppedPulseRateInHz 5 // when iTunes is not playing, draw N times a second
struct VisualPluginData
{
void * appCookie;
ITAppProcPtr appProc;
// projectM stuff
projectM *pm;
#if TARGET_OS_MAC
NSView* destView;
NSRect destRect;
#if USE_SUBVIEW
VisualView* subview; // custom subview
#endif
NSImage * currentArtwork;
#else
HWND destView;
RECT destRect;
Gdiplus::Bitmap* currentArtwork;
long int lastDrawTime;
#endif
OptionBits destOptions;
RenderVisualData renderData;
UInt32 renderTimeStampID;
ITTrackInfo trackInfo;
ITStreamInfo streamInfo;
// Plugin-specific data
Boolean playing; // is iTunes currently playing audio?
Boolean padding[3];
time_t drawInfoTimeOut; // when should we stop showing info/artwork?
UInt8 minLevel[kVisualMaxDataChannels]; // 0-128
UInt8 maxLevel[kVisualMaxDataChannels]; // 0-128
};
typedef struct VisualPluginData VisualPluginData;
void GetVisualName( ITUniStr255 name );
OptionBits GetVisualOptions( void );
OSStatus RegisterVisualPlugin( PluginMessageInfo * messageInfo );
OSStatus ActivateVisual( VisualPluginData * visualPluginData, VISUAL_PLATFORM_VIEW destView, OptionBits options );
OSStatus MoveVisual( VisualPluginData * visualPluginData, OptionBits newOptions );
OSStatus DeactivateVisual( VisualPluginData * visualPluginData );
OSStatus ResizeVisual( VisualPluginData * visualPluginData );
void ProcessRenderData( VisualPluginData * visualPluginData, UInt32 timeStampID, const RenderVisualData * renderData );
void ResetRenderData( VisualPluginData * visualPluginData );
void UpdateInfoTimeOut( VisualPluginData * visualPluginData );
void UpdateTrackInfo( VisualPluginData * visualPluginData, ITTrackInfo * trackInfo, ITStreamInfo * streamInfo );
void UpdateArtwork( VisualPluginData * visualPluginData, VISUAL_PLATFORM_DATA coverArt, UInt32 coverArtSize, UInt32 coverArtFormat );
void UpdatePulseRate( VisualPluginData * visualPluginData, UInt32 * ioPulseRate );
void DrawVisual( VisualPluginData * visualPluginData );
void PulseVisual( VisualPluginData * visualPluginData, UInt32 timeStampID, const RenderVisualData * renderData, UInt32 * ioPulseRate );
void InvalidateVisual( VisualPluginData * visualPluginData );
OSStatus ConfigureVisual( VisualPluginData * visualPluginData );
void initProjectM( VisualPluginData * visualPluginData );
#endif

View File

@ -0,0 +1,396 @@
// cross-platform iTunes plugin code, from the iTunes Visual SDK
// with additions for projectM support
#include "iprojectM.hpp"
#include <string.h>
// projectM
void initProjectM( VisualPluginData * visualPluginData ) {
std::string config_filename = getConfigFilename();
projectM *pm = new projectM(config_filename);
visualPluginData->pm = pm;
}
//-------------------------------------------------------------------------------------------------
// ProcessRenderData
//-------------------------------------------------------------------------------------------------
//
void ProcessRenderData( VisualPluginData * visualPluginData, UInt32 timeStampID, const RenderVisualData * renderData )
{
SInt16 index;
SInt32 channel;
projectM *pm = visualPluginData->pm;
visualPluginData->renderTimeStampID = timeStampID;
if ( renderData == NULL )
{
memset( &visualPluginData->renderData, 0, sizeof(visualPluginData->renderData) );
return;
}
visualPluginData->renderData = *renderData;
for ( channel = 0;channel < renderData->numSpectrumChannels; channel++ )
{
visualPluginData->minLevel[channel] =
visualPluginData->maxLevel[channel] =
renderData->spectrumData[channel][0];
for ( index = 1; index < kVisualNumSpectrumEntries; index++ )
{
UInt8 value;
value = renderData->spectrumData[channel][index];
if ( value < visualPluginData->minLevel[channel] )
visualPluginData->minLevel[channel] = value;
else if ( value > visualPluginData->maxLevel[channel] )
visualPluginData->maxLevel[channel] = value;
}
}
if (pm != NULL) {
// pass waveform data to projectM
pm->pcm()->addPCM8_512(renderData->waveformData);
}
}
//-------------------------------------------------------------------------------------------------
// ResetRenderData
//-------------------------------------------------------------------------------------------------
//
void ResetRenderData( VisualPluginData * visualPluginData )
{
memset( &visualPluginData->renderData, 0, sizeof(visualPluginData->renderData) );
memset( visualPluginData->minLevel, 0, sizeof(visualPluginData->minLevel) );
}
//-------------------------------------------------------------------------------------------------
// UpdateInfoTimeOut
//-------------------------------------------------------------------------------------------------
//
void UpdateInfoTimeOut( VisualPluginData * visualPluginData )
{
// reset the timeout value we will use to show the info/artwork if we have it during DrawVisual()
visualPluginData->drawInfoTimeOut = time( NULL ) + kInfoTimeOutInSeconds;
}
//-------------------------------------------------------------------------------------------------
// UpdatePulseRate
//-------------------------------------------------------------------------------------------------
//
void UpdatePulseRate( VisualPluginData * visualPluginData, UInt32 * ioPulseRate )
{
// vary the pulse rate based on whether or not iTunes is currently playing
if ( visualPluginData->playing )
*ioPulseRate = kPlayingPulseRateInHz;
else
*ioPulseRate = kStoppedPulseRateInHz;
}
//-------------------------------------------------------------------------------------------------
// UpdateTrackInfo
//-------------------------------------------------------------------------------------------------
//
void UpdateTrackInfo( VisualPluginData * visualPluginData, ITTrackInfo * trackInfo, ITStreamInfo * streamInfo )
{
if ( trackInfo != NULL )
visualPluginData->trackInfo = *trackInfo;
else
memset( &visualPluginData->trackInfo, 0, sizeof(visualPluginData->trackInfo) );
if ( streamInfo != NULL )
visualPluginData->streamInfo = *streamInfo;
else
memset( &visualPluginData->streamInfo, 0, sizeof(visualPluginData->streamInfo) );
UpdateInfoTimeOut( visualPluginData );
}
//-------------------------------------------------------------------------------------------------
// RequestArtwork
//-------------------------------------------------------------------------------------------------
//
static void RequestArtwork( VisualPluginData * visualPluginData )
{
// only request artwork if this plugin is active
if ( visualPluginData->destView != NULL )
{
OSStatus status;
status = PlayerRequestCurrentTrackCoverArt( visualPluginData->appCookie, visualPluginData->appProc );
}
}
//-------------------------------------------------------------------------------------------------
// PulseVisual
//-------------------------------------------------------------------------------------------------
//
void PulseVisual( VisualPluginData * visualPluginData, UInt32 timeStampID, const RenderVisualData * renderData, UInt32 * ioPulseRate )
{
// update internal state
ProcessRenderData( visualPluginData, timeStampID, renderData );
// if desired, adjust the pulse rate
UpdatePulseRate( visualPluginData, ioPulseRate );
}
//-------------------------------------------------------------------------------------------------
// VisualPluginHandler
//-------------------------------------------------------------------------------------------------
//
static OSStatus VisualPluginHandler(OSType message,VisualPluginMessageInfo *messageInfo, void *refCon)
{
OSStatus status;
VisualPluginData * visualPluginData;
visualPluginData = (VisualPluginData*) refCon;
status = noErr;
switch ( message )
{
/*
Sent when the visual plugin is registered. The plugin should do minimal
memory allocations here.
*/
case kVisualPluginInitMessage:
{
visualPluginData = (VisualPluginData *)calloc( 1, sizeof(VisualPluginData) );
if ( visualPluginData == NULL )
{
status = memFullErr;
break;
}
visualPluginData->appCookie = messageInfo->u.initMessage.appCookie;
visualPluginData->appProc = messageInfo->u.initMessage.appProc;
messageInfo->u.initMessage.refCon = (void *)visualPluginData;
break;
}
/*
Sent when the visual plugin is unloaded.
*/
case kVisualPluginCleanupMessage:
{
if ( visualPluginData != NULL ) {
if (visualPluginData->pm) {
delete(visualPluginData->pm);
visualPluginData->pm = NULL;
}
free( visualPluginData );
}
break;
}
/*
Sent when the visual plugin is enabled/disabled. iTunes currently enables all
loaded visual plugins at launch. The plugin should not do anything here.
*/
case kVisualPluginEnableMessage:
case kVisualPluginDisableMessage:
{
break;
}
/*
Sent if the plugin requests idle messages. Do this by setting the kVisualWantsIdleMessages
option in the RegisterVisualMessage.options field.
DO NOT DRAW in this routine. It is for updating internal state only.
*/
case kVisualPluginIdleMessage:
{
break;
}
/*
Sent if the plugin requests the ability for the user to configure it. Do this by setting
the kVisualWantsConfigure option in the RegisterVisualMessage.options field.
*/
case kVisualPluginConfigureMessage:
{
status = ConfigureVisual( visualPluginData );
break;
}
/*
Sent when iTunes is going to show the visual plugin. At this
point, the plugin should allocate any large buffers it needs.
*/
case kVisualPluginActivateMessage:
{
status = ActivateVisual( visualPluginData, messageInfo->u.activateMessage.view, messageInfo->u.activateMessage.options );
// note: do not draw here if you can avoid it, a draw message will be sent as soon as possible
if ( status == noErr )
RequestArtwork( visualPluginData );
break;
}
/*
Sent when this visual is no longer displayed.
*/
case kVisualPluginDeactivateMessage:
{
UpdateTrackInfo( visualPluginData, NULL, NULL );
status = DeactivateVisual( visualPluginData );
break;
}
/*
Sent when iTunes is moving the destination view to a new parent window (e.g. to/from fullscreen).
*/
case kVisualPluginWindowChangedMessage:
{
status = MoveVisual( visualPluginData, messageInfo->u.windowChangedMessage.options );
break;
}
/*
Sent when iTunes has changed the rectangle of the currently displayed visual.
Note: for custom NSView subviews, the subview's frame is automatically resized.
*/
case kVisualPluginFrameChangedMessage:
{
status = ResizeVisual( visualPluginData );
break;
}
/*
Sent for the visual plugin to update its internal animation state.
Plugins are allowed to draw at this time but it is more efficient if they
wait until the kVisualPluginDrawMessage is sent OR they simply invalidate
their own subview. The pulse message can be sent faster than the system
will allow drawing to support spectral analysis-type plugins but drawing
will be limited to the system refresh rate.
*/
case kVisualPluginPulseMessage:
{
PulseVisual( visualPluginData,
messageInfo->u.pulseMessage.timeStampID,
messageInfo->u.pulseMessage.renderData,
&messageInfo->u.pulseMessage.newPulseRateInHz );
InvalidateVisual( visualPluginData );
break;
}
/*
It's time for the plugin to draw a new frame.
For plugins using custom subviews, you should ignore this message and just
draw in your view's draw method. It will never be called if your subview
is set up properly.
*/
case kVisualPluginDrawMessage:
{
#if !USE_SUBVIEW
DrawVisual( visualPluginData );
#endif
break;
}
/*
Sent when the player starts.
*/
case kVisualPluginPlayMessage:
{
visualPluginData->playing = true;
UpdateTrackInfo( visualPluginData, messageInfo->u.playMessage.trackInfo, messageInfo->u.playMessage.streamInfo );
RequestArtwork( visualPluginData );
InvalidateVisual( visualPluginData );
break;
}
/*
Sent when the player changes the current track information. This
is used when the information about a track changes.
*/
case kVisualPluginChangeTrackMessage:
{
UpdateTrackInfo( visualPluginData, messageInfo->u.changeTrackMessage.trackInfo, messageInfo->u.changeTrackMessage.streamInfo );
RequestArtwork( visualPluginData );
InvalidateVisual( visualPluginData );
break;
}
/*
Artwork for the currently playing song is being delivered per a previous request.
Note that NULL for messageInfo->u.coverArtMessage.coverArt means the currently playing song has no artwork.
*/
case kVisualPluginCoverArtMessage:
{
UpdateArtwork( visualPluginData,
messageInfo->u.coverArtMessage.coverArt,
messageInfo->u.coverArtMessage.coverArtSize,
messageInfo->u.coverArtMessage.coverArtFormat );
InvalidateVisual( visualPluginData );
break;
}
/*
Sent when the player stops or pauses.
*/
case kVisualPluginStopMessage:
{
visualPluginData->playing = false;
ResetRenderData( visualPluginData );
InvalidateVisual( visualPluginData );
break;
}
/*
Sent when the player changes the playback position.
*/
case kVisualPluginSetPositionMessage:
{
break;
}
default:
{
status = unimpErr;
break;
}
}
return status;
}
//-------------------------------------------------------------------------------------------------
// RegisterVisualPlugin
//-------------------------------------------------------------------------------------------------
//
OSStatus RegisterVisualPlugin( PluginMessageInfo * messageInfo )
{
PlayerMessageInfo playerMessageInfo;
OSStatus status;
memset( &playerMessageInfo.u.registerVisualPluginMessage, 0, sizeof(playerMessageInfo.u.registerVisualPluginMessage) );
GetVisualName( playerMessageInfo.u.registerVisualPluginMessage.name );
SetNumVersion( &playerMessageInfo.u.registerVisualPluginMessage.pluginVersion, kTVisualPluginMajorVersion, kTVisualPluginMinorVersion, kTVisualPluginReleaseStage, kTVisualPluginNonFinalRelease );
playerMessageInfo.u.registerVisualPluginMessage.options = GetVisualOptions();
playerMessageInfo.u.registerVisualPluginMessage.handler = (VisualPluginProcPtr)VisualPluginHandler;
playerMessageInfo.u.registerVisualPluginMessage.registerRefCon = 0;
playerMessageInfo.u.registerVisualPluginMessage.creator = kTVisualPluginCreator;
playerMessageInfo.u.registerVisualPluginMessage.pulseRateInHz = kStoppedPulseRateInHz; // update my state N times a second
playerMessageInfo.u.registerVisualPluginMessage.numWaveformChannels = 2;
playerMessageInfo.u.registerVisualPluginMessage.numSpectrumChannels = 2;
playerMessageInfo.u.registerVisualPluginMessage.minWidth = 64;
playerMessageInfo.u.registerVisualPluginMessage.minHeight = 64;
playerMessageInfo.u.registerVisualPluginMessage.maxWidth = 0; // no max width limit
playerMessageInfo.u.registerVisualPluginMessage.maxHeight = 0; // no max height limit
status = PlayerRegisterVisualPlugin( messageInfo->u.initMessage.appCookie, messageInfo->u.initMessage.appProc, &playerMessageInfo );
return status;
}

View File

@ -0,0 +1,373 @@
// main drawing and interface code for Mac OS iTunes
// Mischa Spiegelmock, 2012
// based on the iTunes SDK example code
#import "iprojectM.hpp"
#import <AppKit/AppKit.h>
#import <OpenGL/gl.h>
#import <OpenGL/glu.h>
#import <string.h>
//-------------------------------------------------------------------------------------------------
// constants, etc.
//-------------------------------------------------------------------------------------------------
#define kTVisualPluginName CFSTR("projectM")
extern "C" OSStatus iTunesPluginMainMachO( OSType inMessage, PluginMessageInfo *inMessageInfoPtr, void *refCon ) __attribute__((visibility("default")));
#if USE_SUBVIEW
@interface VisualView : NSOpenGLView
{
VisualPluginData * _visualPluginData;
}
@property (nonatomic, assign) VisualPluginData * visualPluginData;
- (void)drawRect:(NSRect)dirtyRect;
- (BOOL)acceptsFirstResponder;
- (BOOL)becomeFirstResponder;
- (BOOL)resignFirstResponder;
- (void)keyDown:(NSEvent *)theEvent;
@end
#endif // USE_SUBVIEW
void DrawVisual( VisualPluginData * visualPluginData )
{
CGPoint where;
VISUAL_PLATFORM_VIEW drawView = visualPluginData->subview;
if ( drawView == NULL )
return;
[[drawView openGLContext] makeCurrentContext];
if (visualPluginData->pm == NULL) {
initProjectM(visualPluginData);
// correctly size it
ResizeVisual(visualPluginData);
}
glClearColor( 0.0, 0.5, 0.0, 0.0 );
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// render
visualPluginData->pm->renderFrame();
glFlush();
// should we draw the info/artwork in the bottom-left corner?
time_t theTime = time( NULL );
if ( theTime < visualPluginData->drawInfoTimeOut )
{
where = CGPointMake( 10, 10 );
// if we have a song title, draw it (prefer the stream title over the regular name if we have it)
NSString * theString = NULL;
if ( visualPluginData->streamInfo.streamTitle[0] != 0 )
theString = [NSString stringWithCharacters:&visualPluginData->streamInfo.streamTitle[1] length:visualPluginData->streamInfo.streamTitle[0]];
else if ( visualPluginData->trackInfo.name[0] != 0 )
theString = [NSString stringWithCharacters:&visualPluginData->trackInfo.name[1] length:visualPluginData->trackInfo.name[0]];
if ( theString != NULL )
{
NSDictionary * attrs = [NSDictionary dictionaryWithObjectsAndKeys:[NSColor whiteColor], NSForegroundColorAttributeName, NULL];
[theString drawAtPoint:where withAttributes:attrs];
}
// draw the artwork
if ( visualPluginData->currentArtwork != NULL )
{
where.y += 20;
[visualPluginData->currentArtwork drawAtPoint:where fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:0.75];
}
}
}
//-------------------------------------------------------------------------------------------------
// UpdateArtwork
//-------------------------------------------------------------------------------------------------
//
void UpdateArtwork( VisualPluginData * visualPluginData, CFDataRef coverArt, UInt32 coverArtSize, UInt32 coverArtFormat )
{
// release current image
[visualPluginData->currentArtwork release];
visualPluginData->currentArtwork = NULL;
// create 100x100 NSImage* out of incoming CFDataRef if non-null (null indicates there is no artwork for the current track)
if ( coverArt != NULL )
{
visualPluginData->currentArtwork = [[NSImage alloc] initWithData:(NSData *)coverArt];
[visualPluginData->currentArtwork setSize:CGSizeMake( 100, 100 )];
}
UpdateInfoTimeOut( visualPluginData );
}
//-------------------------------------------------------------------------------------------------
// InvalidateVisual
//-------------------------------------------------------------------------------------------------
//
void InvalidateVisual( VisualPluginData * visualPluginData )
{
(void) visualPluginData;
#if USE_SUBVIEW
// when using a custom subview, we invalidate it so we get our own draw calls
[visualPluginData->subview setNeedsDisplay:YES];
#endif
}
//-------------------------------------------------------------------------------------------------
// CreateVisualContext
//-------------------------------------------------------------------------------------------------
//
OSStatus ActivateVisual( VisualPluginData * visualPluginData, VISUAL_PLATFORM_VIEW destView, OptionBits options )
{
OSStatus status = noErr;
visualPluginData->destView = destView;
visualPluginData->destRect = [destView bounds];
visualPluginData->destOptions = options;
UpdateInfoTimeOut( visualPluginData );
#if USE_SUBVIEW
// NSView-based subview
visualPluginData->subview = [[VisualView alloc] initWithFrame:visualPluginData->destRect];
if ( visualPluginData->subview != NULL )
{
[visualPluginData->subview setAutoresizingMask: (NSViewWidthSizable | NSViewHeightSizable)];
[visualPluginData->subview setVisualPluginData:visualPluginData];
[destView addSubview:visualPluginData->subview];
}
else
{
status = memFullErr;
}
#endif
return status;
}
//-------------------------------------------------------------------------------------------------
// MoveVisual
//-------------------------------------------------------------------------------------------------
//
OSStatus MoveVisual( VisualPluginData * visualPluginData, OptionBits newOptions )
{
visualPluginData->destRect = [visualPluginData->destView bounds];
visualPluginData->destOptions = newOptions;
return noErr;
}
//-------------------------------------------------------------------------------------------------
// DeactivateVisual
//-------------------------------------------------------------------------------------------------
//
OSStatus DeactivateVisual( VisualPluginData * visualPluginData )
{
#if USE_SUBVIEW
[visualPluginData->subview removeFromSuperview];
[visualPluginData->subview autorelease];
visualPluginData->subview = NULL;
[visualPluginData->currentArtwork release];
visualPluginData->currentArtwork = NULL;
#endif
visualPluginData->destView = NULL;
visualPluginData->destRect = CGRectNull;
visualPluginData->drawInfoTimeOut = 0;
if (visualPluginData->pm != NULL) {
delete(visualPluginData->pm);
visualPluginData->pm = NULL;
}
return noErr;
}
//-------------------------------------------------------------------------------------------------
// ResizeVisual
//-------------------------------------------------------------------------------------------------
//
OSStatus ResizeVisual( VisualPluginData * visualPluginData )
{
visualPluginData->destRect = [visualPluginData->destView bounds];
if (visualPluginData->pm != NULL) {
visualPluginData->pm->projectM_resetGL(visualPluginData->destRect.size.width, visualPluginData->destRect.size.height);
}
return noErr;
}
//-------------------------------------------------------------------------------------------------
// ConfigureVisual
//-------------------------------------------------------------------------------------------------
//
OSStatus ConfigureVisual( VisualPluginData * visualPluginData )
{
(void) visualPluginData;
// load nib
// show modal dialog
// update settings
// invalidate
return noErr;
}
#pragma mark -
#if USE_SUBVIEW
@implementation VisualView
@synthesize visualPluginData = _visualPluginData;
//-------------------------------------------------------------------------------------------------
// isOpaque
//-------------------------------------------------------------------------------------------------
//
- (BOOL)isOpaque
{
// your custom views should always be opaque or iTunes will waste CPU time drawing behind you
return YES;
}
//-------------------------------------------------------------------------------------------------
// drawRect
//-------------------------------------------------------------------------------------------------
//
-(void)drawRect:(NSRect)dirtyRect
{
if ( _visualPluginData != NULL )
{
DrawVisual( _visualPluginData );
}
}
//-------------------------------------------------------------------------------------------------
// acceptsFirstResponder
//-------------------------------------------------------------------------------------------------
//
- (BOOL)acceptsFirstResponder
{
return YES;
}
//-------------------------------------------------------------------------------------------------
// becomeFirstResponder
//-------------------------------------------------------------------------------------------------
//
- (BOOL)becomeFirstResponder
{
return YES;
}
//-------------------------------------------------------------------------------------------------
// resignFirstResponder
//-------------------------------------------------------------------------------------------------
//
- (BOOL)resignFirstResponder
{
return YES;
}
//-------------------------------------------------------------------------------------------------
// keyDown
//-------------------------------------------------------------------------------------------------
//
-(void)keyDown:(NSEvent *)theEvent
{
// Handle key events here.
// Do not eat the space bar, ESC key, TAB key, or the arrow keys: iTunes reserves those keys.
// if the 'i' key is pressed, reset the info timeout so that we draw it again
if ( [[theEvent charactersIgnoringModifiers] isEqualTo:@"i"] )
{
UpdateInfoTimeOut( _visualPluginData );
return;
}
// Pass all unhandled events up to super so that iTunes can handle them.
[super keyDown:theEvent];
}
@end
#endif // USE_SUBVIEW
#pragma mark -
//-------------------------------------------------------------------------------------------------
// GetVisualName
//-------------------------------------------------------------------------------------------------
//
void GetVisualName( ITUniStr255 name )
{
CFIndex length = CFStringGetLength( kTVisualPluginName );
name[0] = (UniChar)length;
CFStringGetCharacters( kTVisualPluginName, CFRangeMake( 0, length ), &name[1] );
}
//-------------------------------------------------------------------------------------------------
// GetVisualOptions
//-------------------------------------------------------------------------------------------------
//
OptionBits GetVisualOptions( void )
{
OptionBits options = (kVisualSupportsMuxedGraphics | kVisualWantsIdleMessages);
#if USE_SUBVIEW
options |= kVisualUsesSubview;
#endif
return options;
}
//-------------------------------------------------------------------------------------------------
// iTunesPluginMainMachO
//-------------------------------------------------------------------------------------------------
//
OSStatus iTunesPluginMainMachO( OSType message, PluginMessageInfo * messageInfo, void * refCon )
{
OSStatus status;
(void) refCon;
switch ( message )
{
case kPluginInitMessage:
status = RegisterVisualPlugin( messageInfo );
break;
case kPluginCleanupMessage:
status = noErr;
break;
default:
status = unimpErr;
break;
}
return status;
}

View File

@ -0,0 +1,360 @@
//
// File: iTunesPlugInWin.cpp
//
// Abstract: Visual plug-in for iTunes on Windows
//
// Version: 2.0
//
// Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. ( "Apple" )
// in consideration of your agreement to the following terms, and your use,
// installation, modification or redistribution of this Apple software
// constitutes acceptance of these terms. If you do not agree with these
// terms, please do not use, install, modify or redistribute this Apple
// software.
//
// In consideration of your agreement to abide by the following terms, and
// subject to these terms, Apple grants you a personal, non - exclusive
// license, under Apple's copyrights in this original Apple software ( the
// "Apple Software" ), to use, reproduce, modify and redistribute the Apple
// Software, with or without modifications, in source and / or binary forms;
// provided that if you redistribute the Apple Software in its entirety and
// without modifications, you must retain this notice and the following text
// and disclaimers in all such redistributions of the Apple Software. Neither
// the name, trademarks, service marks or logos of Apple Inc. may be used to
// endorse or promote products derived from the Apple Software without specific
// prior written permission from Apple. Except as expressly stated in this
// notice, no other rights or licenses, express or implied, are granted by
// Apple herein, including but not limited to any patent rights that may be
// infringed by your derivative works or by other works in which the Apple
// Software may be incorporated.
//
// The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
// WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
// WARRANTIES OF NON - INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION
// ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
//
// IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
// CONSEQUENTIAL DAMAGES ( INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION ) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION
// AND / OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER
// UNDER THEORY OF CONTRACT, TORT ( INCLUDING NEGLIGENCE ), STRICT LIABILITY OR
// OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Copyright (c) 2001-2011 Apple Inc. All Rights Reserved.
//
//-------------------------------------------------------------------------------------------------
// includes
//-------------------------------------------------------------------------------------------------
#include "iTunesPlugIn.h"
#include "Time.h"
#include <GdiPlus.h>
#include <string>
//-------------------------------------------------------------------------------------------------
// constants, etc.
//-------------------------------------------------------------------------------------------------
#define kTVisualPluginName L"iTunes Sample Visualizer"
static WNDPROC giTunesWndProc = NULL;
static VisualPluginData* gVisualPluginData = NULL;
//-------------------------------------------------------------------------------------------------
// WndProc
//-------------------------------------------------------------------------------------------------
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CHAR: // handle key pressed messages
if (wParam == 'I' || wParam == 'i')
{
UpdateInfoTimeOut( gVisualPluginData );
}
break;
default:
break;
}
// call iTunes with the event. Always send space bar, ESC key, TAB key and the arrow keys: iTunes reserves those keys
return CallWindowProc( giTunesWndProc, hWnd, message, wParam, lParam );
}
//-------------------------------------------------------------------------------------------------
// DrawVisual
//-------------------------------------------------------------------------------------------------
//
void DrawVisual( VisualPluginData * visualPluginData )
{
// this shouldn't happen but let's be safe
if ( visualPluginData && visualPluginData->destView != NULL )
{
HDC hDC = ::GetDC( visualPluginData->destView );
// fill the whole view with black to start
RECT clientRect;
::GetClientRect( visualPluginData->destView, &clientRect );
::FillRect( hDC, &clientRect, (HBRUSH) GetStockObject( BLACK_BRUSH ) );
// pick a random location to draw our little square
double randomX = (rand() / 32767.0); // [0, 1]
double randomY = (rand() / 32767.0); // [0, 1]
LONG whereX = (LONG) (randomX * ( clientRect.right - clientRect.left ));
LONG whereY = (LONG) (randomY * ( clientRect.bottom - clientRect.top ));
COLORREF color;
if ( visualPluginData->playing )
{
// if playing, draw a square whose color is dictated by the current max levels
int red = visualPluginData->maxLevel[1];
int green = visualPluginData->maxLevel[1];
int blue = visualPluginData->maxLevel[0];
color = RGB(red, green, blue);
}
else
{
color = RGB(0, 0, 255); // a blue square
}
RECT drawRect;
drawRect.left = whereX;
drawRect.top = whereY;
drawRect.right = drawRect.left + 100;
drawRect.bottom = drawRect.top + 100;
HBRUSH brush = CreateSolidBrush( color );
FillRect( hDC, &drawRect, brush );
DeleteObject( brush );
// should we draw the info/artwork in the bottom-left corner?
time_t theTime = time( NULL );
if ( theTime < visualPluginData->drawInfoTimeOut )
{
whereX = 10;
whereY = clientRect.bottom - 30;
// if we have a song title, draw it (prefer the stream title over the regular name if we have it)
wchar_t* theString;
int stringSize(0);
if ( visualPluginData->streamInfo.streamTitle[0] != 0 )
{
theString = (wchar_t*) visualPluginData->streamInfo.streamTitle[1];
stringSize = visualPluginData->streamInfo.streamTitle[0];
}
else if ( visualPluginData->trackInfo.name[0] != 0 )
{
theString = (wchar_t*) &visualPluginData->trackInfo.name[1];
stringSize = visualPluginData->trackInfo.name[0];
}
// Draw the string
if ( theString != NULL )
{
RECT stringRect = {whereX, whereY, whereX + 400, whereY + 20};
COLORREF oldTextColor = SetTextColor (hDC, RGB(200, 200, 200));
COLORREF oldBkColor = SetBkColor (hDC, RGB(0, 0, 0));
::TextOutW( hDC, whereX, whereY, theString, stringSize );
SetTextColor( hDC, oldTextColor );
SetBkColor( hDC, oldBkColor );
}
if ( visualPluginData->currentArtwork )
{
Gdiplus::Graphics graphics(hDC);
int imageSizeOnScreen_Width = 120;
int imageSizeOnScreen_Height = imageSizeOnScreen_Width * ( visualPluginData->currentArtwork->GetHeight() / visualPluginData->currentArtwork->GetWidth() );
whereY = whereY - 10 - imageSizeOnScreen_Height;
graphics.DrawImage(visualPluginData->currentArtwork, whereX, whereY, imageSizeOnScreen_Width, imageSizeOnScreen_Height);
}
ReleaseDC( visualPluginData->destView, hDC );
}
}
}
//-------------------------------------------------------------------------------------------------
// UpdateArtwork
//-------------------------------------------------------------------------------------------------
//
void UpdateArtwork( VisualPluginData * visualPluginData, VISUAL_PLATFORM_DATA coverArt, UInt32 coverArtSize, UInt32 coverArtFormat )
{
visualPluginData->currentArtwork = NULL;
HGLOBAL globalMemory = GlobalAlloc( GMEM_MOVEABLE, coverArtSize );
if ( globalMemory )
{
void* pBuffer = ::GlobalLock(globalMemory);
if ( pBuffer )
{
memcpy( pBuffer, coverArt, coverArtSize );
IStream* stream = NULL;
CreateStreamOnHGlobal( globalMemory, TRUE, &stream );
if ( stream )
{
Gdiplus::Bitmap* gdiPlusBitmap = Gdiplus::Bitmap::FromStream( stream );
stream->Release();
if ( gdiPlusBitmap && gdiPlusBitmap->GetLastStatus() == Gdiplus::Ok)
{
visualPluginData->currentArtwork = gdiPlusBitmap;
}
}
}
}
UpdateInfoTimeOut( visualPluginData );
}
//-------------------------------------------------------------------------------------------------
// InvalidateVisual
//-------------------------------------------------------------------------------------------------
//
void InvalidateVisual( VisualPluginData * visualPluginData )
{
(void) visualPluginData;
// set flags for internal state to decide what to draw the next time around
}
//-------------------------------------------------------------------------------------------------
// ActivateVisual
//-------------------------------------------------------------------------------------------------
//
OSStatus ActivateVisual( VisualPluginData * visualPluginData, VISUAL_PLATFORM_VIEW destView, OptionBits options )
{
gVisualPluginData = visualPluginData;
GetClientRect( destView, &visualPluginData->destRect );
visualPluginData->destView = destView;
visualPluginData->destOptions = options;
if ( giTunesWndProc == NULL )
{
giTunesWndProc = (WNDPROC) SetWindowLong( destView, GWL_WNDPROC, (LONG) WndProc );
}
UpdateInfoTimeOut( visualPluginData );
return noErr;
}
//-------------------------------------------------------------------------------------------------
// MoveVisual
//-------------------------------------------------------------------------------------------------
//
OSStatus MoveVisual( VisualPluginData * visualPluginData, OptionBits newOptions )
{
GetClientRect( visualPluginData->destView, &visualPluginData->destRect );
visualPluginData->destOptions = newOptions;
return noErr;
}
//-------------------------------------------------------------------------------------------------
// DeactivateVisual
//-------------------------------------------------------------------------------------------------
//
OSStatus DeactivateVisual( VisualPluginData * visualPluginData )
{
gVisualPluginData = NULL;
if (giTunesWndProc != NULL )
{
SetWindowLong( visualPluginData->destView, GWL_WNDPROC, (LONG) giTunesWndProc );
giTunesWndProc = NULL;
}
visualPluginData->destView = NULL;
return noErr;
}
//-------------------------------------------------------------------------------------------------
// ResizeVisual
//-------------------------------------------------------------------------------------------------
//
OSStatus ResizeVisual( VisualPluginData * visualPluginData )
{
GetClientRect( visualPluginData->destView, &visualPluginData->destRect );
visualPluginData->lastDrawTime = 0;
return noErr;
}
//-------------------------------------------------------------------------------------------------
// ConfigureVisual
//-------------------------------------------------------------------------------------------------
//
OSStatus ConfigureVisual( VisualPluginData * visualPluginData )
{
(void) visualPluginData;
visualPluginData->currentArtwork = NULL;
return noErr;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
//-------------------------------------------------------------------------------------------------
// GetVisualName
//-------------------------------------------------------------------------------------------------
//
void GetVisualName( ITUniStr255 name )
{
name[0] = (UniChar)wcslen( kTVisualPluginName );
wcscpy_s( (wchar_t *)&name[1], 255, kTVisualPluginName );
}
//-------------------------------------------------------------------------------------------------
// GetVisualOptions
//-------------------------------------------------------------------------------------------------
//
OptionBits GetVisualOptions( void )
{
return kVisualWantsIdleMessages;
}
//-------------------------------------------------------------------------------------------------
// iTunesPluginMain
//-------------------------------------------------------------------------------------------------
//
extern "C" __declspec(dllexport) OSStatus iTunesPluginMain( OSType message, PluginMessageInfo * messageInfo, void * refCon )
{
OSStatus status;
(void) refCon;
switch ( message )
{
case kPluginInitMessage:
status = RegisterVisualPlugin( messageInfo );
break;
case kPluginCleanupMessage:
status = noErr;
break;
default:
status = unimpErr;
break;
}
return status;
}

View File

@ -1,294 +0,0 @@
/*
File: iTunesAPI.c
Contains: iTunes Plug-ins interfaces
Version: Technology: iTunes
Release: 1.1
Copyright: <20> 2001 by Apple Computer, Inc., all rights reserved.
Bugs?: For bug reports, consult the following page on
the World Wide Web:
http://developer.apple.com/bugreporter/
*/
#include "iTunesAPI.h"
#include "iTunesVisualAPI.h"
// MemClear
//
static void MemClear (LogicalAddress dest, SInt32 length)
{
register unsigned char *ptr;
ptr = (unsigned char *) dest;
if( length > 16 )
{
register unsigned long *longPtr;
while( ((unsigned long) ptr & 3) != 0 )
{
*ptr++ = 0;
--length;
}
longPtr = (unsigned long *) ptr;
while( length >= 4 )
{
*longPtr++ = 0;
length -= 4;
}
ptr = (unsigned char *) longPtr;
}
while( --length >= 0 )
{
*ptr++ = 0;
}
}
// SetNumVersion
//
void SetNumVersion (NumVersion *numVersion, UInt8 majorRev, UInt8 minorAndBugRev, UInt8 stage, UInt8 nonRelRev)
{
numVersion->majorRev = majorRev;
numVersion->minorAndBugRev = minorAndBugRev;
numVersion->stage = stage;
numVersion->nonRelRev = nonRelRev;
}
// ITCallApplication
//
OSStatus ITCallApplication (void *appCookie, ITAppProcPtr handler, OSType message, PlayerMessageInfo *messageInfo)
{
PlayerMessageInfo localMessageInfo;
if (messageInfo == nil)
{
MemClear(&localMessageInfo, sizeof(localMessageInfo));
messageInfo = &localMessageInfo;
}
messageInfo->messageMajorVersion = kITCurrentPluginMajorMessageVersion;
messageInfo->messageMinorVersion = kITCurrentPluginMinorMessageVersion;
messageInfo->messageInfoSize = sizeof(PlayerMessageInfo);
return handler(appCookie, message, messageInfo);
}
// PlayerSetFullScreen
//
OSStatus PlayerSetFullScreen (void *appCookie, ITAppProcPtr appProc, Boolean fullScreen)
{
PlayerMessageInfo messageInfo;
MemClear(&messageInfo, sizeof(messageInfo));
messageInfo.u.setFullScreenMessage.fullScreen = fullScreen;
return ITCallApplication(appCookie, appProc, kPlayerSetFullScreenMessage, &messageInfo);
}
// PlayerSetFullScreenOptions
//
OSStatus PlayerSetFullScreenOptions (void *appCookie, ITAppProcPtr appProc, SInt16 minBitDepth, SInt16 maxBitDepth, SInt16 preferredBitDepth, SInt16 desiredWidth, SInt16 desiredHeight)
{
PlayerMessageInfo messageInfo;
MemClear(&messageInfo, sizeof(messageInfo));
messageInfo.u.setFullScreenOptionsMessage.minBitDepth = minBitDepth;
messageInfo.u.setFullScreenOptionsMessage.maxBitDepth = maxBitDepth;
messageInfo.u.setFullScreenOptionsMessage.preferredBitDepth = preferredBitDepth;
messageInfo.u.setFullScreenOptionsMessage.desiredWidth = desiredWidth;
messageInfo.u.setFullScreenOptionsMessage.desiredHeight = desiredHeight;
return ITCallApplication(appCookie, appProc, kPlayerSetFullScreenOptionsMessage, &messageInfo);
}
// PlayerGetPluginData
//
OSStatus PlayerGetPluginData (void *appCookie, ITAppProcPtr appProc, void *dataPtr, UInt32 dataBufferSize, UInt32 *dataSize)
{
OSStatus status;
PlayerMessageInfo messageInfo;
MemClear(&messageInfo, sizeof(messageInfo));
messageInfo.u.getPluginDataMessage.dataPtr = dataPtr;
messageInfo.u.getPluginDataMessage.dataBufferSize = dataBufferSize;
status = ITCallApplication(appCookie, appProc, kPlayerGetPluginDataMessage, &messageInfo);
if (dataSize != nil)
*dataSize = messageInfo.u.getPluginDataMessage.dataSize;
return status;
}
// PlayerSetPluginData
//
OSStatus PlayerSetPluginData (void *appCookie, ITAppProcPtr appProc, void *dataPtr, UInt32 dataSize)
{
PlayerMessageInfo messageInfo;
MemClear(&messageInfo, sizeof(messageInfo));
messageInfo.u.setPluginDataMessage.dataPtr = dataPtr;
messageInfo.u.setPluginDataMessage.dataSize = dataSize;
return ITCallApplication(appCookie, appProc, kPlayerSetPluginDataMessage, &messageInfo);
}
// PlayerGetPluginNamedData
//
OSStatus PlayerGetPluginNamedData (void *appCookie, ITAppProcPtr appProc, ConstStringPtr dataName, void *dataPtr, UInt32 dataBufferSize, UInt32 *dataSize)
{
OSStatus status;
PlayerMessageInfo messageInfo;
MemClear(&messageInfo, sizeof(messageInfo));
messageInfo.u.getPluginNamedDataMessage.dataName = dataName;
messageInfo.u.getPluginNamedDataMessage.dataPtr = dataPtr;
messageInfo.u.getPluginNamedDataMessage.dataBufferSize = dataBufferSize;
status = ITCallApplication(appCookie, appProc, kPlayerGetPluginNamedDataMessage, &messageInfo);
if (dataSize != nil)
*dataSize = messageInfo.u.getPluginNamedDataMessage.dataSize;
return status;
}
// PlayerSetPluginNamedData
//
OSStatus PlayerSetPluginNamedData (void *appCookie, ITAppProcPtr appProc, ConstStringPtr dataName, void *dataPtr, UInt32 dataSize)
{
PlayerMessageInfo messageInfo;
MemClear(&messageInfo, sizeof(messageInfo));
messageInfo.u.setPluginNamedDataMessage.dataName = dataName;
messageInfo.u.setPluginNamedDataMessage.dataPtr = dataPtr;
messageInfo.u.setPluginNamedDataMessage.dataSize = dataSize;
return ITCallApplication(appCookie, appProc, kPlayerSetPluginNamedDataMessage, &messageInfo);
}
// PlayerIdle
//
OSStatus PlayerIdle (void *appCookie, ITAppProcPtr appProc)
{
return ITCallApplication(appCookie, appProc, kPlayerIdleMessage, nil);
}
// PlayerShowAbout
//
void PlayerShowAbout (void *appCookie, ITAppProcPtr appProc)
{
ITCallApplication(appCookie, appProc, kPlayerShowAboutMessage, nil);
}
// PlayerOpenURL
//
void PlayerOpenURL (void *appCookie, ITAppProcPtr appProc, SInt8 *string, UInt32 length)
{
PlayerMessageInfo messageInfo;
MemClear(&messageInfo, sizeof(messageInfo));
messageInfo.u.openURLMessage.url = string;
messageInfo.u.openURLMessage.length = length;
ITCallApplication(appCookie, appProc, kPlayerOpenURLMessage, &messageInfo);
}
// PlayerUnregisterPlugin
//
OSStatus PlayerUnregisterPlugin (void *appCookie, ITAppProcPtr appProc, PlayerMessageInfo *messageInfo)
{
return ITCallApplication(appCookie, appProc, kPlayerUnregisterPluginMessage, messageInfo);
}
// PlayerRegisterVisualPlugin
//
OSStatus PlayerRegisterVisualPlugin (void *appCookie, ITAppProcPtr appProc, PlayerMessageInfo *messageInfo)
{
return ITCallApplication(appCookie, appProc, kPlayerRegisterVisualPluginMessage, messageInfo);
}
// PlayerRegisterDevicePlugin
//
OSStatus PlayerRegisterDevicePlugin (void *appCookie, ITAppProcPtr appProc, PlayerMessageInfo *messageInfo)
{
return ITCallApplication(appCookie, appProc, kPlayerRegisterDevicePluginMessage, messageInfo);
}
// PlayerSetDeviceSerialNumber
//
OSStatus PlayerSetDeviceSerialNumber (void *appCookie, ITAppProcPtr appProc, ConstStringPtr serialNumber)
{
PlayerMessageInfo messageInfo;
MemClear(&messageInfo, sizeof(messageInfo));
messageInfo.u.setDeviceSerialNumberMessage.serialNumber = serialNumber;
return ITCallApplication(appCookie, appProc, kPlayerSetDeviceSerialNumberMessage, &messageInfo);
}
// PlayerHandleMacOSEvent
//
OSStatus PlayerHandleMacOSEvent (void *appCookie, ITAppProcPtr appProc, const EventRecord *theEvent, Boolean *eventHandled)
{
PlayerMessageInfo messageInfo;
OSStatus status;
MemClear(&messageInfo, sizeof(messageInfo));
messageInfo.u.handleMacOSEventMessage.theEvent = theEvent;
status = ITCallApplication(appCookie, appProc, kPlayerHandleMacOSEventMessage, &messageInfo);
if( eventHandled != nil )
*eventHandled = messageInfo.u.handleMacOSEventMessage.handled;
return status;
}
// PlayerGetPluginFileSpec
//
OSStatus PlayerGetPluginFileSpec (void *appCookie, ITAppProcPtr appProc, FSSpec *pluginFileSpec)
{
PlayerMessageInfo messageInfo;
MemClear(&messageInfo, sizeof(messageInfo));
messageInfo.u.getPluginFileSpecMessage.fileSpec = pluginFileSpec;
return ITCallApplication(appCookie, appProc, kPlayerGetPluginFileSpecMessage, &messageInfo);
}

View File

@ -0,0 +1,332 @@
//
// File: iTunesAPI.c
//
// Abstract: part of iTunes Visual SDK
//
// Version: 2.0
//
// Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. ( "Apple" )
// in consideration of your agreement to the following terms, and your use,
// installation, modification or redistribution of this Apple software
// constitutes acceptance of these terms. If you do not agree with these
// terms, please do not use, install, modify or redistribute this Apple
// software.
//
// In consideration of your agreement to abide by the following terms, and
// subject to these terms, Apple grants you a personal, non - exclusive
// license, under Apple's copyrights in this original Apple software ( the
// "Apple Software" ), to use, reproduce, modify and redistribute the Apple
// Software, with or without modifications, in source and / or binary forms;
// provided that if you redistribute the Apple Software in its entirety and
// without modifications, you must retain this notice and the following text
// and disclaimers in all such redistributions of the Apple Software. Neither
// the name, trademarks, service marks or logos of Apple Inc. may be used to
// endorse or promote products derived from the Apple Software without specific
// prior written permission from Apple. Except as expressly stated in this
// notice, no other rights or licenses, express or implied, are granted by
// Apple herein, including but not limited to any patent rights that may be
// infringed by your derivative works or by other works in which the Apple
// Software may be incorporated.
//
// The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
// WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
// WARRANTIES OF NON - INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION
// ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
//
// IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
// CONSEQUENTIAL DAMAGES ( INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION ) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION
// AND / OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER
// UNDER THEORY OF CONTRACT, TORT ( INCLUDING NEGLIGENCE ), STRICT LIABILITY OR
// OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Copyright © 2000-2011 Apple Inc. All Rights Reserved.
//
#include "iTunesAPI.h"
#include "iTunesVisualAPI.h"
#include <string.h>
// SetNumVersion
//
void SetNumVersion(NumVersion *numVersion, UInt8 majorRev, UInt8 minorAndBugRev, UInt8 stage, UInt8 nonRelRev)
{
numVersion->majorRev = majorRev;
numVersion->minorAndBugRev = minorAndBugRev;
numVersion->stage = stage;
numVersion->nonRelRev = nonRelRev;
}
// ITCallApplicationInternal
//
static OSStatus ITCallApplicationInternal(void *appCookie, ITAppProcPtr handler, OSType message, UInt32 messageMajorVersion, UInt32 messageMinorVersion, PlayerMessageInfo *messageInfo)
{
PlayerMessageInfo localMessageInfo;
if (messageInfo == nil)
{
memset(&localMessageInfo, 0, sizeof(localMessageInfo));
messageInfo = &localMessageInfo;
}
messageInfo->messageMajorVersion = messageMajorVersion;
messageInfo->messageMinorVersion = messageMinorVersion;
messageInfo->messageInfoSize = sizeof(PlayerMessageInfo);
return handler(appCookie, message, messageInfo);
}
// ITCallApplication
//
OSStatus ITCallApplication(void *appCookie, ITAppProcPtr handler, OSType message, PlayerMessageInfo *messageInfo)
{
return ITCallApplicationInternal(appCookie, handler, message, kITPluginMajorMessageVersion, kITPluginMinorMessageVersion, messageInfo);
}
// PlayerSetFullScreen
//
OSStatus PlayerSetFullScreen(void *appCookie, ITAppProcPtr appProc, Boolean fullScreen)
{
PlayerMessageInfo messageInfo;
memset(&messageInfo, 0, sizeof(messageInfo));
messageInfo.u.setFullScreenMessage.fullScreen = fullScreen;
return ITCallApplication(appCookie, appProc, kPlayerSetFullScreenMessage, &messageInfo);
}
// PlayerRequestCurrentTrackCoverArt
//
OSStatus PlayerRequestCurrentTrackCoverArt(void *appCookie, ITAppProcPtr appProc)
{
OSStatus status;
status = ITCallApplication(appCookie, appProc, kPlayerRequestCurrentTrackCoverArtMessage, nil);
return status;
}
// PlayerGetPluginData
//
OSStatus PlayerGetPluginData(void *appCookie, ITAppProcPtr appProc, void *dataPtr, UInt32 dataBufferSize, UInt32 *dataSize)
{
OSStatus status;
PlayerMessageInfo messageInfo;
memset(&messageInfo, 0, sizeof(messageInfo));
messageInfo.u.getPluginDataMessage.dataPtr = dataPtr;
messageInfo.u.getPluginDataMessage.dataBufferSize = dataBufferSize;
status = ITCallApplication(appCookie, appProc, kPlayerGetPluginDataMessage, &messageInfo);
if (dataSize != nil)
*dataSize = messageInfo.u.getPluginDataMessage.dataSize;
return status;
}
// PlayerSetPluginData
//
OSStatus PlayerSetPluginData(void *appCookie, ITAppProcPtr appProc, void *dataPtr, UInt32 dataSize)
{
PlayerMessageInfo messageInfo;
memset(&messageInfo, 0, sizeof(messageInfo));
messageInfo.u.setPluginDataMessage.dataPtr = dataPtr;
messageInfo.u.setPluginDataMessage.dataSize = dataSize;
return ITCallApplication(appCookie, appProc, kPlayerSetPluginDataMessage, &messageInfo);
}
// PlayerGetPluginNamedData
//
OSStatus PlayerGetPluginNamedData(void *appCookie, ITAppProcPtr appProc, ConstStringPtr dataName, void *dataPtr, UInt32 dataBufferSize, UInt32 *dataSize)
{
OSStatus status;
PlayerMessageInfo messageInfo;
memset(&messageInfo, 0, sizeof(messageInfo));
messageInfo.u.getPluginNamedDataMessage.dataName = dataName;
messageInfo.u.getPluginNamedDataMessage.dataPtr = dataPtr;
messageInfo.u.getPluginNamedDataMessage.dataBufferSize = dataBufferSize;
status = ITCallApplication(appCookie, appProc, kPlayerGetPluginNamedDataMessage, &messageInfo);
if (dataSize != nil)
*dataSize = messageInfo.u.getPluginNamedDataMessage.dataSize;
return status;
}
// PlayerSetPluginNamedData
//
OSStatus PlayerSetPluginNamedData(void *appCookie, ITAppProcPtr appProc, ConstStringPtr dataName, void *dataPtr, UInt32 dataSize)
{
PlayerMessageInfo messageInfo;
memset(&messageInfo, 0, sizeof(messageInfo));
messageInfo.u.setPluginNamedDataMessage.dataName = dataName;
messageInfo.u.setPluginNamedDataMessage.dataPtr = dataPtr;
messageInfo.u.setPluginNamedDataMessage.dataSize = dataSize;
return ITCallApplication(appCookie, appProc, kPlayerSetPluginNamedDataMessage, &messageInfo);
}
// PlayerIdle
//
OSStatus PlayerIdle(void *appCookie, ITAppProcPtr appProc)
{
return ITCallApplication(appCookie, appProc, kPlayerIdleMessage, nil);
}
// PlayerShowAbout
//
void PlayerShowAbout(void *appCookie, ITAppProcPtr appProc)
{
ITCallApplication(appCookie, appProc, kPlayerShowAboutMessage, nil);
}
// PlayerOpenURL
//
void PlayerOpenURL(void *appCookie, ITAppProcPtr appProc, SInt8 *string, UInt32 length)
{
PlayerMessageInfo messageInfo;
memset(&messageInfo, 0, sizeof(messageInfo));
messageInfo.u.openURLMessage.url = string;
messageInfo.u.openURLMessage.length = length;
ITCallApplication(appCookie, appProc, kPlayerOpenURLMessage, &messageInfo);
}
// PlayerUnregisterPlugin
//
OSStatus PlayerUnregisterPlugin(void *appCookie, ITAppProcPtr appProc, PlayerMessageInfo *messageInfo)
{
return ITCallApplication(appCookie, appProc, kPlayerUnregisterPluginMessage, messageInfo);
}
// PlayerRegisterVisualPlugin
//
OSStatus PlayerRegisterVisualPlugin(void *appCookie, ITAppProcPtr appProc, PlayerMessageInfo *messageInfo)
{
return ITCallApplicationInternal(appCookie, appProc, kPlayerRegisterVisualPluginMessage, kITVisualPluginMajorMessageVersion, kITVisualPluginMinorMessageVersion, messageInfo);
}
// PlayerGetPluginITFileSpec
//
OSStatus PlayerGetPluginITFileSpec(void *appCookie, ITAppProcPtr appProc, ITFileSpec *pluginFileSpec)
{
PlayerMessageInfo messageInfo;
memset(&messageInfo, 0, sizeof(messageInfo));
messageInfo.u.getPluginITFileSpecMessage.fileSpec = pluginFileSpec;
return ITCallApplication(appCookie, appProc, kPlayerGetPluginITFileSpecMessage, &messageInfo);
}
// PlayerGetFileTrackInfo
//
OSStatus PlayerGetFileTrackInfo(void *appCookie, ITAppProcPtr appProc, const ITFileSpec *fileSpec, ITTrackInfo *trackInfo)
{
PlayerMessageInfo messageInfo;
memset(&messageInfo, 0, sizeof(messageInfo));
messageInfo.u.getFileTrackInfoMessage.fileSpec = fileSpec;
messageInfo.u.getFileTrackInfoMessage.trackInfo = trackInfo;
return ITCallApplication(appCookie, appProc, kPlayerGetFileTrackInfoMessage, &messageInfo);
}
// PlayerSetFileTrackInfo
//
OSStatus PlayerSetFileTrackInfo(void *appCookie, ITAppProcPtr appProc, const ITFileSpec *fileSpec, const ITTrackInfo *trackInfo)
{
PlayerMessageInfo messageInfo;
memset(&messageInfo, 0, sizeof(messageInfo));
messageInfo.u.setFileTrackInfoMessage.fileSpec = fileSpec;
messageInfo.u.setFileTrackInfoMessage.trackInfo = trackInfo;
return ITCallApplication(appCookie, appProc, kPlayerSetFileTrackInfoMessage, &messageInfo);
}
// PlayerGetITTrackInfoSize
//
OSStatus PlayerGetITTrackInfoSize(void *appCookie, ITAppProcPtr appProc, UInt32 appPluginMajorVersion, UInt32 appPluginMinorVersion, UInt32 *itTrackInfoSize)
{
PlayerMessageInfo messageInfo;
OSStatus status;
/*
Note: appPluginMajorVersion and appPluginMinorVersion are the versions given to the plugin by iTunes in the plugin's init message.
These versions are *not* the version of the API used when the plugin was compiled.
*/
*itTrackInfoSize = 0;
memset(&messageInfo, 0, sizeof(messageInfo));
status = ITCallApplication(appCookie, appProc, kPlayerGetITTrackInfoSizeMessage, &messageInfo);
if( status == noErr )
{
*itTrackInfoSize = messageInfo.u.getITTrackInfoSizeMessage.itTrackInfoSize;
}
else if( appPluginMajorVersion == 10 && appPluginMinorVersion == 2 )
{
// iTunes 2.0.x
*itTrackInfoSize = ((UInt32)(uintptr_t) &((ITTrackInfo *) 0)->composer);
status = noErr;
}
else if( appPluginMajorVersion == 10 && appPluginMinorVersion == 3 )
{
// iTunes 3.0.x
*itTrackInfoSize = ((UInt32)(uintptr_t) &((ITTrackInfo *) 0)->beatsPerMinute);
status = noErr;
}
else
{
// iTunes 4.0 and later implement the kPlayerGetITTrackInfoSizeMessage message. If you got here
// then the appPluginMajorVersion or appPluginMinorVersion are incorrect.
status = paramErr;
}
if( status == noErr && (*itTrackInfoSize) > sizeof(ITTrackInfo) )
{
// iTunes is using a larger ITTrackInfo than the one when this plugin was compiled. Pin *itTrackInfoSize to the plugin's known size
*itTrackInfoSize = sizeof(ITTrackInfo);
}
return status;
}

1122
src/projectM-iTunes/macos/iTunesAPI.h Executable file → Normal file

File diff suppressed because it is too large Load Diff

427
src/projectM-iTunes/macos/iTunesVisualAPI.h Executable file → Normal file
View File

@ -1,183 +1,244 @@
/*
File: iTunesVisualAPI.h
Contains: iTunes Visual Plug-ins interfaces
Version: Technology: iTunes
Release: 1.1
Copyright: <20> 2001 by Apple Computer, Inc., all rights reserved.
Bugs?: For bug reports, consult the following page on
the World Wide Web:
http://developer.apple.com/bugreporter/
*/
#ifndef __ITUNESVISUALAPI__
#define __ITUNESVISUALAPI__
#include "iTunesAPI.h"
#if PRAGMA_ONCE
#pragma once
#endif
#ifdef __cplusplus
extern "C" {
#endif
#if PRAGMA_STRUCT_ALIGN
#pragma options align=power
#elif PRAGMA_STRUCT_PACKPUSH
#pragma pack(push, 2)
#elif PRAGMA_STRUCT_PACK
#pragma pack(2)
#endif
enum {
/* VisualPlugin messages */
kVisualPluginIdleMessage = 'null',
kVisualPluginInitMessage = 'init',
kVisualPluginCleanupMessage = 'clr ',
kVisualPluginConfigureMessage = 'cnfg', /* Configure the plugin (may not be enabled) */
kVisualPluginEnableMessage = 'von ', /* Turn on the module (automatic)*/
kVisualPluginDisableMessage = 'voff', /* Turn off the module */
kVisualPluginShowWindowMessage = 'show', /* Show the plugin window (allocate large memory here!) */
kVisualPluginHideWindowMessage = 'hide', /* Hide the plugin window (deallocate large memory here!) */
kVisualPluginSetWindowMessage = 'swin', /* Change the window parameters */
kVisualPluginRenderMessage = 'vrnd', /* Render to window */
kVisualPluginUpdateMessage = 'vupd', /* Update the window */
kVisualPluginPlayMessage = 'vply', /* Playing a track */
kVisualPluginChangeTrackMessage = 'ctrk', /* Change track (for CD continuous play) */
kVisualPluginStopMessage = 'vstp', /* Stopping a track */
kVisualPluginSetPositionMessage = 'setp', /* Setting the position of a track */
kVisualPluginPauseMessage = 'vpau', /* Pausing a track (unused - Pause is stop) */
kVisualPluginUnpauseMessage = 'vunp', /* Unpausing a track (unused - Pause is stop) */
kVisualPluginEventMessage = 'vevt' /* Mac-event. */
};
/*
VisualPlugin messages
*/
enum {
kVisualMaxDataChannels = 2,
kVisualNumWaveformEntries = 512,
kVisualNumSpectrumEntries = 512
};
enum {
/* ShowWindow options */
kWindowIsFullScreen = (1L << 0)
};
struct RenderVisualData {
UInt8 numWaveformChannels;
UInt8 waveformData[kVisualMaxDataChannels][kVisualNumWaveformEntries];
UInt8 numSpectrumChannels;
UInt8 spectrumData[kVisualMaxDataChannels][kVisualNumSpectrumEntries];
};
typedef struct RenderVisualData RenderVisualData;
struct VisualPluginInitMessage {
UInt32 messageMajorVersion; /* Input */
UInt32 messageMinorVersion; /* Input */
NumVersion appVersion; /* Input */
void * appCookie; /* Input */
ITAppProcPtr appProc; /* Input */
OptionBits options; /* Output */
void * refCon; /* Output */
};
typedef struct VisualPluginInitMessage VisualPluginInitMessage;
struct VisualPluginShowWindowMessage {
CGrafPtr port; /* Input */
Rect drawRect; /* Input */
OptionBits options; /* Input */
};
typedef struct VisualPluginShowWindowMessage VisualPluginShowWindowMessage;
struct VisualPluginSetWindowMessage {
CGrafPtr port; /* Input */
Rect drawRect; /* Input */
OptionBits options; /* Input */
};
typedef struct VisualPluginSetWindowMessage VisualPluginSetWindowMessage;
struct VisualPluginPlayMessage {
ITTrackInfo * trackInfo; /* Input */
ITStreamInfo * streamInfo; /* Input */
SInt32 volume; /* Input */
UInt32 bitRate; /* Input */
SoundComponentData soundFormat; /* Input */
};
typedef struct VisualPluginPlayMessage VisualPluginPlayMessage;
struct VisualPluginChangeTrackMessage {
ITTrackInfo * trackInfo; /* Input */
ITStreamInfo * streamInfo; /* Input */
};
typedef struct VisualPluginChangeTrackMessage VisualPluginChangeTrackMessage;
struct VisualPluginRenderMessage {
RenderVisualData * renderData; /* Input */
UInt32 timeStampID; /* Input */
};
typedef struct VisualPluginRenderMessage VisualPluginRenderMessage;
struct VisualPluginSetPositionMessage {
UInt32 positionTimeInMS; /* Input */
};
typedef struct VisualPluginSetPositionMessage VisualPluginSetPositionMessage;
struct VisualPluginEventMessage {
EventRecord * event; /* Input */
};
typedef struct VisualPluginEventMessage VisualPluginEventMessage;
struct VisualPluginMessageInfo {
union {
VisualPluginInitMessage initMessage;
VisualPluginShowWindowMessage showWindowMessage;
VisualPluginSetWindowMessage setWindowMessage;
VisualPluginPlayMessage playMessage;
VisualPluginChangeTrackMessage changeTrackMessage;
VisualPluginRenderMessage renderMessage;
VisualPluginSetPositionMessage setPositionMessage;
VisualPluginEventMessage eventMessage;
} u;
};
typedef struct VisualPluginMessageInfo VisualPluginMessageInfo;
#if PRAGMA_STRUCT_ALIGN
#pragma options align=reset
#elif PRAGMA_STRUCT_PACKPUSH
#pragma pack(pop)
#elif PRAGMA_STRUCT_PACK
#pragma pack()
#endif
#ifdef __cplusplus
}
#endif
#endif /* __ITUNESVISUALAPI__ */
//
// File: iTunesVisualAPI.h
//
// Abstract: part of iTunes Visual SDK
//
// Version: 2.0
//
// Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Inc. ( "Apple" )
// in consideration of your agreement to the following terms, and your use,
// installation, modification or redistribution of this Apple software
// constitutes acceptance of these terms. If you do not agree with these
// terms, please do not use, install, modify or redistribute this Apple
// software.
//
// In consideration of your agreement to abide by the following terms, and
// subject to these terms, Apple grants you a personal, non - exclusive
// license, under Apple's copyrights in this original Apple software ( the
// "Apple Software" ), to use, reproduce, modify and redistribute the Apple
// Software, with or without modifications, in source and / or binary forms;
// provided that if you redistribute the Apple Software in its entirety and
// without modifications, you must retain this notice and the following text
// and disclaimers in all such redistributions of the Apple Software. Neither
// the name, trademarks, service marks or logos of Apple Inc. may be used to
// endorse or promote products derived from the Apple Software without specific
// prior written permission from Apple. Except as expressly stated in this
// notice, no other rights or licenses, express or implied, are granted by
// Apple herein, including but not limited to any patent rights that may be
// infringed by your derivative works or by other works in which the Apple
// Software may be incorporated.
//
// The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
// WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
// WARRANTIES OF NON - INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION
// ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
//
// IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
// CONSEQUENTIAL DAMAGES ( INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION ) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION
// AND / OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER
// UNDER THEORY OF CONTRACT, TORT ( INCLUDING NEGLIGENCE ), STRICT LIABILITY OR
// OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Copyright © 2000-2011 Apple Inc. All Rights Reserved.
//
#ifndef ITUNESVISUALAPI_H_
#define ITUNESVISUALAPI_H_
#include "iTunesAPI.h"
#if PRAGMA_ONCE
#pragma once
#endif
#ifdef __cplusplus
extern "C" {
#endif
#if PRAGMA_STRUCT_ALIGN
#pragma options align=power
#elif PRAGMA_STRUCT_PACKPUSH
#pragma pack(push, 4)
#elif PRAGMA_STRUCT_PACK
#pragma pack(4)
#endif
enum {
kCurrentITStreamInfoVersion = 1
};
enum {
kITVisualPluginMajorMessageVersion = 10,
kITVisualPluginMinorMessageVersion = 7
};
enum {
/* VisualPlugin messages */
kVisualPluginInitMessage = 'init',
kVisualPluginCleanupMessage = 'clr ',
kVisualPluginIdleMessage = 'null',
kVisualPluginConfigureMessage = 'cnfg', /* Configure the plugin. */
kVisualPluginEnableMessage = 'von ', /* Enable the plugin and make it available to the user (automatic). */
kVisualPluginDisableMessage = 'voff', /* Disable the plugin. */
kVisualPluginActivateMessage = 'Vact', /* Visualizer is being shown on screen (allocate large memory here) */
kVisualPluginWindowChangedMessage = 'Vmov', /* The visualizer context was moved to a new window. A draw message will be sent immediately. */
kVisualPluginDeactivateMessage = 'Vdct', /* Visualizer is being removed from the screen (deallocate large memory here) */
kVisualPluginPulseMessage = 'Vpls', /* Sent at the rate requested during plugin registration. Contains new data if currently playing audio. */
kVisualPluginDrawMessage = 'Vdrw', /* Draw a new frame. Sent when the OS decides to repaint the backing view. */
kVisualPluginFrameChangedMessage = 'Vfrm', /* The visualizer area resized. A draw message will be sent immediately. */
kVisualPluginPlayMessage = 'Vply', /* Starting playback. */
kVisualPluginChangeTrackMessage = 'Ctrk', /* Current track changed or info about the current track has changed. */
kVisualPluginSetPositionMessage = 'setp', /* Setting the position of the currently playing track. */
kVisualPluginStopMessage = 'vstp', /* Stopping playback. */
kVisualPluginCoverArtMessage = 'Vart', /* Delivers the current track artwork as requested by the plugin. Plugin must retain/copy it if it wants to keep it. */
kVisualPluginDisplayChangedMessage = 'dchn' /* Something about display state changed. */
};
/*
VisualPlugin messages
*/
enum {
kVisualMaxDataChannels = 2,
kVisualNumWaveformEntries = 512,
kVisualNumSpectrumEntries = 512
};
enum {
/* CoverArt format types */
kVisualCoverArtFormatJPEG = 13,
kVisualCoverArtFormatPNG = 14,
kVisualCoverArtFormatBMP = 27
};
enum {
/* Activate options */
kWindowIsFullScreen = (1u << 0)
};
struct RenderVisualData {
UInt8 numWaveformChannels;
UInt8 waveformData[kVisualMaxDataChannels][kVisualNumWaveformEntries];
UInt8 numSpectrumChannels;
UInt8 spectrumData[kVisualMaxDataChannels][kVisualNumSpectrumEntries];
};
typedef struct RenderVisualData RenderVisualData;
struct VisualPluginInitMessage {
UInt32 messageMajorVersion; /* Input */
UInt32 messageMinorVersion; /* Input */
NumVersion appVersion; /* Input */
void * appCookie; /* Input */
ITAppProcPtr appProc; /* Input */
OptionBits unused; /* N/A */
void * refCon; /* Output */
};
typedef struct VisualPluginInitMessage VisualPluginInitMessage;
struct VisualPluginActivateMessage {
VISUAL_PLATFORM_VIEW view; /* Input - plugin should draw in entire bounds */
OptionBits options; /* Input */
};
typedef struct VisualPluginActivateMessage VisualPluginActivateMessage;
struct VisualPluginWindowChangedMessage {
OptionBits options; /* Input */
};
typedef struct VisualPluginWindowChangedMessage VisualPluginWindowChangedMessage;
struct VisualPluginPulseMessage {
RenderVisualData * renderData; /* Input */
UInt32 timeStampID; /* Input */
UInt32 currentPositionInMS; /* Input */
UInt32 newPulseRateInHz; /* Input/Output - contains current rate on input, modify it to get a new rate. */
};
typedef struct VisualPluginPulseMessage VisualPluginPulseMessage;
struct VisualPluginPlayMessage {
ITTrackInfo * trackInfo; /* Input */
ITStreamInfo * streamInfo; /* Input */
AudioStreamBasicDescription audioFormat; /* Input */
UInt32 bitRate; /* Input */
SInt32 volume; /* Input */
};
typedef struct VisualPluginPlayMessage VisualPluginPlayMessage;
struct VisualPluginChangeTrackMessage {
ITTrackInfo * trackInfo; /* Input */
ITStreamInfo * streamInfo; /* Input */
};
typedef struct VisualPluginChangeTrackMessage VisualPluginChangeTrackMessage;
struct VisualPluginCoverArtMessage {
VISUAL_PLATFORM_DATA coverArt; /* input - client must retain (mac) or copy (windows) the data if they want to keep it after this message completes.
- note that coverArt will be NULL if the current track has no artwork */
UInt32 coverArtSize; /* input - size of the coverArt in bytes */
UInt32 coverArtFormat; /* input - format of cover art */
};
typedef struct VisualPluginCoverArtMessage VisualPluginCoverArtMessage;
struct VisualPluginSetPositionMessage {
UInt32 positionTimeInMS; /* Input */
};
typedef struct VisualPluginSetPositionMessage VisualPluginSetPositionMessage;
enum {
kVisualDisplayDepthChanged = 1 << 0, /* the display's depth has changed */
kVisualDisplayRectChanged = 1 << 1, /* the display's location changed */
kVisualWindowMoved = 1 << 2, /* the window has moved location */
kVisualDisplayConfigChanged = 1 << 3, /* something else about the display changed */
};
struct VisualPluginDisplayChangedMessage {
UInt32 flags; /* Input */
};
typedef struct VisualPluginDisplayChangedMessage VisualPluginDisplayChangedMessage;
struct VisualPluginMessageInfo {
union {
VisualPluginInitMessage initMessage;
VisualPluginActivateMessage activateMessage;
VisualPluginWindowChangedMessage windowChangedMessage;
VisualPluginPulseMessage pulseMessage;
VisualPluginPlayMessage playMessage;
VisualPluginChangeTrackMessage changeTrackMessage;
VisualPluginSetPositionMessage setPositionMessage;
VisualPluginCoverArtMessage coverArtMessage;
VisualPluginDisplayChangedMessage displayChangedMessage;
} u;
};
typedef struct VisualPluginMessageInfo VisualPluginMessageInfo;
#if PRAGMA_STRUCT_ALIGN
#pragma options align=reset
#elif PRAGMA_STRUCT_PACKPUSH
#pragma pack(pop)
#elif PRAGMA_STRUCT_PACK
#pragma pack()
#endif
#ifdef __cplusplus
}
#endif
#endif /* ITUNESVISUALAPI_H_ */