Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Posting-Version: version B 2.10.2 9/18/84; site uw-beaver
Path: utzoo!watmath!clyde!burl!ulysses!mhuxj!houxm!vax135!cornell!uw-beaver!info-mac
From: info-mac@uw-beaver
Newsgroups: fa.info-mac
Subject: Icons
Message-ID: <148@uw-beaver>
Date: Mon, 10-Dec-84 00:45:02 EST
Article-I.D.: uw-beave.148
Posted: Mon Dec 10 00:45:02 1984
Date-Received: Tue, 11-Dec-84 03:31:56 EST
Sender: daemon@uw-beaver
Organization: U of Washington Computer Science
Lines: 324
From: Canas%ukans.csnet@csnet-relay.arpa
The following text (edited) comes from a public domain disk. It explains how
to edit icons.
About Icons
Including
Icon Manipulator, Icon General Theory, and the Clipboard Special Property
In order to explain Icon Manipulator, I gotta tell you about some other
'features' of the Mac system as a whole and go into some information on icons
themselves first. This will be pretty informative and will give you an insight
into some 'sneaking around' that you can do.
Part 1: Icons. Icons, like all other pieces of an application reside in the
application's resource fork. If you use Resource Mover, you can actually look at
the icons in a resource fork. (Resource Mover displays the actual data for
resources with types STR, ICON, MENU, CURS, and PICT.) Just pick an application,
(Slots is good....) and open any of the ICON resources with Resource Mover. See
the nice little Icon? You might notice in some resource file the type ICN# and
think that it refers to icons. Resource Mover won't display them, though. The
reason for this is that ICN# is the type for an icon list. There may be two or
more icons in the list, and Resource Mover isn't equipped to handle this.
Icons, in reality, are 32 by 32 bit images. Since a byte is eight bits, that is
4 by 32 bytes. (No, you can't divide both dimensions by four.) This totals to
128 bytes per icon. (You can use this fact to see how many icons are in an icon
list. Just divide the size by 128.)
Now you know how icons are stored. Now I will sidetrack a bit and talk about the
scrapbook. The scrapbook is really nothing more than a resource fork. It
contains one fixed entry of type SMAP (Scrapbook MAP) that tells it what all of
the Scrapbook's entries are. All scrapbook entries are resources and reside in
the scrapbooks resource fork. Nothing resides in its data fork. (Getting some
ideas......?)
It is interesting to note here that you can make a picture with MacPaint, cut or
copy it to the clipboard, and then use Resource Mover to move the picture from
the scrapbook into any other resource file. Some files that have pictures (type
PICT) in their resource forks are System, Finder, etc.Back to icons. Since our
general goal is to be able to manipulate, edit, add, and delete icons from
resource files, we have to be able to work with them. Well, with few exceptions,
there are no appications to edit anything in the resource forks of a file. On
the other hand, MS-Basic, Icon Edit, and most other things work with data in the
data fork of a file.Icon Edit was designed to let developers make icons for
their applications. The instructions from Apple tell the developers to design
their icon with Icon Edit, then display the hex data and type it into the Lisa.
How barbaric: retyping something that is already in computer format.Well,
anyway, it should be getting clear now that if we could move things between the
two forks that lots of problems would clear up. But Resource Mover only moves
things within the realm of the resource fork, MS-Basic only manipulates things
in the data fork, and Examine FIle displays both forks but will edit
neither.Which brings us back to the discussion of the scrapbook. Recall that the
scrapbook is all resource fork. Also realise that MacPaint documents are all
data fork. (Hmmm.....) What did we do to move the pictures to and from the
scrapbook and to and from the MacPaint documents. We used the clipboard.The
clipboard has the unique feature that it moves data across the two forks. You've
seen that it can move picture resources, and can probably assume that it will
handle strings (text), but what about icons and other stuff? Well, it will move
them, but getting to them is not straight forward. Both the clipboard and the
scrapbook will display text and pictures and nothing else, but both will accept
just about anything.To see this, use the Note Pad to enter some random text, cut
it to the clipboard and paste it to the scrapbook. All looks normal. Next, use
Resource Mover to copy an icon from some file to the scrapbook. Then clear the
latest scrapbook entry. (The latest entry has the highest valued number. That
is, -32758 is higher than -32762 because both numbers are negative. If you
ignore the negative sign, you can look for the smallest number.) Select it, then
choose clear from the edit menu but remember the number! Next, select the icon
that you added earlier. Choose Set ID from the edit menu and set the id to the
number of the entry that you deleted.The reason for going through all of this is
pretty clear. The resource SMAP contains a list of id numbers that are currently
in the scrapbook. If you want to add something, sonce there is no way to modify
SMAP, you have to replace something that was already there. That's all we're
doing.
If you exit back to the Finder, you can call up the scrapbook and look at the
first entry. That little message is the Mac's way of saying it isn't a normal
entry. The clipboard doesn't care, though, and will copy (or cut) from it with
no problem. The clipboard will also show a message indicating that you've done
something unusual to it. Don't worry. This is great.Now we have succeeded in
getting the icon onto the clipboard. But how do we get it off the clipboard and
into a data fork of a file? Remember that MS-Basic interacts with data forks?
Good. Here we go.
Part 2: The basic solution. The clipboard is in many places at once. For small
entries, it is all in memory. For larger entries, it is in memory, on the disk,
or wherever the Finder has room. This will be important later. Right now, just
realise that an icon is a small entry and resides in memory.
MS-Basic recognises the clipboard as a device called Clip: with chich it can
communicate. This device mechanism, though, only supports text. If you try to
open the Clip: device for input while it has something other than text in it,
you'll get a device I/O error. But before Ms-Basic checks the data on the
clipboard, it stores the clipboard onto the disk as file Clipboard File. The
reason for this is that MS-Basic is used to dealing with files, not data in
memory.
Although the Clip: device check the data type, if you try to read directly from
the Clipboard File, you won't get any errors. Therefore I set up the basic
program to read from Clipboard File. But first I had to attempt a read from the
Clip: device. If I didn't, no Clipboard File would have been created and I would
have gotten an File Not Found error when trying to read from it. I trapped out
the Device I/O Error with a simple On Error Goto.
There we have it, the data from the clipboard in a Basic-readable file. This
file is an exact copy of the clipboard area in memory. The first four bytes are
the type. For text, they are the ascii values of the letters T, E, X, and T
respectively. For icons, the letters are I, C, O, and N. (Surprise, surprise.)
It is these four bytes that MS-Basic checks when opening the Clip: device. The
next four bytes are the length of the data. For an icon, they are $00 $00 $00
$80. (128 bytes). To get the icon data into memory, all we have to do is read
136 bytes and discard the first 8. That's all I do.
It is a trivial matter, then, to save the 128 bytes to a normal file. In fact,
doing that would create a file that is compatible with Icon Edit. An Icon Edit
file is just 128 bytes of icon data.
Reading the 128 bytes from a normal file would also be trivial, so we can get an
icon into memory easily. The hardest part of all is getting the con data from
memory back to the clipboard. If you open the Clip: device, it automatically
sends 'TEXT' a the first four bytes. If we write to the Clipboard File directly,
it doesn't affect the real clipboard which is in memory.
The only solution available to us from basic is to poke the information directly
into memory where the clipboard resides. There are two problems with this.
First, how do we make the clipboard expect 136 bytes exactly of data? Second,
how do we find in memory where the clipboard resides?
The solution to problem one is simple. All I did was open the Clip: device and
write out a string of 128 characters, then close the Clip: device. Closing the
Clip: device copies the Clipboard File into the clipboard in memory. (But we
can't open Clip:, write to the Clipboard File, then close Clip: to copy it into
ram because Basic won't let you open Clipboard File for output while Clip: is
using it. Oh well.)
Anyway, we now have a clipboard in memory that has exactly 136 bytes. How do we
find it? Well, I look for the string 'TEXT' in memory. Unfortunately there are
more than one occurances of 'TEXT'. No problem. When I send the 128 character
string to the Clip: device, the first four characters are random letters. I then
look for these same random letters to be in memory 8 bytes after the start of
'TEXT'. It works fine.
Then, to get the icon onto the clipboard, I poke 'ICON' $00 $00 $00 $80 followed
by the 128 icon data bytes. After that, it is a simple matter of pasting from
the clipboard to the scrapbook. You can then use Resource Mover to put the icon
into any resource file.
In order to speed things up, I use a 68000 machine language subroutine to find
'TEXT' and the four random letters. If you write a loop in MS-Basic to peek
memory until you find it, it takes about 1/2 hour. My machine language
subroutine finds the clipboard in under a minute. Look for later documents
concerning machine and assmebly languages on the Mac.
Part 3: Using Icon Manipulator. The best way to use Icon Manipulator is to put
it on your MS-Basic disk. If you didn't boot with MS-Basic, and you run Icon
Manipulator, all the text comes out screwed up. Other than that, the whole
program is mouse driven and a piece of cake to use. It won't let you
accidentally write over an existing file, and won't crash if you try to load
something that isn't there.
The current disk name has to match a known disk, or you'll generate File Not
Found errors. The file name can be just about anything. The current icon is
actually displayed in the upper left corner of the screen.
To go from the clipboard to a file, do the following:
1 - Get the icon you want into the scrapbook using Resource Mover.
2 - Copy or cut the icon into the clipboard.
3 - Run Icon Manipulator, load from the clipboard, save to a file.
To go from a file to the clipboar, do this:
1 - Run Icon Manipulator, load from a file, save to the clipboard.
2 - Paste immediately to the scrapbook.
3 - Use Resource Mover to put the icon where you want it.
Icon Manipulator, like all the MS-Basic applications I write, is 100% listable
and copyable. Go through the code if you like. If you have any questions about
it, I'll be happy to answer them.
Another backdoor utility from
SIMON JESTER
-----------------------Icon Manipulator Program ------------------
10 REM Now you can actually move icons to where you want them!
20 REM
30 REM
40 REM Simon Jester!
50 REM
60 CALL TEXTFACE(0):CALL TEXTFONT(1):CALL TEXTSIZE(0)
70 CLS
80 RANDOMIZE TIMER:DEF FNR(X)=INT(RND(1)*10)+65:GOSUB 1240
90 PRINT:PRINT SPC(22);:CALL TEXTFACE(5):CALL TEXTFONT(10):CALL
TEXTSIZE(20):PRINT"ICON Mover"
100 CALL TEXTFACE(1):CALL TEXTFONT(1):CALL TEXTSIZE(0)
110 PRINT" For moving icons from files to the clipboard and vice versa."
120 CALL TEXTFACE(0):PRINT" Another utility from:
";:CALL TEXTFACE(5):PRINT"SIMON JESTER!":CALL TEXTFACE(0)
130 CALL MOVETO(213,125):PRINT"CONTINUE";
140 X1=205:X2=285:Y1=110:Y2=130:GOSUB 1110
150 IF MOUSE(0)=0 THEN 150
160 IF MOUSE(3)<205 OR MOUSE(3)>285 OR MOUSE (4)<110 OR MOUSE(4)>130 THEN 150
170 REM Set up the interaction screen
180 CLS:CALL TEXTFACE(1)
190 PRINT"Current Icon";:LINE (15,20)-STEP(42,42),,B
200 PRINT" Current disk name:":PRINT:PRINT TAB(15);"Current file name:"
210 CALL TEXTFACE(0)
220 PRINT:PRINT TAB(35);"Load Icon from a file."
230 PRINT TAB(35);"Load Icon from the Clipboard."
240 PRINT:PRINT TAB(35);"Save Icon to a file."
250 PRINT TAB(35);"Save Icon to the Clipboard."
260 PRINT:PRINT TAB(35);"Change the current disk name."
270 PRINT TAB(35);"Change the current file name."
280 CALL MOVETO(80,100):PRINT"Messages"
290 LINE(15,85)-(200,200),,B:LINE(15,105)-(200,105)
300 FOR I=1 TO 6:READ Y1:GOSUB 1150:NEXT I
310 DATA 67,82,115,130,163,178
320 DSK$="MS-BASIC Master":FI$="hand icon":DIM D%(80)
330 IF MOUSE(0)<>0 THEN 330
340 REM Main Loop
350 IF MOUSE(0)<>0 THEN 350
360 LINE (270,2)-(490,60),30,BF:CALL MOVETO(270,12):PRINT DSK$
370 CALL MOVETO(270,44):PRINT FI$
380 IF MOUSE(0)=0 THEN 380
390 IF MOUSE(3)<255 OR MOUSE(3)>265 THEN 380
400 IF MOUSE(4)>177 AND MOUSE(4)<189 THEN 470
410 IF MOUSE(4)>162 AND MOUSE(4)<174 THEN 490
420 IF MOUSE(4)>129 AND MOUSE(4)<141 THEN 770
430 IF MOUSE(4)>114 AND MOUSE(4)<126 THEN 510
440 IF MOUSE(4)>81 AND MOUSE(4)<93 THEN 670
450 IF MOUSE(4)>65 AND MOUSE(4)<77 THEN 730
460 GOTO 380
470 MSG$="Enter a new file name:":GOSUB 1160:GOSUB 1170:GOSUB 1180:IF IN$=""
THEN IN$=FI$
480 FI$=IN$:GOTO 340
490 MSG$="Enter a new disk name:":GOSUB 1160:GOSUB 1170:GOSUB 1180:IF IN$=""
THEN IN$=DSK$
500 DSK$=IN$:GOTO 340
510 ON ERROR GOTO 640:TFI$=DSK$+":"+FI$
520 OPEN TFI$ FOR INPUT AS #1
530 CLOSE #1:MSG$="That file exists!":GOSUB 1160
540 CALL MOVETO(25,180):PRINT" Abort
Overwrite":LINE(15,105)-(200,200),,B
550 X1=27:Y1=167:X2=75:Y2=185:GOSUB 1110
560 X1=110:X2=185:GOSUB 1110
570 BEEP
580 IF MOUSE(0)<>0 THEN 580
590 IF MOUSE(0)=0 THEN 590
600 IF MOUSE(4)Y2 THEN 590
610 IF MOUSE(3)>=X1 AND MOUSE(3)<=X2 THEN GOSUB 1180:GOTO 650
620 IF MOUSE(3)>=27 AND MOUSE(3)<=75 THEN GOSUB 1180:GOTO 340
630 GOTO 590
640 CLOSE #1:RESUME 650
650 OPEN TFI$ FOR OUTPUT AS #1
660 PRINT #1,B$;:CLOSE #1:GOTO 340
670 ON ERROR GOTO 690
680 B$="":OPEN "Clip:" FOR INPUT AS #1: CLOSE #1
690 CLOSE #1:RESUME 700
700 ON ERROR GOTO 720
710 TFI$=DSK$+":"+"Clipboard File":GOTO 940
720 MSG$="Error loading icon...":GOSUB 1160:GOSUB 1190:GOSUB 1180: RESUME 340
730 ON ERROR GOTO 760
740 B$="ICON"+CHR$(0)+CHR$(0)+CHR$(0)+CHR$(128)
750 TFI$=DSK$+":"+FI$ : GOTO 940
760 MSG$=" No such file!":GOSUB 1160 :GOSUB 1190:GOSUB 1180:RESUME 340
770 A$=CHR$(FNR(0))+CHR$(FNR(0))+CHR$(FNR(0))+CHR$(FNR(0))
780 WHILE LEN(A$)<128
790 A$=A$+"X"
800 WEND
810 TEMP=ASC(MID$(A$,1,1))*256+ASC(MID$(A$,2,1)):IF TEMP>32767 THEN
TEMP=TEMP-65536!
820 CODE%(12)=TEMP
830 TEMP=ASC(MID$(A$,3,1))*256+ASC(MID$(A$,4,1)):IF TEMP>32767 THEN
TEMP=TEMP-65536!
840 CODE%(13)=TEMP
850 OPEN "Clip:" FOR OUTPUT AS #1:PRINT #1,A$;:CLOSE #1
860 TEMP=VARPTR(CODE%(0)) : CALL TEMP : PTR = CODE%(24) + CODE%(23) * 65536!
870 IF CODE%(24)<0 THEN PTR+CODE%(24)+65536!+CODE%(23)*65536!
880 B$="ICON"+CHR$(0)+CHR$(0)+CHR$(0)+CHR$(128)+B$
890 FOR I=0 TO LEN(B$)-1
900 POKE PTR+I,ASC(MID$(B$,I+1,1))
910 NEXT I
920 CLS:SYSTEM
930 END
940 OPEN TFI$ FOR INPUT AS #1
950 WHILE (NOT EOF(1)) AND (LEN(B$)<=136)
960 A$=INPUT$(1,#1)
970 B$=B$+A$
980 WEND
990 CLOSE #1
1000 IF LEFT$(B$,4)="ICON" THEN 1020
1010 MSG$="Not an Icon file!":GOSUB 1160:GOSUB 1190:GOSUB 1180:GOTO 340
1020 D%(0)=32:D%(1)=32
1030 FOR I=0 TO (4*32)-1 STEP 2
1040 TMP=ASC(MID$(B$,I+9,1))*256+ASC(MID$(B$,I+10,1))
1050 IF TMP>32767 THEN TMP=TMP-65536!
1060 D%(I/2+2)=TMP
1070 NEXT
1080 LINE(16,21)-STEP(40,40),30,BF:PUT (20,25),D%
1090 B$=RIGHT$(B$,LEN(B$)-8)
1100 GOTO 340
1110 REM RoundRect subroutine
1120 RECT%(0)=Y1:RECT%(1)=X1:RECT%(2)=Y2:RECT%(3)=X2
1130 CALL FRAMEROUNDRECT(VARPTR(RECT%(0)),18,18)
1140 RETURN
1150 LINE(255,Y1)-(265,Y1+10),,B:RETURN
1160 CALL MOVETO(20,120):PRINT MSG$:RETURN
1170 CALL MOVETO(20,150):INPUT IN$:RETURN
1180 LINE(16,106)-(199,199),30,BF:LINE(15,105)-(200,200),,B:RETURN
1190 CALL MOVETO(100,180): PRINT"Okay":X1=90:Y1=167 :X2=140 :Y2=188: GOSUB
1110:BEEP
1200 IF MOUSE(0)<>0 THEN 1200
1210 IF MOUSE(0)=0 THEN 1210
1220 IF MOUSE(3)X2 OR MOUSE(4)Y2 THEN 1210
1230 RETURN
1240 DATA "X","207C0000D6D843FA002622880C9054455854660E"
1250 DATA "4E71"
1260 DATA "0CA800000000000866024E755448B1FC0001ADB0"
1270 DATA "66DE60F200000000"
1280 DATA "FFFF"
1290 REM Fill machine language data
1300 DIM CODE%(36)
1310 CPT=0:READ CD$:IF CD$<>"X" THEN 1310
1320 READ CD$:IF CD$="FFFF" THEN RESTORE:RETURN
1330 CODE%(CPT) = VAL("&H"+LEFT$(CD$,4)) : CPT=CPT+1 :
CD$=RIGHT$(CD$,LEN(CD$)-4)
1340 IF LEN(CD$)>0 THEN 1330 ELSE 1320