unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Carbon port: setting the creator code (patch)
@ 2005-06-24  9:05 David Reitter
  2005-07-09  3:04 ` Steven Tamm
  0 siblings, 1 reply; 9+ messages in thread
From: David Reitter @ 2005-06-24  9:05 UTC (permalink / raw)


[-- Attachment #1: Type: text/plain, Size: 640 bytes --]

I'm posting some code that introduces a function "mac-set-creator" in  
the Mac (Carbon) port. The function sets the creator code (metadata  
information) of a file to 'EMAx'. That enables LaunchServices to  
start up Emacs whenever the file is double-clicked.

In the Aquamacs distribution, I use it as follows:

(defun mac-set-creator-code-for-file ()
   (if (and aquamacs-set-creator-codes-after-writing-files
        buffer-file-name
        (fboundp 'mac-set-creator)
        )
       (mac-set-creator buffer-file-name)
     )
   )

(add-hook 'after-save-hook 'mac-set-creator-code-for-file)

This contains some free code from Apple.


[-- Attachment #2: mac-set-creator.patch --]
[-- Type: application/octet-stream, Size: 5339 bytes --]

Index: macfns.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/macfns.c,v
retrieving revision 1.61
diff -c -r1.61 macfns.c
*** macfns.c	23 Jun 2005 16:12:25 -0000	1.61
--- macfns.c	24 Jun 2005 08:51:24 -0000
***************
*** 4406,4411 ****
--- 4406,4570 ----
  {
  }
  #endif
+  
+ 
+ #ifdef MAC_OSX
+ 
+ 
+ /* The code for FSBumpDate and FSChangeCreator is taken from 
+    MoreFilesX.c (Apple Sample Code), authored by Jim Luther / Apple 
+    and released for free use. The code has been modified.
+ 
+    To do: test on MacOS.
+ */
+ 
+ OSErr
+ FSBumpDate(
+ 	const FSRef *ref)
+ {
+ 	OSStatus		result;
+ 	FSCatalogInfo	        catalogInfo;
+ 	UTCDateTime		oldDateTime;
+ #ifdef MAC_OSX
+ 	FSRef			parentRef;
+ 	Boolean			notifyParent;
+ #endif
+ 
+ #ifdef MAC_OSX
+ 	/* Get the node flags, the content modification date and time, and the parent ref */
+ 	result = FSGetCatalogInfo(ref, kFSCatInfoNodeFlags + kFSCatInfoContentMod, &catalogInfo, NULL, NULL, &parentRef);
+ 	require_noerr(result, FSGetCatalogInfo);
+ 	
+ 	/* Notify the parent if this is a file */
+ 	notifyParent = (0 == (catalogInfo.nodeFlags & kFSNodeIsDirectoryMask));
+ #else
+ 	/* Get the content modification date and time */
+ 	result = FSGetCatalogInfo(ref, kFSCatInfoContentMod, &catalogInfo, NULL, NULL, NULL);
+ 	require_noerr(result, FSGetCatalogInfo);
+ #endif
+ 	
+ 	oldDateTime = catalogInfo.contentModDate;
+ 
+ 	/* Get the current date and time */
+ 	result = GetUTCDateTime(&catalogInfo.contentModDate, kUTCDefaultOptions);
+ 	require_noerr(result, GetUTCDateTime);
+ 	
+ 	/* if the old date and time is the the same as the current, bump the seconds by one */
+ 	if ( (catalogInfo.contentModDate.fraction == oldDateTime.fraction) &&
+ 		 (catalogInfo.contentModDate.lowSeconds == oldDateTime.lowSeconds) &&
+ 		 (catalogInfo.contentModDate.highSeconds == oldDateTime.highSeconds) )
+ 	{
+ 		++catalogInfo.contentModDate.lowSeconds;
+ 		if ( 0 == catalogInfo.contentModDate.lowSeconds )
+ 		{
+ 			++catalogInfo.contentModDate.highSeconds;
+ 		}
+ 	}
+ 	
+ 	/* Bump the content modification date and time */
+ 	result = FSSetCatalogInfo(ref, kFSCatInfoContentMod, &catalogInfo);
+ 	require_noerr(result, FSSetCatalogInfo);
+ 
+ #if MAC_OSX
+ 	/*
+ 	 * The problem with FNNotify is that it is not available under Mac OS 9
+ 	 * and there's no way to test for that except for looking for the symbol
+ 	 * or something. So, I'll just conditionalize this for those who care
+ 	 * to send a notification.
+ 	 */
+ 	
+ 	/* Send a notification for the parent of the file, or for the directory */
+ 	result = FNNotify(notifyParent ? &parentRef : ref, kFNDirectoryModifiedMessage, kNilOptions);
+ 	require_noerr(result, FNNotify);
+ #endif
+ 
+ 	/* ignore errors from FSSetCatalogInfo (volume might be write protected) and FNNotify */
+ FNNotify:
+ FSSetCatalogInfo:
+ 	
+ 	return ( noErr );
+ 	
+ 	/**********************/
+ 	
+ GetUTCDateTime:
+ FSGetCatalogInfo:
+ 
+ 	return ( result );
+ }
+ 
+ 
+ OSErr
+ FSChangeCreator(
+ 	const FSRef *ref,
+ 	OSType fileCreator)
+ {
+ 	OSErr			result;
+ 	FSCatalogInfo	catalogInfo;
+ 	FSRef			parentRef;
+ 	
+ 	/* get nodeFlags, finder info, and parent FSRef */
+ 	result = FSGetCatalogInfo(ref, kFSCatInfoNodeFlags + 
+ 				  kFSCatInfoFinderInfo, &catalogInfo , 
+ 				  NULL, NULL, &parentRef);
+ 	require_noerr(result, FSGetCatalogInfo);
+ 	
+ 	/* make sure FSRef was to a file */
+ 	require_action(0 == (catalogInfo.nodeFlags & kFSNodeIsDirectoryMask),
+ 		       FSRefNotFile, result = notAFileErr);
+ 	
+ 	
+ 	/* If creator not 0x00000000, change creator */
+ 	if ( fileCreator != (OSType)0x00000000 )
+ 	{
+ 	  ((FileInfo *)&catalogInfo.finderInfo)->fileCreator = fileCreator;
+ 	}
+ 	
+ 	/* now, save the new information back to disk */
+ 	result = FSSetCatalogInfo(ref, kFSCatInfoFinderInfo, &catalogInfo);
+ 	require_noerr(result, FSSetCatalogInfo);
+ 	
+ 	/* and attempt to bump the parent directory's mod date to wake up */
+ 	/* the Finder to the change we just made (ignore errors from this) */
+ 	verify_noerr(FSBumpDate(&parentRef));
+ 	
+ FSSetCatalogInfo:
+ FSRefNotFile:
+ FSGetCatalogInfo:
+ 
+ 	return ( result );
+ }
+ 
+ 
+ DEFUN ("mac-set-creator", Fmac_set_creator, Smac_set_creator, 1, 1, 0,
+        doc: /* Set creator code of file PATH to 'EMAx'.
+ PATH must be a fully qualified file name.
+ Return non-nil if successful.
+    */)
+   (path)
+      Lisp_Object path;
+ {
+   CHECK_STRING (path);
+ 
+   OSErr	status;
+   FSRef defLoc;
+   status = FSPathMakeRef(SDATA(ENCODE_FILE(path)), &defLoc, NULL);
+ 
+   if (status == noErr)
+     {
+       status = FSChangeCreator(&defLoc, (OSType) 'EMAx');
+ 	
+ 	if (status == noErr)
+ 	  return Qt;
+     }
+   return Qnil;
+ }
+  
+ 
+ 
+ #endif
+ 
+ 
+ 
  \f
  /***********************************************************************
  			    Initialization
***************
*** 4617,4622 ****
--- 4776,4784 ----
  #if TARGET_API_MAC_CARBON
    defsubr (&Sx_file_dialog);
  #endif
+ #if MAC_OSX
+   defsubr (&Smac_set_creator);
+ #endif
  }
  
  /* arch-tag: d7591289-f374-4377-b245-12f5dbbb8edc

[-- Attachment #3: Type: text/plain, Size: 142 bytes --]

_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-devel

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2005-07-10 13:30 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-06-24  9:05 Carbon port: setting the creator code (patch) David Reitter
2005-07-09  3:04 ` Steven Tamm
2005-07-09  8:11   ` Sébastien Kirche
2005-07-09 13:06   ` David Reitter
2005-07-09 16:08     ` Steven Tamm
2005-07-10  0:56       ` YAMAMOTO Mitsuharu
2005-07-10 11:55         ` David Reitter
2005-07-10 11:16       ` David Reitter
2005-07-10 13:30         ` Benjamin Riefenstahl

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).