Lisp HUG Maillist Archive

Mac resource forks from Lispworks

In one of my forthcoming projects I'm going to want to be able to create buttons or other CAPI objects containing images obtained from the custom icons on Mac OSX directories. OSX uses a sort of bizarre hack to associate custom icons with folders for use by the Finder and other Mac apps--specifically, It creates an invisible empty file named "Icon^M" (that last character is a carriage return), and stores the icon data in the resource fork of the invisible file (resource forks are idiosyncratic to the Mac platform).

Now, Cocoa provides some straightforward tools with which to get at those icons, using NSWorkspace, but calling an Objective-C method to return an NSImage isn't necessarily the most convenient way to get an image that is easy to work with in Lisp. I can go that route if I have to, but does anyone know how I might persuade Lispworks to read the icons from the resource fork? There are pathname shenanigans you can perform with OSX tools to get at resource forks but, unsurprisingly, the Lispworks pathname implementation doesn't seem to know about them (not that it necessarily should...).





_______________________________________________
Lisp Hug - the mailing list for LispWorks users
lisp-hug@lispworks.com
http://www.lispworks.com/support/lisp-hug.html


Re: Mac resource forks from Lispworks

Hi,

I know about the Mac'sms very well. But in the recent past, I have just used (as seems most other App writers) the Contents/Resources folder of the App to store any custom information, such as cursors, icons, text and data files, etc. I think the fork you speak of dates back to 1984 when the Mac was first introduced. Might even have been an outgrowth of the old Lisa project. But today, totally unnecessary. 

- DM


On Nov 29, 2013, at 09:54 AM, mikel evins <mevins@me.com> wrote:


In one of my forthcoming projects I'm going to want to be able to create buttons or other CAPI objects containing images obtained from the custom icons on Mac OSX directories. OSX uses a sort of bizarre hack to associate custom icons with folders for use by the Finder and other Mac apps--specifically, It creates an invisible empty file named "Icon^M" (that last character is a carriage return), and stores the icon data in the resource fork of the invisible file (resource forks are idiosyncratic to the Mac platform).

Now, Cocoa provides some straightforward tools with which to get at those icons, using NSWorkspace, but calling an Objective-C method to return an NSImage isn't necessarily the most convenient way to get an image that is easy to work with in Lisp. I can go that route if I have to, but does anyone know how I might persuade Lispworks to read the icons from the resource fork? There are pathname shenanigans you can perform with OSX tools to get at resource forks but, unsurprisingly, the Lispworks pathname implementation doesn't seem to know about them (not that it necessarily should...).





_______________________________________________
Lisp Hug - the mailing list for LispWorks users
lisp-hug@lispworks.com
http://www.lispworks.com/support/lisp-hug.html



Dr. David McClain
dbm@refined-audiometrics.com



Re: Mac resource forks from Lispworks

Hi Mikel,

I would suggest you try this:

(from Wikipedia article: http://en.wikipedia.org/wiki/Resource_fork)

> From the POSIX interface, the resource fork could be accessed as filename/..namedfork/rsrc […]


So I would guess that opening a stream to the special pathname would work.
Now, it is not exactly sure that you will like what you’ll see, I wouldn’t bet the icon data is merely encoded as standard encoding like PNG...


Best,
Cam


On 29 nov. 2013, at 17:54, mikel evins <mevins@me.com> wrote:

> 
> In one of my forthcoming projects I'm going to want to be able to create buttons or other CAPI objects containing images obtained from the custom icons on Mac OSX directories. OSX uses a sort of bizarre hack to associate custom icons with folders for use by the Finder and other Mac apps--specifically, It creates an invisible empty file named "Icon^M" (that last character is a carriage return), and stores the icon data in the resource fork of the invisible file (resource forks are idiosyncratic to the Mac platform).
> 
> Now, Cocoa provides some straightforward tools with which to get at those icons, using NSWorkspace, but calling an Objective-C method to return an NSImage isn't necessarily the most convenient way to get an image that is easy to work with in Lisp. I can go that route if I have to, but does anyone know how I might persuade Lispworks to read the icons from the resource fork? There are pathname shenanigans you can perform with OSX tools to get at resource forks but, unsurprisingly, the Lispworks pathname implementation doesn't seem to know about them (not that it necessarily should...).
> 
> 
> 
> 
> 
> _______________________________________________
> Lisp Hug - the mailing list for LispWorks users
> lisp-hug@lispworks.com
> http://www.lispworks.com/support/lisp-hug.html
> 


_______________________________________________
Lisp Hug - the mailing list for LispWorks users
lisp-hug@lispworks.com
http://www.lispworks.com/support/lisp-hug.html


Re: Mac resource forks from Lispworks


On Nov 29, 2013, at 11:32 AM, Camille Troillard <camille@osculator.net> wrote:

> 
> Hi Mikel,
> 
> I would suggest you try this:
> 
> (from Wikipedia article: http://en.wikipedia.org/wiki/Resource_fork)
> 
>> From the POSIX interface, the resource fork could be accessed as filename/..namedfork/rsrc […]
> 
> 
> So I would guess that opening a stream to the special pathname would work.
> Now, it is not exactly sure that you will like what you’ll see, I wouldn’t bet the icon data is merely encoded as standard encoding like PNG....

I already tried it; it didn't work.

I'll try it again just to make sure I didn't screw something up the first time.


_______________________________________________
Lisp Hug - the mailing list for LispWorks users
lisp-hug@lispworks.com
http://www.lispworks.com/support/lisp-hug.html


Re: Mac resource forks from Lispworks


On Nov 29, 2013, at 11:23 AM, David McClain <dbm@refined-audiometrics.com> wrote:

> Hi,
> 
> I know about the Mac'sms very well. But in the recent past, I have just used (as seems most other App writers) the Contents/Resources folder of the App to store any custom information, such as cursors, icons, text and data files, etc. I think the fork you speak of dates back to 1984 when the Mac was first introduced. Might even have been an outgrowth of the old Lisa project. But today, totally unnecessary. 

The project in question needs to be able to look at an existing OSX system and display the same custom folder icons that the Finder would display. Those custom icons are stored in a resource fork (yes, still, in this day and age). That being the case, I have to be able to read those resource forks.

As I already mentioned, I know how to do that using Cocoa (I was a programmer at Apple in the 80s and 90s and am quite familiar with both resource forks and the historical context of their invention). I would prefer to do it in a more Lisp-friendly way if I can, and I was hoping someone else already had that figured out.



_______________________________________________
Lisp Hug - the mailing list for LispWorks users
lisp-hug@lispworks.com
http://www.lispworks.com/support/lisp-hug.html


Re: Mac resource forks from Lispworks


On Nov 30, 2013, at 7:50 AM, Camille Troillard <camille@osculator.net> wrote:

> Hi Mikel,
> 
> I would advise that you abstract the system interfaces away (ie NSWorkSpace). You can get the NSImage's decoded bytes and feed it into a gp:image that you will use in your LW application.
> 
> You can't guarantee in the future that Apple won't change the format of the icons or just drop support for resource forks in the future. For me this is private stuff.

Good point.




_______________________________________________
Lisp Hug - the mailing list for LispWorks users
lisp-hug@lispworks.com
http://www.lispworks.com/support/lisp-hug.html


Re: Mac resource forks from Lispworks

Mikel,

Perhaps I'm misunderstanding, but aren't all the application icons 
located in the Contents/Resources folder of the .app "file"? The 
filename of the icns file will be located in Contents/Info.plist under:

<plist>
<dict>
     ...
<key>CFBundleIconFile</key>
<string>app.icns</string>
     ...
</dict>
</plist>

So, if you wanted to find the icns file reliably for any Mac OS X 
..app... (note: the code below uses my xml parsing library - available on 
github - but should give you the idea):

(defun icns-for-app (app)
   (when-let (pathname (probe-file app))
     (let* ((contents (merge-pathnames "Contents/" pathname))
            (resources (merge-pathnames "Resources/" contents))
            (plist-file (merge-pathnames "Info.plist" contents))
            (plist-doc (xml:parse-xml (lex:slurp plist-file)))
            (plist-dict (xml:query-xml plist-doc "/plist/dict" :first t))
            (key-values (xml:node-elements plist-dict)))
       (loop :for key := (pop key-values)
             :for value := (pop key-values)
             :while key
             :when (string= (xml:node-value key) "CFBundleIconFile")
             :return (let ((icns (pathname (xml:node-value value))))
                       (unless (pathname-type icns)
                         (setf icns (make-pathname :name (pathname-name 
icns) :type "icns")))
                       (merge-pathnames icns resources))))))

Sometimes the CFBundleIconFile is missing the .icns extension, so it's a 
good idea to check for it and add it on if missing.

CL-USER > (icns-for-app "/Applications/LispWorks 6.1/LispWorks.app")
#P"/Applications/LispWorks 6.1/LispWorks.app/Contents/Resources/app.icns"

CL-USER > (icns-for-app "/Applications/iMovie.app")
#P"/Applications/iMovie.app/Contents/Resources/iMovie.icns"

Is this what you are hoping to achieve?

Jeff M.

mikel evins wrote:
> In one of my forthcoming projects I'm going to want to be able to create buttons or other CAPI objects containing images obtained from the custom icons on Mac OSX directories. OSX uses a sort of bizarre hack to associate custom icons with folders for use by the Finder and other Mac apps--specifically, It creates an invisible empty file named "Icon^M" (that last character is a carriage return), and stores the icon data in the resource fork of the invisible file (resource forks are idiosyncratic to the Mac platform).
>
> Now, Cocoa provides some straightforward tools with which to get at those icons, using NSWorkspace, but calling an Objective-C method to return an NSImage isn't necessarily the most convenient way to get an image that is easy to work with in Lisp. I can go that route if I have to, but does anyone know how I might persuade Lispworks to read the icons from the resource fork? There are pathname shenanigans you can perform with OSX tools to get at resource forks but, unsurprisingly, the Lispworks pathname implementation doesn't seem to know about them (not that it necessarily should...).
>
>
>
>
>
> _______________________________________________
> Lisp Hug - the mailing list for LispWorks users
> lisp-hug@lispworks.com
> http://www.lispworks.com/support/lisp-hug.html
>

_______________________________________________
Lisp Hug - the mailing list for LispWorks users
lisp-hug@lispworks.com
http://www.lispworks.com/support/lisp-hug.html


Re: Mac resource forks from Lispworks


On Nov 30, 2013, at 10:43 AM, Jeffrey Massung <massung@gmail.com> wrote:

Perhaps I'm misunderstanding, but aren't all the application icons located in the Contents/Resources folder of the .app "file"? The filename of the icns file will be located in Contents/Info.plist under:

You're right: you're misunderstanding.

You're quite right about the accessibility of app icons, but that's not what I'm talking about. What I'm talking about is this:


Notice the custom icons on the Finder's view of the Adobe folders.

The icon resources are stored here:


See the file named "Icon"? In fact, it's actually named "Icon<carriage-return>", and it's an empty file:

  esthannon:~ mikel$ cd /Applications/Adobe\ InDesign\ CS5.5
  esthannon:Adobe InDesign CS5.5 mikel$ ls -l Icon^M
  -rw-r--r--@ 1 root  admin  0 Feb 24  2013 Icon?

The file that ls examines is empty, but there is also a resource fork that isn't empty:

esthannon:Adobe InDesign CS5.5 mikel$ ls -l Icon^M/..namedfork/rsrc
-rw-r--r--  1 root  admin  133034 Feb 24  2013 Icon?/..namedfork/rsrc

That resource fork is where the custom icon shown in the Finder for InDesign resides. I need to be able to display that custom icon in the same way that the Finder does.

I consider this question answered. I already knew how to do it from Cocoa code; I was looking for a way to tell Lispworks to read the data from the resource fork in order to dodge writing Cocoa code, but I buy Camille's argument that it's better to just go ahead and use Cocoa. Apple could change how these data are stored at any point in the future, and it's marginally less likely that such changes will break my code if I use the native Cocoa idiom for reading them.


Updated at: 2020-12-10 08:34 UTC