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

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