home *** CD-ROM | disk | FTP | other *** search
- /** routine for saveing an IFF picture to the clipboard...
- By Stephen Vermeulen 1989.
- **/
-
- struct IOClipReq clipboardIO = 0;
- struct MsgPort clipboardMsgPort = 0;
- struct MsgPort satisfyMsgPort = 0;
-
- #ifndef MakeID
- #define MakeID(a, b, c, d)\
- ( ((long) (a)<<24) + ((long) (b)<<16) + ((long)(c)<<8) + (long)(d) )
- #endif
-
- short CBisOpen; /** this will be set to 1 when the clipboard has
- been successfully opened.
- **/
-
- /** the following two routines are from a CBM example somewhere on the
- Fish Disks...
- **/
-
- int CBOpen(unit)
- int unit;
- {
- int error;
-
- /* open the clipboard device */
- if ((error = OpenDevice("clipboard.device", (long) unit, &clipboardIO, 0L)) != 0)
- CBisOpen = 0;
-
- /* Set up the message port in the I/O request */
- clipboardMsgPort.mp_Node.ln_Type = NT_MSGPORT;
- clipboardMsgPort.mp_Flags = 0;
- clipboardMsgPort.mp_SigBit = AllocSignal(-1L);
- clipboardMsgPort.mp_SigTask = (struct Task *) FindTask((char *) NULL);
- AddPort(&clipboardMsgPort);
- clipboardIO.io_Message.mn_ReplyPort = &clipboardMsgPort;
-
- satisfyMsgPort.mp_Node.ln_Type = NT_MSGPORT;
- satisfyMsgPort.mp_Flags = 0;
- satisfyMsgPort.mp_SigBit = AllocSignal(-1L);
- satisfyMsgPort.mp_SigTask = (struct Task *) FindTask((char *) NULL);
- AddPort(&satisfyMsgPort);
- CBisOpen = 1;
- }
-
- CBClose()
- {
- if (CBisOpen)
- {
- if (clipboardMsgPort.mp_SigBit > 0)
- FreeSignal(clipboardMsgPort.mp_SigBit);
- if (satisfyMsgPort.mp_SigBit > 0)
- FreeSignal(satisfyMsgPort.mp_SigBit);
-
- RemPort(&satisfyMsgPort);
- RemPort(&clipboardMsgPort);
- CloseDevice(&clipboardIO);
- CBisOpen = 0;
- }
- }
-
- /** the rest of the clipboard routines are my own work **/
-
- /** this is used to set the mode of the clipboard, to either read
- or write (0 or 1)
- **/
-
- CBSetMode(mode)
- int mode;
- {
- if (mode) /** write **/
- {
- clipboardIO.io_Command = CMD_WRITE;
- clipboardIO.io_Offset = 0;
- clipboardIO.io_ClipID = 0;
- }
- else
- {
- clipboardIO.io_Command = CMD_READ;
- clipboardIO.io_Offset = 0;
- clipboardIO.io_ClipID = 0;
- }
- }
-
- /** the following is the function that replaces fread(), calling
- the clipboard instead.
- **/
-
- gfread(data, length, n)
- UBYTE *data;
- int length, n;
- {
- if (CBisOpen)
- {
- while (n)
- {
- clipboardIO.io_Command = CMD_READ;
- clipboardIO.io_Data = (STRPTR) data;
- clipboardIO.io_Length = length;
- DoIO(&clipboardIO);
- data += length;
- --n;
- }
- }
- }
-
- gputc(c)
- char c;
- {
- if (CBisOpen)
- {
- clipboardIO.io_Command = CMD_WRITE;
- clipboardIO.io_Data = (STRPTR) &c;
- clipboardIO.io_Length = 1;
- DoIO(&clipboardIO);
- }
- }
-
- gfwrite(data, length, n)
- UBYTE *data;
- int length, n;
- {
- if (CBisOpen)
- {
- while (n)
- {
- clipboardIO.io_Command = CMD_WRITE;
- clipboardIO.io_Data = (STRPTR) data;
- clipboardIO.io_Length = length;
- DoIO(&clipboardIO);
- data += length;
- --n;
- }
- }
- }
-
- CBEndSession(mode)
- int mode;
- {
- if (!CBisOpen) return;
- if (mode) /** end of writing **/
- {
- clipboardIO.io_Command = CMD_UPDATE;
- DoIO(&clipboardIO);
- }
- else /** end of reading **/
- {
- clipboardIO.io_Command = CMD_READ;
- clipboardIO.io_Offset = 2000000000; /** don't use -1L here!
- the clipboard treats this
- as a SIGNED quantity! **/
- clipboardIO.io_Length = 1;
- clipboardIO.io_Data = (STRPTR) 0;
- DoIO(&clipboardIO);
- }
- }
-
- /** note the following does not support seeking relative to the end
- of the clip...
- **/
-
- gfseek(offset, origin)
- long offset;
- int origin;
- {
- if (CBisOpen)
- {
- switch (origin)
- {
- case 0: /** rel to begining **/
- clipboardIO.io_Offset = offset;
- break;
- case 1: /** rel to current pos **/
- clipboardIO.io_Offset += offset;
- break;
- }
- }
- }
-
- long gftell()
- {
- if (CBisOpen)
- {
- return(clipboardIO.io_Offset);
- }
- else
- return(NULL);
- }
-
- gfopen(mode)
- char *mode;
- {
- if (mode[0] == 'r') CBSetMode(0);
- else CBSetMode(1);
- }
-
- gfclose(mode)
- char *mode;
- {
- if (mode[0] == 'r')
- {
- /** we must force a read beyond the end of the file to tell
- clipboard we are done with it!
- **/
- CBEndSession(0);
- }
- else CBEndSession(1);
- }
-
- #define MaxPackedSize(rowSize) ( (rowSize) + ( ((rowSize) + 127) >> 7) )
- #define RowBytes(w) ((((w) + 15) >> 4) << 1)
-
- /************************************************************
- The following are the IFF read and write routines
- ************************************************************/
-
- #define FORM MakeID('F', 'O', 'R', 'M')
- #define ILBM MakeID('I', 'L', 'B', 'M')
- #define BMHD MakeID('B', 'M', 'H', 'D')
- #define BODY MakeID('B', 'O', 'D', 'Y')
- #define VDFL MakeID('V', 'D', 'F', 'L')
- #define CMAP MakeID('C', 'M', 'A', 'P')
- #define GRAB MakeID('G', 'R', 'A', 'B')
- #define CAMG MakeID('C', 'A', 'M', 'G')
- #define CRNG MakeID('C', 'R', 'N', 'G')
-
- struct BMHdr
- {
- USHORT w, h;
- SHORT x, y;
- UBYTE nPlanes, masking, compression, pad1;
- USHORT transparentColor;
- UBYTE xAspect, yAspect;
- SHORT pageWidth, pageHeight;
- };
-
- struct PictHdr
- {
- LONG IFFid, filelen, ILBMid, BMHDid, BMHDsize;
- struct BMHdr bmhdr;
- };
-
- char comp_buf[1036]; /* buffer to hold the compressed input data */
- short comp_buf_len; /* number of bytes in the compressed buffer */
-
- /***************************************************************
- Quicky little routine that just writes a long word to the file
- ****************************************************************/
-
- void write_WORD(i)
- LONG i;
- {
- (void) gfwrite( (char *) &i, 4, 1);
- }
-
- void write_CMAP(s, d)
- struct Screen *s;
- short d;
- {
- short i, colour;
-
- if (d == 6) d == 5; /* cause of ehb */
- write_WORD(CMAP);
- write_WORD(3L * (1L << d));
- for (i = 0; i < (1 << d); ++i)
- {
- colour = GetRGB4(s->ViewPort.ColorMap, (long) i);
- gputc((colour & 0x0f00) >> 4); /****** red ******/
- gputc((colour & 0x00f0)); /***** green *****/
- gputc((colour & 0x000f) << 4); /****** blue *****/
- }
- }
-
- /************************************************************
- The following routine is used by the IFF saving routines
- to write the body section of the image.
- Returns true if sucessful, else it returns FALSE.
- ************************************************************/
-
- int save_BODY(bm, comp)
- struct BitMap *bm;
- short comp;
- {
- short y, nbytes, bwidth, depth;
- short p;
- struct BitMap mybm;
- char *source, *dest, *bp;
-
- nbytes = bwidth = bm->BytesPerRow;
- mybm = *bm;
- depth = bm->Depth;
-
- /*******************
- scan down the rows
- ********************/
-
- for (y = 0; y < bm->Rows; ++y)
- {
- /**************************
- Sweep down the bit planes
- ***************************/
-
- for (p = 0; p < depth; ++p)
- {
- bp = (char *) mybm.Planes[p];
- if (comp)
- {
- /****************
- pack this row
- *****************/
-
- source = bp;
- dest = &comp_buf[0];
- nbytes = PackRow(&source, &dest, bwidth);
- bp = &comp_buf[0];
- }
-
- /************************
- Now write out the data
- *************************/
-
- gfwrite((char *) bp, nbytes, 1);
- mybm.Planes[p] += bwidth;
- } /* end for bitplanes */
- } /* end for rows */
- return(1);
- }
-
- /************************************************************
- The routine to save designated area of a raster port in
- IFF format.
- ************************************************************/
-
- short save_bm(bm, s)
- struct BitMap *bm;
- struct Screen *s;
- {
- LONG vmode, body_start, body_len, file_len;
- struct PictHdr Pict;
- short i;
- FILE *out;
- char *name;
-
- CBOpen(0);
- if (!CBisOpen) return(0);
- gfopen("w");
- Pict.bmhdr.w = bm->BytesPerRow << 3;
- Pict.bmhdr.h = bm->Rows;
- Pict.bmhdr.x = 0;
- Pict.bmhdr.y = 0;
- Pict.bmhdr.nPlanes = bm->Depth;
- Pict.bmhdr.masking = 0;
- Pict.bmhdr.compression = 1;
- Pict.bmhdr.pad1 = 0;
- Pict.bmhdr.transparentColor = 0;
- Pict.bmhdr.xAspect = (s->Width > 400) ? 10 : 20;
- Pict.bmhdr.yAspect = (s->Height > 280) ? 11 : 22;
- Pict.bmhdr.pageWidth = s->Width;
- Pict.bmhdr.pageHeight = s->Height;
- Pict.IFFid = FORM;
- Pict.filelen = 0; /* fill in later */
- Pict.ILBMid = ILBM;
- Pict.BMHDid = BMHD;
- Pict.BMHDsize = sizeof(struct BMHdr);
- gfwrite( (char *) &Pict, (short) sizeof(struct PictHdr), 1);
-
- write_CMAP(s, bm->Depth);
- vmode = s->ViewPort.Modes;
- vmode &= HIRES | LACE | EXTRA_HALFBRITE | HAM;
- write_WORD(CAMG, out);
- write_WORD(4L, out);
- write_WORD(vmode, out);
-
- /*********************
- Write the BODY chunk
- **********************/
-
- write_WORD(BODY);
- write_WORD(0L); /* fill in later */
- body_start = gftell();
- save_BODY(bm, 1);
- body_len = gftell() - body_start; /* length of body chunk */
- if (gftell() & 0x01L) gputc(0); /* pad byte if needed */
- file_len = gftell();
-
- /**************************
- Reposition in the file
- and write the actual body
- and file lengths.
- ***************************/
-
- gfseek(body_start - 4L, 0); /* body length */
- write_WORD(body_len);
- gfseek(4L, 0); /* file length */
- write_WORD(file_len - 8L);
- gfclose("w");
- CBClose();
- return(1);
- }
-
-
-