The R Project SVN R

Rev

Rev 12778 | Rev 15609 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 12778 Rev 13792
Line 33... Line 33...
33
	Copyright © 1993-1998 Marco Piovanelli
33
	Copyright © 1993-1998 Marco Piovanelli
34
	All Rights Reserved
34
	All Rights Reserved
35
 
35
 
36
	C port by John C. Daub
36
	C port by John C. Daub
37
*/
37
*/
-
 
38
#include <Carbon.h>
-
 
39
 
-
 
40
#include <AppleEvents.h>
-
 
41
 
38
 
42
 
39
#ifndef __AEOBJECTS__
43
#ifndef __AEOBJECTS__
40
#include <AEObjects.h>
44
#include <AEObjects.h>
41
#endif
45
#endif
42
 
46
 
Line 63... Line 67...
63
 
67
 
64
 
68
 
65
OSStatus GetAEDescDataAsHandle ( const AEDesc * inDesc, Handle * outData )
69
OSStatus GetAEDescDataAsHandle ( const AEDesc * inDesc, Handle * outData )
66
{
70
{
67
	Size		dataSize ;
71
	Size		dataSize ;
68
	Handle		dataHandle ;
72
	Handle		dataHandle =NULL;
69
	OSStatus	err ;
73
	OSStatus	err ;
70
 
74
 
71
	* outData = nil ;
75
	* outData = nil ;
72
 
76
 
73
	//	do nothing if inDesc is a null descriptor
77
	//	do nothing if inDesc is a null descriptor
Line 370... Line 374...
370
OSStatus InstallCoreHandlers(void)
374
OSStatus InstallCoreHandlers(void)
371
{
375
{
372
	OSStatus err;
376
	OSStatus err;
373
 
377
 
374
	if ((err = AEInstallEventHandler(kAECoreSuite, kAEGetData,
378
	if ((err = AEInstallEventHandler(kAECoreSuite, kAEGetData,
375
			NewAEEventHandlerProc(HandleGetData), 0L, false)) != noErr)
379
			NewAEEventHandlerUPP(HandleGetData), 0L, false)) != noErr)
376
	{
380
	{
377
		return err;
381
		return err;
378
	}
382
	}
379
 
383
 
380
	if ((err = AEInstallEventHandler(kAECoreSuite, kAESetData,
384
	if ((err = AEInstallEventHandler(kAECoreSuite, kAESetData,
381
			NewAEEventHandlerProc(HandleSetData), 0L, false)) != noErr)
385
			NewAEEventHandlerUPP(HandleSetData), 0L, false)) != noErr)
382
	{
386
	{
383
		return err;
387
		return err;
384
	}
388
	}
385
 
389
 
386
	return noErr;
390
	return noErr;
387
}
391
}
388
 
392
 
-
 
393
OSStatus CreatePSNBasedAppleEvent
-
 
394
	(
-
 
395
		const ProcessSerialNumber *		inTargetPSN,
-
 
396
		AEEventClass					inEventClass,
-
 
397
		AEEventID						inEventID,
-
 
398
		AppleEvent *					outAE
-
 
399
	)
-
 
400
{
-
 
401
	AEAddressDesc	targetAddress ;
-
 
402
	OSStatus		err ;
-
 
403
 
-
 
404
	InitDesc ( outAE ) ;
-
 
405
	InitDesc ( & targetAddress ) ;
-
 
406
 
-
 
407
	//	create an address descriptor for the target application based on the PSN
-
 
408
	if ( ( err = AECreateDesc ( typeProcessSerialNumber, inTargetPSN,
-
 
409
		sizeof ( * inTargetPSN ), & targetAddress ) ) != noErr )
-
 
410
	{
-
 
411
		goto cleanup ;
-
 
412
	}
-
 
413
 
-
 
414
	//	create the Apple event
-
 
415
	if ( ( err = AECreateAppleEvent ( inEventClass, inEventID, & targetAddress,
-
 
416
		kAutoGenerateReturnID, kAnyTransactionID, outAE ) ) != noErr )
-
 
417
	{
-
 
418
		goto cleanup ;
-
 
419
	}
-
 
420
 
-
 
421
	//	clear result code
-
 
422
	err = noErr ;
-
 
423
 
-
 
424
cleanup :
-
 
425
	AEDisposeDesc ( & targetAddress ) ;
-
 
426
 
-
 
427
	//	return result code
-
 
428
	return err ;
-
 
429
}
-
 
430
 
-
 
431
OSStatus CreateObjectSpecifier
-
 
432
	(
-
 
433
		const AEDesc *		inContainerDesc,
-
 
434
		DescType			inDesiredClass,
-
 
435
		AEKeyword			inKeyForm,
-
 
436
		const AEDesc *		inKeyData,
-
 
437
		AEDesc *			outObjectSpecifier
-
 
438
	)
-
 
439
{
-
 
440
	AEDesc			recordDesc ;
-
 
441
	OSStatus		err ;
-
 
442
 
-
 
443
	InitDesc ( & recordDesc ) ;
-
 
444
 
-
 
445
	//	create a record
-
 
446
	if ( ( err = AECreateList ( nil, 0, true, & recordDesc ) ) != noErr )
-
 
447
	{
-
 
448
		goto cleanup ;
-
 
449
	}
-
 
450
 
-
 
451
	//	add container field
-
 
452
	if ( ( err = AEPutParamDesc ( & recordDesc, keyAEContainer, inContainerDesc ) ) != noErr )
-
 
453
	{
-
 
454
		goto cleanup ;
-
 
455
	}
-
 
456
 
-
 
457
	//	add desired class field
-
 
458
	if ( ( err = AEPutParamPtr ( & recordDesc, keyAEDesiredClass, typeType,
-
 
459
		& inDesiredClass, sizeof ( inDesiredClass ) ) ) != noErr )
-
 
460
	{
-
 
461
		goto cleanup ;
-
 
462
	}
-
 
463
 
-
 
464
	//	add key form field
-
 
465
	if ( ( err = AEPutParamPtr ( & recordDesc, keyAEKeyForm, typeEnumerated,
-
 
466
		& inKeyForm, sizeof ( inKeyForm ) ) ) != noErr )
-
 
467
	{
-
 
468
		goto cleanup ;
-
 
469
	}
-
 
470
 
-
 
471
	//	add key data field
-
 
472
	if ( ( err = AEPutParamDesc ( & recordDesc, keyAEKeyData, inKeyData ) ) != noErr )
-
 
473
	{
-
 
474
		goto cleanup ;
-
 
475
	}
-
 
476
 
-
 
477
	//	coerce the AE record to typeObjectSpecifier
-
 
478
	if ( ( err = AECoerceDesc ( & recordDesc, typeObjectSpecifier, outObjectSpecifier ) ) != noErr )
-
 
479
	{
-
 
480
		goto cleanup ;
-
 
481
	}
-
 
482
 
-
 
483
	//	clear result code
-
 
484
	err = noErr ;
-
 
485
 
-
 
486
cleanup :
-
 
487
	AEDisposeDesc ( & recordDesc ) ;
-
 
488
 
-
 
489
	//	return result code
-
 
490
	return err ;
-
 
491
}
-
 
492
 
-
 
493
OSStatus CreatePropertySpecifier
-
 
494
	(
-
 
495
		const AEDesc *		inContainerSpec,
-
 
496
		AEKeyword			inPropertyTag,
-
 
497
		AEDesc *			outPropertySpecifier
-
 
498
	)
-
 
499
{
-
 
500
	AEDesc			propertyDesc ;
-
 
501
	OSStatus		err ;
-
 
502
 
-
 
503
	InitDesc ( & propertyDesc ) ;
-
 
504
 
-
 
505
	//	create property descriptor
-
 
506
	if ( ( err = AECreateDesc ( typeType, & inPropertyTag, sizeof ( inPropertyTag ), & propertyDesc ) ) != noErr )
-
 
507
	{
-
 
508
		goto cleanup ;
-
 
509
	}
-
 
510
 
-
 
511
	//	create object specifier
-
 
512
	if ( ( err = CreateObjectSpecifier ( inContainerSpec, cProperty,
-
 
513
		formPropertyID, & propertyDesc, outPropertySpecifier ) ) != noErr )
-
 
514
	{
-
 
515
		goto cleanup ;
-
 
516
	}
-
 
517
 
-
 
518
	//	clear result code
-
 
519
	err = noErr ;
-
 
520
 
-
 
521
cleanup :
-
 
522
	AEDisposeDesc ( & propertyDesc ) ;
-
 
523
 
-
 
524
	//	return result code
-
 
525
	return err ;
-
 
526
}
-
 
527
 
-
 
528
OSStatus CreateFinderObjectSpecifier
-
 
529
	(
-
 
530
		const FSSpec *		inThing,
-
 
531
		AEDesc *			outThingSpec
-
 
532
	)
-
 
533
{
-
 
534
	Handle			alias = nil ;
-
 
535
	AEDesc			nullDesc ;
-
 
536
	AEDesc			aliasDesc ;
-
 
537
	OSStatus		err ;
-
 
538
 
-
 
539
	InitDesc ( outThingSpec ) ;
-
 
540
	InitDesc ( & nullDesc ) ;
-
 
541
	InitDesc ( & aliasDesc ) ;
-
 
542
 
-
 
543
	// make an alias for the given Finder object
-
 
544
	if ( ( err = NewAliasMinimal ( inThing, ( AliasHandle * ) & alias ) ) != noErr )
-
 
545
	{
-
 
546
		goto cleanup ;
-
 
547
	}
-
 
548
 
-
 
549
	//	create an alias descriptor
-
 
550
	HLock ( alias ) ;
-
 
551
	err = AECreateDesc ( typeAlias, * alias, GetHandleSize ( alias ), & aliasDesc ) ;
-
 
552
	HUnlock ( alias ) ;
-
 
553
	if ( err != noErr )
-
 
554
	{
-
 
555
		goto cleanup ;
-
 
556
	}
-
 
557
 
-
 
558
	//	make an object specifier for the thing
-
 
559
	if ( ( err = CreateObjectSpecifier ( & nullDesc, typeWildCard, formAlias, & aliasDesc, outThingSpec ) ) != noErr )
-
 
560
	{
-
 
561
		goto cleanup ;
-
 
562
	}
-
 
563
 
-
 
564
	// clear result code
-
 
565
	err = noErr ;
-
 
566
 
-
 
567
cleanup :
-
 
568
	ForgetHandle ( & alias ) ;
-
 
569
	AEDisposeDesc ( & aliasDesc ) ;
-
 
570
 
-
 
571
	return err ;
-
 
572
}
-
 
573
 
-
 
574
OSStatus SendGetDataEvent
-
 
575
	(
-
 
576
		const ProcessSerialNumber *		inTargetPSN,
-
 
577
		const AEDesc *					inObjectSpec,
-
 
578
		DescType						inRequestedType,
-
 
579
		AEDesc *						outResult
-
 
580
	)
-
 
581
{
-
 
582
	AppleEvent		ae ;		// the "get data" event
-
 
583
	AppleEvent		reply ;		// the reply event
-
 
584
	OSStatus		err ;
-
 
585
 
-
 
586
	InitDesc ( & ae ) ;
-
 
587
	InitDesc ( & reply ) ;
-
 
588
 
-
 
589
	//	create a "get data" Apple event for the specified process
-
 
590
	if ( ( err = CreatePSNBasedAppleEvent ( inTargetPSN, kAECoreSuite, kAEGetData, & ae ) ) != noErr )
-
 
591
	{
-
 
592
		goto cleanup ;
-
 
593
	}
-
 
594
 
-
 
595
	//	put the given specifier into the direct parameter of the event
-
 
596
	if ( ( err = AEPutParamDesc ( & ae, keyDirectObject, inObjectSpec ) ) != noErr )
-
 
597
	{
-
 
598
		goto cleanup ;
-
 
599
	}
-
 
600
 
-
 
601
	//	add the optional keyAERequestedType parameter to the event (unless we don't care)
-
 
602
	if ( inRequestedType != typeWildCard )
-
 
603
	{
-
 
604
		if ( ( err = AEPutParamPtr ( & ae, keyAERequestedType, typeType, & inRequestedType, sizeof ( inRequestedType ) ) ) != noErr )
-
 
605
		{
-
 
606
			goto cleanup ;
-
 
607
		}
-
 
608
	}
-
 
609
 
-
 
610
	//	send the event and wait for the reply
-
 
611
	if ( ( err = AESend ( & ae, & reply, kAEWaitReply + kAENeverInteract, kAENormalPriority, kAEDefaultTimeout, nil, nil ) ) != noErr )
-
 
612
	{
-
 
613
		goto cleanup ;
-
 
614
	}
-
 
615
 
-
 
616
	// extract direct parameter from the reply
-
 
617
	if ( ( err = AEGetParamDesc ( & reply, keyDirectObject, inRequestedType, outResult ) ) != noErr )
-
 
618
	{
-
 
619
		goto cleanup ;
-
 
620
	}
-
 
621
 
-
 
622
	// clear result code
-
 
623
	err = noErr ;
-
 
624
 
-
 
625
cleanup:
-
 
626
	AEDisposeDesc ( & ae ) ;
-
 
627
	AEDisposeDesc ( & reply ) ;
-
 
628
 
-
 
629
	return err ;
-
 
630
}
-
 
631
 
-
 
632
 
-
 
633
OSStatus GetFileRect
-
 
634
	(
-
 
635
		const FSSpec *	inThing,
-
 
636
		Rect *			outFileRect
-
 
637
	)
-
 
638
{
-
 
639
	ProcessSerialNumber		finderPSN ;			// the Finder's process serial number
-
 
640
	AEDesc					thingSpec ;			// specifier for inThing
-
 
641
	AEDesc					containerSpec ;		// specifier for "container of inThing"
-
 
642
	AEDesc					windowSpec ;		// specifier for "window of container of inThing"
-
 
643
	AEDesc					windowBoundsSpec ;	// specifier for "bounds of window of container of inThing"
-
 
644
	AEDesc					iconBoundsSpec ;	// specifier for "bounds of inThing"
-
 
645
	AEDesc					result ;
-
 
646
	Rect					windowBounds ;
-
 
647
	SInt16					deskVRefNum ;
-
 
648
	SInt32					deskDirID ;
-
 
649
	OSStatus				err ;
-
 
650
 
-
 
651
	InitDesc ( & thingSpec ) ;
-
 
652
	InitDesc ( & containerSpec ) ;
-
 
653
	InitDesc ( & windowSpec ) ;
-
 
654
	InitDesc ( & windowBoundsSpec ) ;
-
 
655
	InitDesc ( & iconBoundsSpec )  ;
-
 
656
	InitDesc ( & result ) ;
-
 
657
 
-
 
658
	//	get the Finder's process serial number
-
 
659
	if ( ( err = FindProcess ( FOUR_CHAR_CODE ( 'FNDR' ), FOUR_CHAR_CODE ( 'MACS' ), & finderPSN ) ) != noErr )
-
 
660
	{
-
 
661
	}
-
 
662
 
-
 
663
	//	make an object specifier for the given Finder object
-
 
664
	if ( ( err = CreateFinderObjectSpecifier ( inThing, & thingSpec ) ) != noErr )
-
 
665
	{
-
 
666
		goto cleanup ;
-
 
667
	}
-
 
668
 
-
 
669
	//	make an object specifier for "container of" object
-
 
670
	if ( ( err = CreatePropertySpecifier ( & thingSpec, pContainer, & containerSpec ) ) != noErr )
-
 
671
	{
-
 
672
		goto cleanup ;
-
 
673
	}
-
 
674
 
-
 
675
	//	make an object specifier for "window of container of" object
-
 
676
	if ( ( err = CreatePropertySpecifier ( & containerSpec, pWindow, & windowSpec ) ) != noErr )
-
 
677
	{
-
 
678
		goto cleanup ;
-
 
679
	}
-
 
680
 
-
 
681
	//	make an object specifier for "bounds of window of container of" object
-
 
682
	if ( ( err = CreatePropertySpecifier ( & windowSpec, pBounds, & windowBoundsSpec ) ) != noErr )
-
 
683
	{
-
 
684
		goto cleanup ;
-
 
685
	}
-
 
686
 
-
 
687
	//	get bounds of object's enclosing window, in global coordinates
-
 
688
	if ( ( err = SendGetDataEvent ( & finderPSN, & windowBoundsSpec, typeQDRectangle, & result ) ) != noErr )
-
 
689
	{
-
 
690
		goto cleanup ;
-
 
691
	}
-
 
692
	if ( ( err = AEGetDescData ( & result, & windowBounds, sizeof ( windowBounds ) ) ) != noErr )
-
 
693
	{
-
 
694
		goto cleanup ;
-
 
695
	}
-
 
696
	AEDisposeDesc ( & result ) ;
-
 
697
 
-
 
698
	//	make an object specifier for "bounds of" object
-
 
699
	if ( ( err = CreatePropertySpecifier ( & thingSpec, pBounds, & iconBoundsSpec ) ) != noErr )
-
 
700
	{
-
 
701
		goto cleanup ;
-
 
702
	}
-
 
703
 
-
 
704
	// get bounds of object, relative to the enclosing window
-
 
705
	if ( ( err = SendGetDataEvent ( & finderPSN, & iconBoundsSpec, typeQDRectangle, & result ) ) != noErr )
-
 
706
	{
-
 
707
		goto cleanup ;
-
 
708
	}
-
 
709
	if ( ( err = AEGetDescData ( & result, outFileRect, sizeof ( * outFileRect ) ) ) != noErr )
-
 
710
	{
-
 
711
		goto cleanup ;
-
 
712
	}
-
 
713
	AEDisposeDesc ( & result ) ;
-
 
714
 
-
 
715
	// calculate object's rectangle, in global coordinates
-
 
716
	OffsetRect ( outFileRect, windowBounds . left, windowBounds . top ) ;
-
 
717
 
-
 
718
	// SPECIAL CASE: check if the object is on the desktop
-
 
719
	if ( ( err = FindFolder ( inThing -> vRefNum, kDesktopFolderType, kDontCreateFolder, & deskVRefNum, & deskDirID ) ) != noErr )
-
 
720
	{
-
 
721
		goto cleanup ;
-
 
722
	}
-
 
723
 
-
 
724
	// if the object is on the desktop, the rectangle returned by the Finder
-
 
725
	// is 20 pixels below the actual icon
-
 
726
	if ( inThing -> parID == deskDirID )
-
 
727
	{
-
 
728
		OffsetRect ( outFileRect, 0, -20 ) ;
-
 
729
	}
-
 
730
 
-
 
731
	// clear result code
-
 
732
	err = noErr ;
-
 
733
 
-
 
734
cleanup :
-
 
735
	AEDisposeDesc ( & thingSpec ) ;
-
 
736
	AEDisposeDesc ( & containerSpec ) ;
-
 
737
	AEDisposeDesc ( & windowSpec ) ;
-
 
738
	AEDisposeDesc ( & windowBoundsSpec ) ;
-
 
739
	AEDisposeDesc ( & iconBoundsSpec ) ;
-
 
740
	AEDisposeDesc ( & result ) ;
-
 
741
 
-
 
742
	return err ;
-
 
743
}
389
 
744
 
390
 
745