From: David Reitter <david.reitter@gmail.com>
Cc: Steven Tamm <steventamm@mac.com>, emacs-devel@gnu.org
Subject: Re: Carbon port: setting the creator code (patch)
Date: Sun, 10 Jul 2005 12:55:01 +0100 [thread overview]
Message-ID: <130C5771-E3DE-4ADF-97B1-0D992E726ED8@gmail.com> (raw)
In-Reply-To: <wl3bqn5vj2.wl%mituharu@math.s.chiba-u.ac.jp>
[-- Attachment #1: Type: text/plain, Size: 858 bytes --]
On 10 Jul 2005, at 01:56, YAMAMOTO Mitsuharu wrote:
> I think these functions should follow the convention of existing
> operations on files. For example, with respect to the default
> directory, error handling, and argument names. Maybe the function
> name should be "mac-set-file-creator". We can additionally think of
> "mac-file-creator" and "mac-file-type", or "mac-file-attributes" for
> reading these kinds of information.
OK, what I have now is
(mac-set-file-creator filename &optional code)
(mac-set-file-type filename type)
They throw errors if code or type or filename are bad.
> And more importantly, please care about BLOCK_INPUT when adding new C
> functions. It required much effort to fill missing BLOCK_INPUTs that
> had been a cause of unstability in the Carbon port.
OK, done. Hope I got that right.
The new patch is enclosed.
[-- Attachment #2: mac-set-creator.patch --]
[-- Type: application/octet-stream, Size: 7529 bytes --]
Index: macfns.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/macfns.c,v
retrieving revision 1.63
diff -c -r1.63 macfns.c
*** macfns.c 4 Jul 2005 16:06:33 -0000 1.63
--- macfns.c 10 Jul 2005 11:52:18 -0000
***************
*** 4406,4411 ****
--- 4406,4656 ----
{
}
#endif
+
+
+ #ifdef MAC_OSX
+
+
+ /* The code for FSBumpDate and FSChangeCreatorType 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
+ FSChangeCreatorType(
+ const FSRef *ref,
+ OSType fileCreator,
+ OSType fileType)
+ {
+ 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 && fileCreator != (OSType)0x00000000 )
+ {
+ ((FileInfo *)&catalogInfo.finderInfo)->fileCreator = fileCreator;
+ }
+ /* If type not 0x00000000, change type */
+ if (fileType && fileType != (OSType)0x00000000 )
+ {
+ ((FileInfo *)&catalogInfo.finderInfo)->fileType = fileType;
+ }
+
+ /* 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-file-creator", Fmac_set_file_creator, Smac_set_file_creator, 1, 2, 0,
+ doc: /* Set creator code of file FILENAME to CODE.
+ If non-nil, CODE must be a 4-character string. Otherwise,
+ 'EMAx' is assumed. Return non-nil if successful.
+ */)
+ (filename, code)
+ Lisp_Object filename;
+ Lisp_Object code;
+ {
+
+
+
+
+ CHECK_STRING (filename);
+ OSErr status;
+ FSRef defLoc;
+ OSType cCode;
+
+ if (NILP(code))
+ {
+ cCode = 'EMAx';
+ }
+ else
+ {
+ /* check type string */
+ CHECK_STRING(code);
+ if (strlen(SDATA(code)) != 4)
+ {
+ error ("Wrong argument: need string of length 4 for CODE");
+ }
+ cCode = (OSType) *((int *) SDATA(code));
+ }
+ BLOCK_INPUT;
+ filename = Fexpand_file_name (filename, Qnil);
+ status = FSPathMakeRef(SDATA(ENCODE_FILE(filename)), &defLoc, NULL);
+
+
+ if (status == noErr)
+ {
+ status = FSChangeCreatorType(&defLoc, cCode, (OSType) 0);
+ UNBLOCK_INPUT;
+
+ if (status == noErr)
+ {
+ return Qt;
+ }
+ else
+ error ("Error while setting creator information.");
+ }
+ else
+ {
+ UNBLOCK_INPUT;
+ error ("Error while accessing file.");
+ }
+ }
+
+
+ DEFUN ("mac-set-file-type", Fmac_set_file_type, Smac_set_file_type, 2, 2, 0,
+ doc: /* Set type of file FILENAME to TYPE.
+ TYPE must be a 4-character string.
+ Return non-nil if successful.
+ */)
+ (filename,type)
+ Lisp_Object filename;
+ Lisp_Object type;
+ {
+ OSErr status;
+ FSRef defLoc;
+
+ CHECK_STRING (filename);
+
+ /* check type string */
+ CHECK_STRING(type);
+ if (strlen(SDATA(type)) != 4)
+ {
+ error ("Wrong argument: need string of length 4 for CODE");
+ }
+
+ BLOCK_INPUT;
+ filename = Fexpand_file_name (filename, Qnil);
+ status = FSPathMakeRef(SDATA(ENCODE_FILE(filename)), &defLoc, NULL);
+
+ if (status == noErr)
+ {
+ /* warning: the string-to-OSType conversion here might not be safe
+ when using Intel type endians... */
+
+ status = FSChangeCreatorType(&defLoc,
+ (OSType) 0,
+ (OSType) *((int *) SDATA(type)));
+ UNBLOCK_INPUT;
+ if (status == noErr)
+ {
+ return Qt;
+ }
+ else
+ error ("Error while setting creator information.");
+ }
+ else
+ {
+ UNBLOCK_INPUT;
+ error ("Error while accessing file.");
+ }
+ }
+
+
+ #endif
+
+
+
\f
/***********************************************************************
Initialization
***************
*** 4616,4621 ****
--- 4861,4870 ----
#if TARGET_API_MAC_CARBON
defsubr (&Sx_file_dialog);
+ #endif
+ #if MAC_OSX
+ defsubr (&Smac_set_file_creator);
+ defsubr (&Smac_set_file_type);
#endif
}
[-- Attachment #3: Type: text/plain, Size: 1 bytes --]
[-- Attachment #4: Type: text/plain, Size: 142 bytes --]
_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-devel
next prev parent reply other threads:[~2005-07-10 11:55 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
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 [this message]
2005-07-10 11:16 ` David Reitter
2005-07-10 13:30 ` Benjamin Riefenstahl
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=130C5771-E3DE-4ADF-97B1-0D992E726ED8@gmail.com \
--to=david.reitter@gmail.com \
--cc=emacs-devel@gnu.org \
--cc=steventamm@mac.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.