home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- * Iteraction library - save/restore bitmaps. *
- * *
- * Written by Gershon Elber, Oct. 1990 *
- *******************************************************************************
- * History: *
- * 3 Oct 90 - Version 1.0 by Gershon Elber. *
- ******************************************************************************/
-
- #include <stdio.h>
- #include <string.h>
- #include <io.h>
- #include <fcntl.h>
- #ifdef __MSDOS__
- #include <sys\stat.h>
- #endif /* __MSDOS__ */
- #include "intr_loc.h"
- #include "intr_gr.h"
- #ifdef __MSDOS__
- #include "intr_ems.h"
- #endif /* __MSDOS__ */
-
- #define MAX_NUM_SAVE_IMAGE 20
- #define MAX_ASYNC_EVENTS (MAX_NUM_SAVE_IMAGE - 5)
-
- typedef struct IntrSaveMemStruct {
- struct IntrSaveMemStruct *Pnext; /* If has more save mem. structs. */
- int Xmin, Ymin, Xmax, Ymax;
- int Handle, LineSize, NumOfLines, LinesPerPage;
- union {
- void *Buffer; /* Pointer to real memory buffer if in real memory. */
- char *FileName; /* Pointer to full path file name if save on disk. */
- #ifdef DJGCC
- void *Region;/* struct GrRegion actually, but hidden by intr_djg.cc. */
- #endif /* DJGCC */
- } U;
- } IntrSaveMemStruct;
-
- /* If _IntrSaveBelow is TRUE, the image below the pop up window is saved and */
- /* restored once done. This requires the usage of temporary memory. */
- /* If _IntrSaveBelow is FALSE, the windows below should be refreshed. This */
- /* is usually slower but no image saving is required. */
- IntrBType _IntrSaveBelow = TRUE;
-
- static IntrSaveMemType
- SaveMemMethod = INTR_SAVE_CONV,
- AllowAsyncEvents = FALSE;
-
- static char
- *TempFileName = "Intr$Tmp.SM1",
- *TempFilePath = NULL;
-
- static int
- NumOfSavedImages = 0;
- static IntrSaveMemStruct
- *SaveMemAllRoots[MAX_NUM_SAVE_IMAGE];
-
- /****************************************************************************
- * Function to control if internal events are to be handled. *
- ****************************************************************************/
- IntrBType _IntrAllowInternalEvent(void)
- {
- if (NumOfSavedImages == 0) return TRUE;
-
- return AllowAsyncEvents && NumOfSavedImages < MAX_ASYNC_EVENTS;
- }
-
- /****************************************************************************
- * Function to control if internal events are to be handled. *
- ****************************************************************************/
- void IntrSetAsyncEventMode(IntrBType AsyncMode)
- {
- AllowAsyncEvents = AsyncMode;
- }
-
- /****************************************************************************
- * Function returns number of pop up items. *
- ****************************************************************************/
- int IntrPopUpActive(void)
- {
- return NumOfSavedImages;
- }
-
- /****************************************************************************
- * Set back saving flag. *
- ****************************************************************************/
- void IntrSetSaveBackGround(IntrBType SaveBackGround)
- {
- if (NumOfSavedImages > 0)
- IntrFatalError("Can not change image save method while image saved.");
-
- _IntrSaveBelow = SaveBackGround;
- }
-
- /****************************************************************************
- * Set back saving method. See IntrSameMemType for methods. *
- ****************************************************************************/
- void IntrSetSaveBackMethod(IntrSaveMemType SaveBackMethod)
- {
- if (NumOfSavedImages > 0)
- IntrFatalError("Can not change image save method while image saved.");
-
- SaveMemMethod = SaveBackMethod;
-
- switch(SaveMemMethod) {
- case INTR_SAVE_CONV:
- break;
- #ifdef __MSDOS__
- case INTR_SAVE_EMS:
- if (!EMSDetected())
- IntrFatalError("EMS driver not detected.");
- break;
- case INTR_SAVE_XMS:
- IntrFatalError("XMS not implemented.");
- break;
- case INTR_SAVE_DISK:
- break;
- #endif /* __MSDOS__ */
- }
- }
-
- /****************************************************************************
- * Set path to save images on disk. Default is current directory. *
- * This path is used to save images if method is INTR_SAVE_DISK. *
- ****************************************************************************/
- void IntrSetSaveBackPath(char *Path)
- {
- if (NumOfSavedImages > 0)
- IntrFatalError("Can not change image save method while image saved.");
-
- if (TempFilePath != NULL) _IntrFree(TempFilePath);
-
- if (Path != NULL)
- TempFilePath = strdup(Path);
- else
- TempFilePath = NULL;
- }
-
-
- /****************************************************************************
- * Saves the content of the image buffer specified by the BBox below. *
- ****************************************************************************/
- void _IntrSaveWindow(int Xmin, int Ymin, int Xmax, int Ymax)
- {
- void *Buffer;
- char Name[80];
- int Handle, y, Page;
- unsigned long Size;
- unsigned int NumOfPages, LinesInOne, YmaxTmp, LineSize;
- IntrSaveMemStruct *SaveMem,
- *SaveMemRoot = NULL,
- *SaveMemTail = NULL;
-
- if (Xmin < 0) Xmin = 0;
- if (Ymin < 0) Ymin = 0;
- if (Xmax > GRScreenMaxX) Xmax = GRScreenMaxX;
- if (Ymax > GRScreenMaxY) Ymax = GRScreenMaxY;
-
- if (NumOfSavedImages >= MAX_NUM_SAVE_IMAGE)
- IntrFatalError("Save image stack overflow.");
-
- #ifdef __MSDOS__
- Size = (unsigned long) GRGetImageBufferSize(Xmin, Ymin, Xmax, Ymax);
- LineSize = GRGetImageBufferSize(Xmin, 0, Xmax, 0);
-
- /* Size is bigger than 64k - find real size. */
- if (Size == 0xffffL)
- Size = (Ymax - Ymin) * ((unsigned long) LineSize);
- #endif /* __MSDOS__ */
-
- switch (SaveMemMethod) {
- default:
- case INTR_SAVE_CONV:
- #ifdef __MSDOS__
- if (Size > 0xffffL) { /* Need to save in parts. */
- LinesInOne = 32767 / LineSize; /* Approx. 32k each time. */
- while (Ymin < Ymax) {
- SaveMem = (IntrSaveMemStruct *)
- _IntrMalloc(sizeof(IntrSaveMemStruct));
- SaveMem -> Pnext = NULL;
- SaveMem -> Xmin = Xmin;
- SaveMem -> Ymin = Ymin;
- SaveMem -> Xmax = Xmax;
- SaveMem -> Ymax = Ymax;
- YmaxTmp = MIN(Ymin + LinesInOne, Ymax);
- SaveMem -> U.Buffer =
- _IntrMalloc(GRGetImageBufferSize(Xmin, Ymin,
- Xmax, YmaxTmp));
- GRGetImageBuffer(Xmin, Ymin, Xmax, YmaxTmp,
- SaveMem -> U.Buffer);
- Ymin = YmaxTmp;
-
- if (SaveMemRoot != NULL) {
- SaveMemTail -> Pnext = SaveMem;
- SaveMemTail = SaveMem;
- }
- else {
- SaveMemRoot = SaveMemTail = SaveMem;
- }
- }
- }
- else
- #endif /* __MSDOS__ */
- {
- SaveMemRoot = (IntrSaveMemStruct *)
- _IntrMalloc(sizeof(IntrSaveMemStruct));
- SaveMemRoot -> Pnext = NULL;
- SaveMemRoot -> Xmin = Xmin;
- SaveMemRoot -> Ymin = Ymin;
- SaveMemRoot -> Xmax = Xmax;
- SaveMemRoot -> Ymax = Ymax;
- #ifdef __MSDOS__
- SaveMemRoot -> U.Buffer = _IntrMalloc((unsigned int) Size);
- GRGetImageBuffer(Xmin, Ymin, Xmax, Ymax,
- SaveMemRoot -> U.Buffer);
- #endif /* __MSDOS__ */
- #ifdef DJGCC
- SaveMemRoot -> U.Region = GRGetImageBuffer(Xmin, Ymin,
- Xmax, Ymax);
- #endif /* DJGCC */
- }
- break;
- #ifdef __MSDOS__
- case INTR_SAVE_EMS:
- LinesInOne = 15000 / LineSize; /* Approx. 15k in page. */
- NumOfPages = (Ymax - Ymin + 1) / LinesInOne + 1;
- if (NumOfPages > 1)
- printf("");
- SaveMemRoot = (IntrSaveMemStruct *)
- _IntrMalloc(sizeof(IntrSaveMemStruct));
- if ((SaveMemRoot -> Handle = EMSAlloc(NumOfPages)) == 0)
- IntrFatalError("Fail to EMS allocate.");
- SaveMemRoot -> Pnext = NULL;
- SaveMemRoot -> Xmin = Xmin;
- SaveMemRoot -> Ymin = Ymin;
- SaveMemRoot -> Xmax = Xmax;
- SaveMemRoot -> Ymax = Ymax;
- SaveMemRoot -> LineSize = LineSize;
- SaveMemRoot -> NumOfLines = Ymax - Ymin + 1;
- SaveMemRoot -> LinesPerPage = LinesInOne;
-
- Page = 0;
- while (Ymin < Ymax) {
- if ((Buffer = EMSMap(SaveMemRoot -> Handle, Page++, 0)) == NULL)
- IntrFatalError("Fail to EMS Map.");
- YmaxTmp = MIN(Ymin + LinesInOne - 1, Ymax);
- GRGetImageBuffer(Xmin, Ymin, Xmax, YmaxTmp, Buffer);
- Ymin += LinesInOne;
- }
- break;
- case INTR_SAVE_XMS:
- break;
- case INTR_SAVE_DISK:
- /* Save into disk one line at a time. */
- if (TempFilePath != NULL)
- strcpy(Name, TempFilePath);
- else
- Name[0] = 0;
- strcat(Name, TempFileName);
- Name[strlen(Name) - 1] = 'A' + NumOfSavedImages;
- if ((Handle = open(Name,
- O_RDWR | O_CREAT | O_BINARY,
- S_IREAD | S_IWRITE)) < 0)
- IntrFatalError("Fail to open image disk file.");
-
- Buffer = _IntrMalloc(LineSize);
- SaveMemRoot = (IntrSaveMemStruct *)
- _IntrMalloc(sizeof(IntrSaveMemStruct));
- SaveMemRoot -> Pnext = NULL;
- SaveMemRoot -> Xmin = Xmin;
- SaveMemRoot -> Ymin = Ymin;
- SaveMemRoot -> Xmax = Xmax;
- SaveMemRoot -> Ymax = Ymax;
- SaveMemRoot -> LineSize = LineSize;
- SaveMemRoot -> NumOfLines = Ymax - Ymin + 1;
- SaveMemRoot -> U.FileName = strdup(Name);
- for (y = Ymin; y <= Ymax; y++) {
- GRGetImageBuffer(Xmin, y, Xmax, y, Buffer);
- write(Handle, Buffer, LineSize);
- }
- _IntrFree(Buffer);
- close(Handle);
- break;
- #endif /* __MSDOS__ */
- }
-
- SaveMemAllRoots[NumOfSavedImages++] = SaveMemRoot;
- }
-
- /****************************************************************************
- * Free all saved images in case of async. exit. *
- ****************************************************************************/
- void _IntrRestoreAll(void)
- {
- while (NumOfSavedImages > 0) _IntrRestoreWindow();
- }
-
- /****************************************************************************
- * Restores the content of the image buffer specified by SaveMemRoot. *
- ****************************************************************************/
- void _IntrRestoreWindow(void)
- {
- int Handle, y, LinesPerPage, Page;
- void *Buffer;
- IntrSaveMemStruct *SaveMem, *SaveMemRoot;
-
- if (NumOfSavedImages <= 0)
- IntrFatalError("Save image stack underflow.");
- SaveMemRoot = SaveMemAllRoots[--NumOfSavedImages];
-
- switch (SaveMemMethod) {
- default:
- case INTR_SAVE_CONV:
- while (SaveMemRoot != NULL) {
- SaveMem = SaveMemRoot;
- SaveMemRoot = SaveMemRoot -> Pnext;
- #ifdef __MSDOS__
- GRPutImageBuffer(SaveMem -> Xmin, SaveMem -> Ymin,
- SaveMem -> U.Buffer);
- _IntrFree(SaveMem -> U.Buffer);
- #endif /* __MSDOS__ */
- #ifdef DJGCC
- GRPutImageBuffer(SaveMem -> Xmin, SaveMem -> Ymin,
- SaveMem -> U.Region);
- #endif /* DJGCC */
- _IntrFree(SaveMem);
- }
- break;
- #ifdef __MSDOS__
- case INTR_SAVE_EMS:
- y = SaveMemRoot -> Ymin;
- LinesPerPage = SaveMemRoot -> LinesPerPage;
-
- Page = 0;
- while (y < SaveMemRoot -> Ymax) {
- if ((Buffer = EMSMap(SaveMemRoot -> Handle, Page++, 0)) == NULL)
- IntrFatalError("Fail to EMS Map.");
- GRPutImageBuffer(SaveMemRoot -> Xmin, y, Buffer);
- y += LinesPerPage;
- }
- EMSFree(SaveMemRoot -> Handle);
- _IntrFree(SaveMemRoot);
- break;
- case INTR_SAVE_XMS:
- break;
- case INTR_SAVE_DISK:
- /* Read from disk one line at a time. */
- Buffer = _IntrMalloc(SaveMemRoot -> LineSize);
- if ((Handle = open(SaveMemRoot -> U.FileName,
- O_RDONLY | O_BINARY,
- S_IREAD)) < 0)
- IntrFatalError("Fail to open image disk file.");
-
- for (y = SaveMemRoot -> Ymin; y <= SaveMemRoot -> Ymax; y++) {
- read(Handle, Buffer, SaveMemRoot -> LineSize);
- GRPutImageBuffer(SaveMemRoot -> Xmin, y, Buffer);
- }
- _IntrFree(Buffer);
- close(Handle);
- unlink(SaveMemRoot -> U.FileName); /* Delete the file. */
- _IntrFree(SaveMemRoot -> U.FileName);
- _IntrFree(SaveMemRoot);
- break;
- #endif /* __MSDOS__ */
- }
- }
-