home *** CD-ROM | disk | FTP | other *** search
- /*
- * ClipTool (Udklipsværktøj) - A Commodities Exchange Application
- * Copyright (C) 1994 Torsten Poulin
- *
- * buffers.c - the text buffer and clipboard routines.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * The author can be contacted by mail at
- * Torsten Poulin
- * Banebrinken 99, 2, 77
- * DK-2400 Copenhagen NV
- * Denmark
- * or via email: torsten@diku.dk
- *
- * $Log: buffers.c,v $
- * Revision 1.1 94/02/20 21:30:22 Torsten
- * Initial revision
- *
- */
-
- static char const RCSid[] = "$Id: buffers.c,v 1.1 94/02/20 21:30:22 Torsten Exp $";
-
- #include "cliptool.h"
- #include "ctstrings.h"
-
- #define ID_FTXT MAKE_ID('F','T','X','T')
- #define ID_CHRS MAKE_ID('C','H','R','S')
-
- struct bufferlisthead *currentbuffer;
- long ntotal, ncurrent;
- static struct bufferlisthead *firstlisthead;
- static struct bufferlisthead *lastlisthead;
-
- static void inserttextbuffer(struct textbuffer *);
- static void disposelistheader(void);
- static void readFTXTclip(struct textbuffer **);
- static void writeFTXTclip(struct textbuffer *);
- static BOOL readTEXTfile(UBYTE *, struct textbuffer **);
- static BOOL readFTXTfile(UBYTE *, struct textbuffer **);
- static BOOL writeTEXTfile(UBYTE *, struct textbuffer *);
- static BOOL writeFTXTfile(UBYTE *, struct textbuffer *);
- static void storetext(struct textbuffer **, UBYTE *, long);
- static void addicon(UBYTE *, BOOL);
-
-
- /*
- * Move to the previous text buffer list.
- */
-
- void prevtext(void)
- {
- if (firstlisthead && firstlisthead != lastlisthead) {
- if (currentbuffer->prev) {
- currentbuffer = currentbuffer->prev;
- ncurrent--;
- }
- else {
- currentbuffer = lastlisthead; /* wrap around */
- ncurrent = ntotal;
- }
- updatetitlebar();
- showtext();
- }
- }
-
-
- /*
- * Move to the next text buffer list.
- */
-
- void nexttext(void)
- {
- if (firstlisthead && firstlisthead != lastlisthead) {
- if (currentbuffer->next) {
- currentbuffer = currentbuffer->next;
- ncurrent++;
- }
- else {
- currentbuffer = firstlisthead; /* wrap around */
- ncurrent = 1;
- }
- updatetitlebar();
- showtext();
- }
- }
-
-
- /*
- * Private function to insert a new text buffer list
- * at the end of the header list.
- */
-
- static void inserttextbuffer(struct textbuffer *tb)
- {
- struct bufferlisthead *newblh;
-
- if (tb) {
- if (newblh = malloc(sizeof(struct bufferlisthead))) {
- newblh->tb = tb;
- newblh->next = NULL;
- newblh->prev = lastlisthead;
- if (lastlisthead) lastlisthead->next = newblh;
- else firstlisthead = newblh;
- currentbuffer = lastlisthead = newblh;
- ncurrent = ++ntotal;
- updatetitlebar();
- }
- }
- }
-
-
- /*
- * Private function to dispose a buffer list header
- * and move the current buffer header one step forward.
- */
-
- static void disposelistheader(void)
- {
- if (currentbuffer) { /* list isn't empty */
- if (currentbuffer == firstlisthead) {
- if (currentbuffer == lastlisthead) {
- free(currentbuffer); /* disposing the only header */
- currentbuffer = firstlisthead = lastlisthead = NULL;
- ncurrent = ntotal = 0;
- }
- else {
- firstlisthead = currentbuffer->next;
- currentbuffer->next->prev = NULL;
- free(currentbuffer); /* disposing first header */
- currentbuffer = firstlisthead;
- ncurrent = 1;
- ntotal--;
- }
- }
- else if (currentbuffer == lastlisthead) {
- lastlisthead = currentbuffer->prev;
- currentbuffer->prev->next = NULL;
- free(currentbuffer); /* disposing the last header */
- currentbuffer = firstlisthead;
- ncurrent = 1;
- ntotal--;
- }
- else {
- struct bufferlisthead *temp = currentbuffer;
-
- currentbuffer = currentbuffer->next;
- temp->prev->next = temp->next;
- temp->next->prev = temp->prev;
- free(temp); /* disposing interior header */
- ntotal--;
- }
- updatetitlebar();
- }
- }
-
-
- /*
- * move the contents of the current buffer to the clipboard.
- */
-
- void cut(void)
- {
- if (currentbuffer) {
- writeFTXTclip(currentbuffer->tb);
- freetext();
- }
- }
-
-
- /*
- * copy the contents of the current buffer to the clipboard.
- */
-
- void copy(void)
- {
- if (currentbuffer)
- writeFTXTclip(currentbuffer->tb);
- }
-
-
- /*
- * Store the contents of the clipboard in the
- * buffer list, and update the display.
- */
-
- void paste(void)
- {
- struct textbuffer *tb = NULL;
-
- readFTXTclip(&tb);
- inserttextbuffer(tb);
- showtext();
- }
-
-
- /*
- * This function removes the current buffer from
- * the list and frees the memory it occupied.
- */
-
- void freetext(void)
- {
- struct textbuffer *tb, *temp;
-
- if (currentbuffer) {
- tb = currentbuffer->tb;
- while (tb) {
- temp = tb->next;
- free(tb);
- tb = temp;
- }
- disposelistheader();
- showtext();
- }
- }
-
-
- /*
- * This is a rather simplistic implementation of storetext().
- * It relies on the fact that SAS/C requests memory from the
- * system pool in relatively large chunks to reduce fragmentation.
- */
-
- static void storetext(struct textbuffer **root, UBYTE *buf, long rlen)
- {
- static struct textbuffer *last;
- struct textbuffer *tb;
-
- if (tb = malloc(sizeof(struct textbuffer) + rlen)) {
- tb->next = NULL;
- tb->length = rlen - 1;
- memcpy(tb->data, buf, rlen);
- if (!*root) *root = tb;
- else last->next = tb;
- last = tb;
- }
- }
-
-
- static void readFTXTclip(struct textbuffer **tbptr)
- {
- struct IFFHandle *iff;
- struct ContextNode *cn;
- long rlen;
- long error = 0;
- UBYTE readbuf[RBUFSZ];
-
- if (iff = AllocIFF()) {
- if (iff->iff_Stream = (ULONG) OpenClipboard(unitnumber)) {
- InitIFFasClip(iff);
- if (!OpenIFF(iff, IFFF_READ)) {
- if (!StopChunk(iff, ID_FTXT, ID_CHRS)) {
- for (;;) {
- if ((error = ParseIFF(iff, IFFPARSE_SCAN)) == IFFERR_EOC)
- continue; /* go to the next context */
- else if (error)
- break;
- cn = CurrentChunk(iff);
- if (cn && cn->cn_Type == ID_FTXT && cn->cn_ID == ID_CHRS) {
- while ((rlen = ReadChunkBytes(iff, readbuf, RBUFSZ)) > 0)
- storetext(tbptr, readbuf, rlen);
- }
- }
- }
- CloseIFF(iff);
- }
- CloseClipboard((struct ClipboardHandle *) iff->iff_Stream);
- }
- FreeIFF(iff);
- }
- }
-
-
- static void writeFTXTclip(struct textbuffer *tb)
- {
- struct IFFHandle *iff;
-
- if (iff = AllocIFF()) {
- if (iff->iff_Stream = (ULONG) OpenClipboard(unitnumber)) {
- InitIFFasClip(iff);
- if (!OpenIFF(iff, IFFF_WRITE)) {
- /* write FORM FTXT */
- if (!PushChunk(iff, ID_FTXT, ID_FORM, IFFSIZE_UNKNOWN)) {
- for (; tb; tb = tb->next) {
- /* write a CHRS chunk... */
- if (!PushChunk(iff, 0, ID_CHRS, tb->length)) {
- /* ...followed by its chunk data */
- if (WriteChunkBytes(iff,tb->data,tb->length) != tb->length)
- break;
- PopChunk(iff);
- }
- }
- PopChunk(iff);
- }
- CloseIFF(iff);
- }
- CloseClipboard((struct ClipboardHandle *) iff->iff_Stream);
- }
- FreeIFF(iff);
- }
- }
-
-
- static BOOL readTEXTfile(UBYTE *fname, struct textbuffer **tbptr)
- {
- long rlen;
- UBYTE readbuf[RBUFSZ];
- BPTR file;
-
- if (file = Open(fname, MODE_OLDFILE)) {
- while ((rlen = Read(file, readbuf, RBUFSZ)) > 0)
- storetext(tbptr, readbuf, rlen);
- Close(file);
- }
- else return FALSE;
- return TRUE;
- }
-
-
- static BOOL readFTXTfile(UBYTE *fname, struct textbuffer **tbptr)
- {
- struct IFFHandle *iff;
- struct ContextNode *cn;
- long rlen;
- long error = 0;
- UBYTE readbuf[RBUFSZ];
-
- if (iff = AllocIFF()) {
- if (iff->iff_Stream = Open(fname, MODE_OLDFILE)) {
- InitIFFasDOS(iff);
- if (!(error = OpenIFF(iff, IFFF_READ))) {
- if (!(error = StopChunk(iff, ID_FTXT, ID_CHRS))) {
- for (;;) {
- if ((error = ParseIFF(iff, IFFPARSE_SCAN)) == IFFERR_EOC)
- continue; /* go to the next context */
- else if (error)
- break;
- cn = CurrentChunk(iff);
- if (cn && cn->cn_Type == ID_FTXT && cn->cn_ID == ID_CHRS) {
- while ((rlen = ReadChunkBytes(iff, readbuf, RBUFSZ)) > 0)
- storetext(tbptr, readbuf, rlen);
- }
- }
- }
- CloseIFF(iff);
- }
- Close(iff->iff_Stream);
- }
- FreeIFF(iff);
- }
- return (BOOL) (error ? FALSE : TRUE);
- }
-
-
- static BOOL writeTEXTfile(UBYTE *fname, struct textbuffer *tb)
- {
- BPTR file;
-
- if (file = Open(fname, MODE_NEWFILE)) {
- for (; tb; tb = tb->next) {
- if (Write(file, tb->data, tb->length) != tb->length)
- break;
- }
- Close(file);
- addicon(fname, FALSE);
- }
- else return FALSE;
- return TRUE;
- }
-
-
- static BOOL writeFTXTfile(UBYTE *fname, struct textbuffer *tb)
- {
- struct IFFHandle *iff;
- long error = 0;
-
- if (iff = AllocIFF()) {
- if (iff->iff_Stream = Open(fname, MODE_NEWFILE)) {
- InitIFFasDOS(iff);
- if (!(error = OpenIFF(iff, IFFF_WRITE))) {
- /* write FORM FTXT */
- if (!(error = PushChunk(iff, ID_FTXT, ID_FORM, IFFSIZE_UNKNOWN))) {
- for (; tb; tb = tb->next) {
- /* write a CHRS chunk... */
- if (!PushChunk(iff, 0, ID_CHRS, tb->length)) {
- /* ...followed by its chunk data */
- if (WriteChunkBytes(iff,tb->data,tb->length) != tb->length) {
- error = IFFERR_WRITE;
- break;
- }
- PopChunk(iff);
- }
- }
- PopChunk(iff);
- }
- CloseIFF(iff);
- }
- Close(iff->iff_Stream);
- }
- FreeIFF(iff);
- addicon(fname, TRUE);
- }
- return (BOOL) (error ? FALSE : TRUE);
- }
-
-
- void loaddropped(UBYTE *fname, BPTR dirlock)
- {
- BPTR curdirlock;
- struct textbuffer *tb = NULL;
- BOOL ok;
-
- curdirlock = CurrentDir(dirlock);
- if (!(ok = readFTXTfile(fname, &tb)))
- ok = readTEXTfile(fname, &tb);
- if (!ok)
- msgreq(ls(MSG_FILE_ACCESS_ERROR), fname);
- else {
- inserttextbuffer(tb);
- showtext();
- }
- CurrentDir(curdirlock);
- }
-
-
- void loadtext(BOOL asFTXT)
- {
- BPTR curdirlock, dirlock;
- struct textbuffer *tb = NULL;
- BOOL ok;
-
- if (AslRequestTags(filereq,
- ASL_Hail, (asFTXT
- ? ls(MSG_LOADFTXT)
- : ls(MSG_LOADTEXT)),
- ASL_FuncFlags, 0,
- ASL_Window, guiwin,
- TAG_END)) {
- if (dirlock = Lock(filereq->rf_Dir, SHARED_LOCK)) {
- curdirlock = CurrentDir(dirlock);
- if (asFTXT) ok = readFTXTfile(filereq->rf_File, &tb);
- else ok = readTEXTfile(filereq->rf_File, &tb);
- if (!ok)
- msgreq(ls(MSG_FILE_ACCESS_ERROR), filereq->rf_File);
- else {
- inserttextbuffer(tb);
- showtext();
- }
- CurrentDir(curdirlock);
- UnLock(dirlock);
- }
- }
- }
-
-
- /*
- * Save the contents of the current buffer list,
- * either as text or FTXT depending on 'asFTXT'.
- */
-
- void savetext(BOOL asFTXT)
- {
- BPTR curdirlock, dirlock;
- BOOL ok;
-
- if (currentbuffer) {
- if (AslRequestTags(filereq,
- ASL_Hail, (asFTXT
- ? ls(MSG_SAVEASFTXT)
- : ls(MSG_SAVEASTEXT)),
- ASL_FuncFlags, FILF_SAVE,
- ASL_Window, guiwin,
- TAG_END)) {
- if (dirlock = Lock(filereq->rf_Dir, SHARED_LOCK)) {
- curdirlock = CurrentDir(dirlock);
- if (asFTXT) ok = writeFTXTfile(filereq->rf_File, currentbuffer->tb);
- else ok = writeTEXTfile(filereq->rf_File, currentbuffer->tb);
- if (!ok)
- msgreq(ls(MSG_FILE_ACCESS_ERROR), filereq->rf_File);
- CurrentDir(curdirlock);
- UnLock(dirlock);
- }
- }
- }
- }
-
-
- /*
- * This function is used by the ARexx interface to load a file.
- * IFF FTXT files are handled transparently.
- */
-
- void rxload(UBYTE *fname, UBYTE *dname)
- {
- BPTR curdirlock, dirlock;
- struct textbuffer *tb = NULL;
-
- if (dirlock = Lock(dname, SHARED_LOCK)) {
- curdirlock = CurrentDir(dirlock);
- if (!readFTXTfile(fname, &tb))
- readTEXTfile(fname, &tb);
- inserttextbuffer(tb);
- showtext();
- CurrentDir(curdirlock);
- UnLock(dirlock);
- }
- }
-
-
- /*
- * This function is used by the ARexx interface to save a file.
- */
-
- void rxsave(UBYTE *fname, UBYTE *dname, BOOL asFTXT)
- {
- BPTR curdirlock, dirlock;
-
- if (currentbuffer) {
- if (dirlock = Lock(dname, SHARED_LOCK)) {
- curdirlock = CurrentDir(dirlock);
- if (asFTXT) writeFTXTfile(fname, currentbuffer->tb);
- else writeTEXTfile(fname, currentbuffer->tb);
- CurrentDir(curdirlock);
- UnLock(dirlock);
- }
- }
- }
-
-
- static void addicon(UBYTE *fname, BOOL ftxt)
- {
- struct DiskObject *diskobj;
-
- synchronizechecked(); /* just in case... */
- if (createicons)
- if (diskobj = GetDefDiskObject(WBPROJECT)) {
- PutDiskObject(fname, diskobj);
- FreeDiskObject(diskobj);
- }
- }
-