PageRenderTime 66ms CodeModel.GetById 14ms app.highlight 44ms RepoModel.GetById 1ms app.codeStats 0ms

/xbmc/visualizations/Goom/goom2k4-0/mac/iTunes/iGoom.c

http://github.com/xbmc/xbmc
C | 896 lines | 684 code | 131 blank | 81 comment | 93 complexity | cb30ab81f0e9b35f02fe7affbc2bdade MD5 | raw file
  1//	includes
  2#include <stdio.h>
  3#include "iTunesVisualAPI.h"
  4#include "iTunesAPI.h"
  5#include "src/goom.h"
  6#include <CoreFoundation/CFBundle.h>
  7#include <Carbon/Carbon.h>
  8
  9//*****************************************************
 10#include <stdlib.h>
 11#include <string.h>
 12//*****************************************************
 13
 14CFStringRef CFBundleIdentifier;
 15
 16extern void ppc_doubling(unsigned int,UInt32 *,UInt32 *,UInt32 *,UInt32,UInt32);
 17
 18//	typedef's, struct's, enum's, etc.
 19#define kTVisualPluginName		"\piGoom"
 20#define	kTVisualPluginCreator		'gyom'
 21#define	kTVisualPluginMajorVersion	2
 22#define	kTVisualPluginMinorVersion	4
 23#define	kTVisualPluginReleaseStage	betaStage
 24#define	kTVisualPluginNonFinalRelease	1
 25
 26#define VERSION "2k4"
 27
 28#define kPixelDoublingPrefName		"PixelDoubling"
 29#define kShowFPSPrefName		    "ShowFPS"
 30#define kSensitivityPrefName		"Sensitivity"
 31#define kShowAboutWhenIdlePrefName	"ShowAboutWhenIdle"
 32
 33//#define Timers
 34
 35enum
 36{
 37    kOKSettingID = 1,
 38    kPixelDoublingSettingID = 2,
 39    kFrameRateSettingID = 3,
 40    kSensitivitySettingID = 4,
 41    kShowAboutWhenIdleSettingID = 5
 42};
 43
 44typedef struct VisualPluginData {
 45    void *			appCookie;
 46    ITAppProcPtr		appProc;
 47    ITFileSpec			pluginFileSpec;
 48
 49    CGrafPtr			destPort;
 50    Rect			destRect;
 51    OptionBits			destOptions;
 52    UInt32			destBitDepth;
 53
 54    ITTrackInfo			trackInfo;
 55    ITStreamInfo		streamInfo;
 56
 57    Boolean			playing;
 58
 59    //	Plugin-specific data
 60    GWorldPtr			offscreen;
 61    signed short 		data[2][512];
 62} VisualPluginData;
 63
 64
 65//	local (static) globals
 66//static unsigned int	useSpectrum = 0;
 67static CGrafPtr		gSavePort;
 68static GDHandle		gSaveDevice;
 69static unsigned int	changeRes = FALSE;
 70static unsigned int	oldx = 0, oldy = 0;
 71static signed int	forced = 0;
 72static unsigned int	showFPS = 0;
 73static int		showTexte = 0, showTitle = 1;
 74static Boolean		doublePixels = true;
 75static int		sensitivity = 160;
 76static int		ShowAboutWhenIdle = 0;
 77static AbsoluteTime	backUpTime;
 78static char *		aboutMessage;
 79
 80static PluginInfo  *    goomInfo;
 81
 82
 83//	exported function prototypes
 84extern OSStatus iTunesPluginMainMachO(OSType message,PluginMessageInfo *messageInfo,void *refCon);
 85
 86// Calcul de diff de temps
 87#ifdef Timers
 88static void HowLong(const char* text)
 89{
 90    AbsoluteTime absTime;
 91    Nanoseconds nanosec;
 92
 93    absTime = SubAbsoluteFromAbsolute(UpTime(), backUpTime);
 94    nanosec = AbsoluteToNanoseconds(absTime);
 95    fprintf(stderr,"Time for %s:  %f\n", text, (float) UnsignedWideToUInt64( nanosec ) / 1000000.0);
 96    backUpTime = UpTime();
 97}
 98#else
 99#define  HowLong(a)
100#endif
101
102// ProcessRenderData --> preprocessing des donnees en entr&#x17D;e
103static void ProcessRenderData(VisualPluginData *visualPluginData,const RenderVisualData *renderData)
104{
105    SInt16		index;
106    SInt32		channel;
107
108    if (renderData == nil)
109    {
110        bzero(&visualPluginData->data,sizeof(visualPluginData->data));
111        return;
112    }
113    else
114    {
115        for (channel = 0;channel < 2;channel++)
116        {
117            for (index = 0; index < 512; index++)
118                visualPluginData->data[channel][index] = (renderData->waveformData[channel][index]-127)*sensitivity;
119        }
120    }
121}
122
123// GetPortCopyBitsBitMap
124//
125static BitMap* GetPortCopyBitsBitMap(CGrafPtr port)
126{
127    BitMap*		destBMap;
128
129#if ACCESSOR_CALLS_ARE_FUNCTIONS
130    destBMap = (BitMap*)GetPortBitMapForCopyBits(port);
131#else
132#if OPAQUE_TOOLBOX_STRUCTS
133    PixMapHandle	pixMap;
134
135    pixMap		= GetPortPixMap(port);
136    destBMap	= (BitMap*) (*pixMap);
137#else
138    destBMap	= (BitMap*) &((GrafPtr)port)->portBits;
139#endif
140#endif
141    return destBMap;
142}
143
144//	RenderVisualPort
145/*	OK, This is pretty weird : if we are not in pixel doubling mode, 
146the goom internal buffer is copied on destPort via CopyBits().
147Now, if we are in pixel doubling mode : if we are full screen,
148the goom internal buffer is copied on another buffer with ppc_doubling()
149and then to destPort with CopyBits().*/
150
151char * Str255ToC(Str255 source)
152{
153    static char dst[255];
154    char * cur = dst, * src = (char*)source;
155    int i;
156    int size = *src;
157    if (source == NULL) return "";
158    src++;
159    for (i=0; i<size; i++)
160    {
161        *cur = *src;
162        switch (*cur)
163        {
164            case 'Ë' :
165                *cur = 'A';
166                break;
167            case '&#x2C6;' :
168            case '&#x2021;' :
169            case '&#x160;' :
170            case '&#x2030;' :
171                *cur = 'a';
172                break;
173            case '?' :
174            case 'é' :
175            case '&#x192;' :
176                *cur = 'E';
177                break;
178            case '&#x17D;' :
179            case '?' :
180            case '?' :
181            case '&#x2018;' :
182                *cur = 'e';
183                break;
184            case '&#x201C;' :
185            case '&#x2022;' :
186            case '&#x201D;' :
187            case '&#x2019;' :
188                *cur = 'i';
189                break;
190            case '&#x2013;' :
191                *cur = 'n';
192                break;
193            case '?' :
194                *cur = 'c';
195                break;
196            case '&#x2DC;' :
197            case '&#x2014;' :
198            case '&#x161;' :
199            case '&#x2122;' :
200                *cur = 'o';
201                break;
202            case '?' :
203            case '&#x153;' :
204            case '&#x17E;' :
205            case '&#x;' :
206                *cur = 'u';
207                break;
208            default : break;
209        }
210        src++;
211        cur++;
212    }
213    *cur = 0;
214    return dst;
215}
216
217static void RenderVisualPort(VisualPluginData *visualPluginData,CGrafPtr destPort,const Rect *destRect,Boolean onlyUpdate)
218{
219    BitMap*		srcBitMap;
220    BitMap*		dstBitMap;
221    unsigned int 	right, bottom;
222    Rect		srcRect= *destRect;
223    Rect		dstRect = srcRect;
224    int	fullscreen;
225    static GWorldPtr	offscreen;
226    PixMapHandle	pixMapHdl = GetGWorldPixMap(visualPluginData->offscreen);
227    Point pt = {0,0};
228    static float	fpssampler = 0;
229    static char textBuffer[15];
230    static char titleBuffer[255];
231    unsigned char * str, * str2;
232
233    AbsoluteTime absTime;
234    Nanoseconds nanosec;
235
236    LocalToGlobal(&pt);
237    fullscreen = (pt.v == 0);
238
239    if ((NULL == destPort) || (NULL == destRect) || (NULL == visualPluginData->offscreen)) return;
240
241    absTime = SubAbsoluteFromAbsolute(UpTime(), backUpTime);
242    nanosec = AbsoluteToNanoseconds(absTime);
243    fpssampler = 1000000000.0 / (float) UnsignedWideToUInt64( nanosec );
244    if (fpssampler>35) return;
245    backUpTime = UpTime();
246
247
248    GetGWorld(&gSavePort,&gSaveDevice);
249    SetGWorld(destPort,nil);
250
251    srcBitMap	= GetPortCopyBitsBitMap(visualPluginData->offscreen);
252    dstBitMap	= GetPortCopyBitsBitMap(destPort);
253
254    OffsetRect(&srcRect,-srcRect.left,-srcRect.top);
255    if (!pixMapHdl || !*pixMapHdl) return;
256
257    right = srcRect.right;
258    bottom = srcRect.bottom;
259    if ((right<2) || (bottom<2)) return;
260
261    // Update our offscreen pixmap
262    if ((changeRes) || (oldx != right) || (oldy != bottom))
263    {
264        if (doublePixels)
265            goom_set_resolution (goomInfo,right%2 + right/2,  bottom/2 + bottom%2);
266        else
267            goom_set_resolution (goomInfo,right, bottom);
268        oldx = right;
269        oldy = bottom;
270        changeRes = FALSE;
271    }
272
273    str2 = NULL;
274    if (showTitle == 0)
275    {
276        strcpy(titleBuffer, Str255ToC(visualPluginData->trackInfo.name));
277        str2 = titleBuffer;
278        str = " ";
279        showTexte = 10000;
280    }
281    else
282    {
283        if (ShowAboutWhenIdle)
284        {
285            switch (showTexte)
286            {
287                case 0:
288                    str2 = " ";
289                    sprintf(textBuffer,"The iGoom %s",VERSION);
290                    str = textBuffer;
291                    break;
292                case 500:
293                    str = "http://www.ios-software.com/";
294                    break;
295                case 1000 :
296                    str = aboutMessage;
297                    break;
298                default :
299                    str = NULL;
300                    break;
301            }
302        }
303        else
304        {
305            str = " ";
306        }
307    }
308    
309    if (doublePixels)
310    {
311        UInt32 rowBytes = (GetPixRowBytes(pixMapHdl))>>2;
312        register UInt32 *myX = (UInt32*) GetPixBaseAddr(pixMapHdl);
313        register UInt32 inc = 2*rowBytes - right - right%2;
314        register UInt32 *myx = (UInt32*)  goom_update (goomInfo,visualPluginData->data,forced,(showFPS > 0)?fpssampler:-1,str2,str);
315
316        ppc_doubling(right/2 + right%2, myx, myX, myX + rowBytes, bottom/2,inc*4);
317        srcBitMap = GetPortCopyBitsBitMap(visualPluginData->offscreen);
318        CopyBits(srcBitMap,dstBitMap,&srcRect,&dstRect,srcCopy,nil);
319    }
320    else
321    {
322        NewGWorldFromPtr(&offscreen, k32ARGBPixelFormat,&srcRect, NULL, NULL, 0, (Ptr) goom_update (goomInfo,visualPluginData->data,forced, (showFPS > 0)?fpssampler:-1, str2, str), right*4);
323        HowLong("Goom");
324        srcBitMap = GetPortCopyBitsBitMap(offscreen);
325        CopyBits(srcBitMap,dstBitMap,&srcRect,&dstRect,srcCopy,nil);
326        DisposeGWorld(offscreen);
327    }
328    showTexte++;
329    if (showTexte>10000) showTexte = 10000;
330    showTitle = 1;
331    if (forced>0) forced = -1;
332
333    SetGWorld(gSavePort,gSaveDevice);
334}
335
336
337/*	AllocateVisualData is where you should allocate any information that depends
338on the port or rect changing (like offscreen GWorlds). */
339static OSStatus AllocateVisualData(VisualPluginData *visualPluginData,CGrafPtr destPort,const Rect *destRect)
340{
341    OSStatus		status;
342    Rect			allocateRect;
343
344    (void) destPort;
345
346    GetGWorld(&gSavePort,&gSaveDevice);
347
348    allocateRect = *destRect;
349    OffsetRect(&allocateRect,-allocateRect.left,-allocateRect.top);
350
351    status = NewGWorld(&visualPluginData->offscreen,32,&allocateRect,nil,nil,useTempMem);
352    if (status == noErr)
353    {
354        PixMapHandle	pix = GetGWorldPixMap(visualPluginData->offscreen);
355        LockPixels(pix);
356
357        // Offscreen starts out black
358        SetGWorld(visualPluginData->offscreen,nil);
359        ForeColor(blackColor);
360        PaintRect(&allocateRect);
361    }
362    SetGWorld(gSavePort,gSaveDevice);
363
364    return status;
365}
366
367//	DeallocateVisualData is where you should deallocate the .
368static void DeallocateVisualData(VisualPluginData *visualPluginData)
369{
370    CFPreferencesAppSynchronize(CFBundleIdentifier);
371
372    if (visualPluginData->offscreen != nil)
373    {
374        DisposeGWorld(visualPluginData->offscreen);
375        visualPluginData->offscreen = nil;
376    }
377}
378
379// ChangeVisualPort
380static OSStatus ChangeVisualPort(VisualPluginData *visualPluginData,CGrafPtr destPort,const Rect *destRect)
381{
382    OSStatus		status;
383    Boolean			doAllocate;
384    Boolean			doDeallocate;
385
386    status = noErr;
387
388    doAllocate	= false;
389    doDeallocate	= false;
390
391    if (destPort != nil)
392    {
393        if (visualPluginData->destPort != nil)
394        {
395            if (false == EqualRect(destRect,&visualPluginData->destRect))
396            {
397                doDeallocate	= true;
398                doAllocate	= true;
399            }
400        }
401        else
402        {
403            doAllocate = true;
404        }
405    }
406    else
407    {
408        doDeallocate = true;
409    }
410
411    if (doDeallocate)
412        DeallocateVisualData(visualPluginData);
413
414    if (doAllocate)
415        status = AllocateVisualData(visualPluginData,destPort,destRect);
416
417    if (status != noErr)
418        destPort = nil;
419
420    visualPluginData->destPort = destPort;
421    if (destRect != nil)
422        visualPluginData->destRect = *destRect;
423
424    return status;
425}
426
427//	ResetRenderData
428static void ResetRenderData(VisualPluginData *visualPluginData)
429{
430    bzero(&visualPluginData->data,sizeof(visualPluginData->data));
431}
432
433//	settingsControlHandler
434pascal OSStatus settingsControlHandler(EventHandlerCallRef inRef,EventRef inEvent, void* userData)
435{
436    WindowRef wind=NULL;
437    ControlID controlID;
438    ControlRef control=NULL;
439    //get control hit by event
440    GetEventParameter(inEvent,kEventParamDirectObject,typeControlRef,NULL,sizeof(ControlRef),NULL,&control);
441    wind=GetControlOwner(control);
442    GetControlID(control,&controlID);
443    switch(controlID.id){
444
445        case kShowAboutWhenIdleSettingID:
446            ShowAboutWhenIdle = GetControlValue(control);
447            CFPreferencesSetAppValue (CFSTR(kShowAboutWhenIdlePrefName),ShowAboutWhenIdle?CFSTR("YES"):CFSTR("NO"),CFBundleIdentifier);
448            break;
449
450        case kPixelDoublingSettingID:
451            doublePixels = GetControlValue(control);
452            CFPreferencesSetAppValue (CFSTR(kPixelDoublingPrefName),doublePixels?CFSTR("YES"):CFSTR("NO"),CFBundleIdentifier);
453            changeRes = TRUE;
454            break;
455
456        case kFrameRateSettingID:
457            showFPS = GetControlValue( control );
458            CFPreferencesSetAppValue (CFSTR(kShowFPSPrefName),showFPS?CFSTR("YES"):CFSTR("NO"),CFBundleIdentifier);
459            break;
460
461        case kSensitivitySettingID:
462            sensitivity = GetControlValue( control );
463            {
464                CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &sensitivity);
465                CFPreferencesSetAppValue (CFSTR(kSensitivityPrefName), value, CFBundleIdentifier);
466                CFRelease(value);
467            }
468            break;
469
470        case kOKSettingID:
471            HideWindow(wind);
472            break;
473    }
474    return noErr;
475}
476
477//	VisualPluginHandler
478static OSStatus VisualPluginHandler(OSType message,VisualPluginMessageInfo *messageInfo,void *refCon)
479{
480    OSStatus		status;
481    VisualPluginData *	visualPluginData;
482
483    visualPluginData = (VisualPluginData*) refCon;
484
485    status = noErr;
486
487    switch (message)
488    {
489        //	Sent when the visual plugin is registered.  The plugin should do minimal
490        //	memory allocations here.  The resource fork of the plugin is still available.
491        case kVisualPluginInitMessage:
492        {
493            visualPluginData = (VisualPluginData*) NewPtrClear(sizeof(VisualPluginData));
494            if (visualPluginData == nil)
495            {
496                status = memFullErr;
497                break;
498            }
499            visualPluginData->appCookie = messageInfo->u.initMessage.appCookie;
500            visualPluginData->appProc   = messageInfo->u.initMessage.appProc;
501            // Remember the file spec of our plugin file.
502            // We need this so we can open our resource fork during
503            // the configuration message
504
505            status = PlayerGetPluginFileSpec(visualPluginData->appCookie, visualPluginData->appProc, &visualPluginData->pluginFileSpec);
506            messageInfo->u.initMessage.refCon	= (void*) visualPluginData;
507            goomInfo = goom_init(100,100);
508            
509            //fprintf(stderr,"Loc : %s\n", CFStringGetCStringPtr(CFCopyLocalizedStringFromTableInBundle(CFSTR("AboutString"), CFSTR("About"), CFBundleGetBundleWithIdentifier(CFBundleIdentifier), NULL),kCFStringEncodingMacRoman));
510
511            aboutMessage = (char*)CFStringGetCStringPtr(CFCopyLocalizedStringFromTableInBundle(CFSTR("AboutString"), CFSTR("About"), CFBundleGetBundleWithIdentifier(CFBundleIdentifier), NULL),kCFStringEncodingMacRoman);
512
513            break;
514        }
515
516            //	Sent when the visual plugin is unloaded
517        case kVisualPluginCleanupMessage:
518            if (visualPluginData != nil)
519                DisposePtr((Ptr)visualPluginData);
520
521            goom_close(goomInfo);
522            break;
523
524            //	Sent when the visual plugin is enabled.  iTunes currently enables all
525            //	loaded visual plugins.  The plugin should not do anything here.
526        case kVisualPluginEnableMessage:
527            if (true == visualPluginData->playing)
528            {
529                showTexte = 10000;
530                showTitle = 0;
531            }
532            else
533            {
534                showTexte = 0;
535                showTitle = 1;
536            }
537        case kVisualPluginDisableMessage:
538            break;
539
540            //	Sent if the plugin requests idle messages.  Do this by setting the kVisualWantsIdleMessages
541            //	option in the RegisterVisualMessage.options field.
542        case kVisualPluginIdleMessage:
543                RenderVisualPort(visualPluginData,visualPluginData->destPort,&visualPluginData->destRect,false);
544            break;
545
546            //	Sent if the plugin requests the ability for the user to configure it.  Do this by setting
547            //	the kVisualWantsConfigure option in the RegisterVisualMessage.options field.
548        case kVisualPluginConfigureMessage:
549        {
550            
551            // kOKSettingID = 1,
552             //kPixelDoublingSettingID = 2,
553             //kFrameRateSettingID = 3,
554             //kSensitivitySettingID = 4
555                        
556            static EventTypeSpec controlEvent={kEventClassControl,kEventControlHit};
557            static const ControlID kPixelDoublingSettingControlID={'cbox',kPixelDoublingSettingID};
558            static const ControlID kFrameRateSettingControlID={'cbox',kFrameRateSettingID};
559            static const ControlID kSensitivitySettingControlID={'slid',kSensitivitySettingID};
560            static const ControlID kShowAboutWhenIdleSettingControlID={'cbox',kShowAboutWhenIdleSettingID};
561            static WindowRef settingsDialog=NULL;
562            static ControlRef PixelDoublingCTRL=NULL;
563            static ControlRef FrameRateCTRL=NULL;
564            static ControlRef SensitivityCTRL=NULL;
565            static ControlRef ShowAboutWhenIdleCTRL=NULL;
566
567            if(settingsDialog==NULL){
568                IBNibRef 	nibRef;
569                CFBundleRef	iGoomPlugin;
570                //we have to find our bundle to load the nib inside of it
571                iGoomPlugin=CFBundleGetBundleWithIdentifier(CFBundleIdentifier);
572                CreateNibReferenceWithCFBundle(iGoomPlugin,CFSTR("SettingsDialog"), &nibRef);
573                CreateWindowFromNib(nibRef, CFSTR("PluginSettings"), &settingsDialog);
574                DisposeNibReference(nibRef);
575
576                      
577                //fprintf (stderr,"Picture @ %d\n", (PicHandle)GetPicture (12866));
578
579                InstallWindowEventHandler(settingsDialog,NewEventHandlerUPP(settingsControlHandler),
580                                          1,&controlEvent,0,NULL);
581                GetControlByID(settingsDialog,&kPixelDoublingSettingControlID,&PixelDoublingCTRL);
582                GetControlByID(settingsDialog,&kFrameRateSettingControlID,&FrameRateCTRL);
583                GetControlByID(settingsDialog,&kSensitivitySettingControlID,&SensitivityCTRL);
584                GetControlByID(settingsDialog,&kShowAboutWhenIdleSettingControlID,&ShowAboutWhenIdleCTRL);
585            }
586            SetControlValue(PixelDoublingCTRL,doublePixels);
587            SetControlValue(FrameRateCTRL,showFPS);
588            SetControlValue(SensitivityCTRL,sensitivity);
589            SetControlValue(ShowAboutWhenIdleCTRL,ShowAboutWhenIdle);
590
591            ShowWindow(settingsDialog);
592        }
593            break;
594
595            //	Sent when iTunes is going to show the visual plugin in a port.  At
596            //	this point,the plugin should allocate any large buffers it needs.
597        case kVisualPluginShowWindowMessage:
598            if (true == visualPluginData->playing)
599            {
600                showTexte = 10000;
601                showTitle = 0;
602            }
603            else
604            {
605                showTexte = 0;
606                showTitle = 1;
607            }
608            visualPluginData->destOptions = messageInfo->u.showWindowMessage.options;
609            status = ChangeVisualPort( visualPluginData, messageInfo->u.showWindowMessage.port,
610                                       &messageInfo->u.showWindowMessage.drawRect);
611            //FIXME setres here
612            break;
613            //	Sent when iTunes is no longer displayed.
614        case kVisualPluginHideWindowMessage:
615
616            (void) ChangeVisualPort(visualPluginData,nil,nil);
617
618            bzero(&visualPluginData->trackInfo,sizeof(visualPluginData->trackInfo));
619            bzero(&visualPluginData->streamInfo,sizeof(visualPluginData->streamInfo));
620            break;
621
622            //	Sent when iTunes needs to change the port or rectangle of the currently
623            //	displayed visual.
624        case kVisualPluginSetWindowMessage:
625            visualPluginData->destOptions = messageInfo->u.setWindowMessage.options;
626
627            status = ChangeVisualPort(	visualPluginData,
628                                       messageInfo->u.setWindowMessage.port,
629                                       &messageInfo->u.setWindowMessage.drawRect);
630            break;
631
632            //	Sent for the visual plugin to render a frame.
633        case kVisualPluginRenderMessage:
634            ProcessRenderData(visualPluginData,messageInfo->u.renderMessage.renderData);
635            RenderVisualPort(visualPluginData,visualPluginData->destPort,&visualPluginData->destRect,false);
636            break;
637
638            //	Sent in response to an update event.  The visual plugin should update
639            //	into its remembered port.  This will only be sent if the plugin has been
640            //	previously given a ShowWindow message.
641        case kVisualPluginUpdateMessage:
642            RenderVisualPort(visualPluginData,visualPluginData->destPort,&visualPluginData->destRect,true);
643            break;
644
645            //	Sent when the player starts.
646        case kVisualPluginPlayMessage:
647            if (messageInfo->u.playMessage.trackInfo != nil)
648                visualPluginData->trackInfo = *messageInfo->u.playMessage.trackInfo;
649            else
650                bzero(&visualPluginData->trackInfo,sizeof(visualPluginData->trackInfo));
651
652            if (messageInfo->u.playMessage.streamInfo != nil)
653                visualPluginData->streamInfo = *messageInfo->u.playMessage.streamInfo;
654            else
655                bzero(&visualPluginData->streamInfo,sizeof(visualPluginData->streamInfo));
656
657            visualPluginData->playing = true;
658            showTexte = 10000;
659            showTitle = 0;
660            break;
661
662            //	Sent when the player changes the current track information.  This
663            //	is used when the information about a track changes,or when the CD
664            //	moves onto the next track.  The visual plugin should update any displayed
665            //	information about the currently playing song.
666        case kVisualPluginChangeTrackMessage:
667            if (messageInfo->u.changeTrackMessage.trackInfo != nil)
668                visualPluginData->trackInfo = *messageInfo->u.changeTrackMessage.trackInfo;
669            else
670                bzero(&visualPluginData->trackInfo,sizeof(visualPluginData->trackInfo));
671
672            if (messageInfo->u.changeTrackMessage.streamInfo != nil)
673                visualPluginData->streamInfo = *messageInfo->u.changeTrackMessage.streamInfo;
674            else
675                bzero(&visualPluginData->streamInfo,sizeof(visualPluginData->streamInfo));
676            showTexte = 10000;
677            showTitle = 0;
678            break;
679
680            //	Sent when the player stops.
681        case kVisualPluginStopMessage:
682            visualPluginData->playing = false;
683            ResetRenderData(visualPluginData);
684            //RenderVisualPort(visualPluginData,visualPluginData->destPort,&visualPluginData->destRect,true);
685            showTexte = 0;
686            showTitle = 1;
687            break;
688
689            //	Sent when the player changes position.
690        case kVisualPluginSetPositionMessage:
691            break;
692
693            //	Sent when the player pauses.  iTunes does not currently use pause or unpause.
694            //	A pause in iTunes is handled by stopping and remembering the position.
695        case kVisualPluginPauseMessage:
696            visualPluginData->playing = false;
697            ResetRenderData(visualPluginData);
698            //RenderVisualPort(visualPluginData,visualPluginData->destPort,&visualPluginData->destRect,true);
699            break;
700
701            //	Sent when the player unpauses.  iTunes does not currently use pause or unpause.
702            //	A pause in iTunes is handled by stopping and remembering the position.
703        case kVisualPluginUnpauseMessage:
704            visualPluginData->playing = true;
705            break;
706
707            //	Sent to the plugin in response to a MacOS event.  The plugin should return noErr
708            //	for any event it handles completely,or an error (unimpErr) if iTunes should handle it.
709        case kVisualPluginEventMessage:
710        {
711            EventRecord* tEventPtr = messageInfo->u.eventMessage.event;
712            if ((tEventPtr->what == keyDown) || (tEventPtr->what == autoKey))
713            {    // charCodeMask,keyCodeMask;
714                char theChar = tEventPtr->message & charCodeMask;
715
716                switch (theChar) // Process keys here
717                {
718                    
719                    case	't':
720                    case	'T':
721                        ShowAboutWhenIdle = (ShowAboutWhenIdle==0)?1:0;
722                        CFPreferencesSetAppValue (CFSTR(kShowAboutWhenIdlePrefName),ShowAboutWhenIdle?CFSTR("YES"):CFSTR("NO"), CFBundleIdentifier);
723                        break;
724                    case	'q':
725                    case	'Q':
726                        doublePixels = (doublePixels==0)?1:0;
727                        CFPreferencesSetAppValue (CFSTR(kPixelDoublingPrefName),doublePixels?CFSTR("YES"):CFSTR("NO"), CFBundleIdentifier);
728                        changeRes = TRUE;
729                        break;
730                    case	'0':
731                        forced = (forced == 0) ? -1 : 0;
732                        break;
733                    case	'1':
734                    case	'2':
735                    case	'3':
736                    case	'4':
737                    case	'5':
738                    case	'6':
739                    case	'7':
740                    case	'8':
741                    case	'9':
742                        forced = theChar - '0';
743                        break;
744                    case	'f':
745                    case	'F':
746                        showFPS = (showFPS==0)?1:0;
747                        CFPreferencesSetAppValue (CFSTR(kShowFPSPrefName),showFPS?CFSTR("YES"):CFSTR("NO"),CFBundleIdentifier);
748                        break;
749                        
750                    case	'>':
751                        if (sensitivity <= 240) sensitivity += 10;
752                        {
753                            CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &sensitivity);
754                            CFPreferencesSetAppValue (CFSTR(kSensitivityPrefName), value, CFBundleIdentifier);
755                            CFRelease(value);
756                        }
757                            break;
758                    case	'<':
759                        if (sensitivity >= 80) sensitivity -= 10;
760                        {
761                            CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &sensitivity);
762                            CFPreferencesSetAppValue (CFSTR(kSensitivityPrefName), value, CFBundleIdentifier);
763                            CFRelease(value);
764                        }
765                            break;
766                        
767                    case	'\r':
768                    case	'\n':
769                        break;
770                    default:
771                        status = unimpErr;
772                        break;
773                }
774            }
775            else
776                status = unimpErr;
777        }
778            break;
779
780        default:
781            status = unimpErr;
782            break;
783    }
784    return status;
785}
786
787//	RegisterVisualPlugin
788static OSStatus RegisterVisualPlugin(PluginMessageInfo *messageInfo)
789{
790    OSStatus		status;
791    PlayerMessageInfo	playerMessageInfo;
792    Str255		pluginName = kTVisualPluginName;
793#ifdef Timers
794    backUpTime = UpTime();
795#endif
796
797    CFStringRef aString;
798    CFNumberRef aNumber;
799    CFComparisonResult result;
800
801    CFBundleIdentifier = CFSTR("com.ios.igoom");
802
803    // Read the preferences
804    aString = CFPreferencesCopyAppValue(CFSTR(kPixelDoublingPrefName),CFBundleIdentifier);
805    if (aString != NULL)
806    {
807        result = CFStringCompareWithOptions(aString, CFSTR("YES"), CFRangeMake(0,CFStringGetLength(aString)), kCFCompareCaseInsensitive);
808        if (result ==  kCFCompareEqualTo) {
809            doublePixels = true;
810        }
811        else doublePixels = false;
812    }
813
814    aString = CFPreferencesCopyAppValue(CFSTR(kShowFPSPrefName),CFBundleIdentifier);
815    if (aString != NULL)
816    {
817        result = CFStringCompareWithOptions(aString, CFSTR("YES"), CFRangeMake(0,CFStringGetLength(aString)), kCFCompareCaseInsensitive);
818        if (result ==  kCFCompareEqualTo) {
819            showFPS = true;
820        }
821        else showFPS = false;
822    }
823    
824    aString = CFPreferencesCopyAppValue(CFSTR(kShowAboutWhenIdlePrefName),CFBundleIdentifier);
825    if (aString != NULL)
826    {
827        result = CFStringCompareWithOptions(aString, CFSTR("YES"), CFRangeMake(0,CFStringGetLength(aString)), kCFCompareCaseInsensitive);
828        if (result ==  kCFCompareEqualTo) {
829            ShowAboutWhenIdle = true;
830        }
831        else ShowAboutWhenIdle = false;
832    }
833    
834    aNumber = CFPreferencesCopyAppValue(CFSTR(kSensitivityPrefName),CFBundleIdentifier);
835    if (aNumber != NULL)
836    {
837        CFNumberGetValue(aNumber,kCFNumberIntType,&sensitivity);
838    }
839    
840
841
842    
843    bzero(&playerMessageInfo.u.registerVisualPluginMessage,sizeof(playerMessageInfo.u.registerVisualPluginMessage));
844    BlockMoveData((Ptr)&pluginName[0],(Ptr)&playerMessageInfo.u.registerVisualPluginMessage.name[0],pluginName[0] + 1);
845
846    SetNumVersion(&playerMessageInfo.u.registerVisualPluginMessage.pluginVersion, kTVisualPluginMajorVersion, kTVisualPluginMinorVersion, kTVisualPluginReleaseStage, kTVisualPluginNonFinalRelease);
847
848    playerMessageInfo.u.registerVisualPluginMessage.options			= kVisualWantsIdleMessages | kVisualWantsConfigure;
849    playerMessageInfo.u.registerVisualPluginMessage.handler			= (VisualPluginProcPtr)VisualPluginHandler;
850    playerMessageInfo.u.registerVisualPluginMessage.registerRefCon		= 0;
851    playerMessageInfo.u.registerVisualPluginMessage.creator			= kTVisualPluginCreator;
852
853    playerMessageInfo.u.registerVisualPluginMessage.timeBetweenDataInMS	= 0xFFFFFFFF; // 16 milliseconds = 1 Tick, 0xFFFFFFFF = Often as possible.
854    playerMessageInfo.u.registerVisualPluginMessage.numWaveformChannels	= 2;
855    playerMessageInfo.u.registerVisualPluginMessage.numSpectrumChannels	= 0;
856
857    playerMessageInfo.u.registerVisualPluginMessage.minWidth		= 100;
858    playerMessageInfo.u.registerVisualPluginMessage.minHeight		= 100;
859    playerMessageInfo.u.registerVisualPluginMessage.maxWidth		= 2000;
860    playerMessageInfo.u.registerVisualPluginMessage.maxHeight		= 2000;
861    playerMessageInfo.u.registerVisualPluginMessage.minFullScreenBitDepth	= 32;
862    playerMessageInfo.u.registerVisualPluginMessage.maxFullScreenBitDepth	= 32;
863    playerMessageInfo.u.registerVisualPluginMessage.windowAlignmentInBytes	= 0;
864
865    status = PlayerRegisterVisualPlugin(messageInfo->u.initMessage.appCookie,messageInfo->u.initMessage.appProc,&playerMessageInfo);
866/*
867    Gestalt(gestaltPowerPCProcessorFeatures,&CPU);
868    if (1 & (CPU >> gestaltPowerPCHasVectorInstructions)) CPU_FLAVOUR = 1;
869    else CPU_FLAVOUR = 0;
870*/
871    
872    return status;
873}
874
875//	main entrypoint
876OSStatus iTunesPluginMainMachO(OSType message,PluginMessageInfo *messageInfo,void *refCon)
877{
878    OSStatus		status;
879
880    (void) refCon;
881
882    switch (message)
883    {
884        case kPluginInitMessage:
885            status = RegisterVisualPlugin(messageInfo);
886            break;
887        case kPluginCleanupMessage:
888            status = noErr;
889            break;
890        default:
891            status = unimpErr;
892            break;
893    }
894
895    return status;
896}