home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- * Iteraction library - text windows. *
- * *
- * Written by Gershon Elber, Oct. 1990 *
- *******************************************************************************
- * Implements a text printf for graphics windows. *
- *******************************************************************************
- * History: *
- * 29 Oct 90 - Version 1.0 by Gershon Elber. *
- ******************************************************************************/
-
- #include <stdio.h>
- #include <string.h>
- #include <stdarg.h>
- #include <ctype.h>
- #ifdef __MSDOS__
- #include <mem.h>
- #endif /* __MSDOS__ */
- #include "intr_loc.h"
- #include "intr_gr.h"
-
- static IntrBType SmoothScroll = FALSE;
- static IntrBType WasAPrintf = FALSE;
-
- static void ScrollAndPrint(_IntrWindowStruct *Window);
-
- /******************************************************************************
- * Select a window and initialize it to text drawing. *
- ******************************************************************************/
- void IntrTextInitWindow(int WindowID,
- IntrBType ReadBottomLine,
- IntrColorType TextColor,
- IntrColorType BottomLineColor,
- IntrScrlBarType HScrlBar,
- IntrScrlBarType VScrlBar,
- int NumOfLines,
- int LineLen)
- {
- _IntrWindowStruct
- *Window = _IntrFindWndwUsingID(WindowID);
-
- if (Window -> WindowType == INTR_WNDW_TEXT) {
- _IntrFree(Window -> TextInfo -> TextData); /* Delete old data. */
- }
- else
- Window -> TextInfo = (_IntrWndwTextStruct *)
- _IntrMalloc(sizeof(_IntrWndwTextStruct));
-
- Window -> TextInfo -> TextData = (char *) _IntrMalloc(NumOfLines * ++LineLen);
- Window -> TextInfo -> ReadBottomLine = ReadBottomLine;
- Window -> TextInfo -> TextColor = TextColor;
- Window -> TextInfo -> BottomLineColor = BottomLineColor;
- Window -> TextInfo -> NumOfLines = NumOfLines;
- Window -> TextInfo -> LineLen = LineLen;
- Window -> TextInfo -> LinesInBuffer = 0;
- Window -> TextInfo -> FirstDisplayed = 0;
-
- Window -> HScrlBar = HScrlBar;
- Window -> VScrlBar = VScrlBar;
- Window -> HScrlBarColor = Window -> VScrlBarColor = TextColor;
- Window -> WindowType = INTR_WNDW_TEXT;
- }
-
- /******************************************************************************
- * Free TextInfo structure. *
- ******************************************************************************/
- void _IntrTextWndwDelete(_IntrWndwTextStruct *TextInfo)
- {
- _IntrFree(TextInfo -> TextData);
- _IntrFree(TextInfo);
- }
-
- /******************************************************************************
- * Set smooth scrolling for text windows. *
- ******************************************************************************/
- void IntrTextSetSmoothScroll(IntrBType SmoothScrolling)
- {
- SmoothScroll = SmoothScrolling;
- }
-
- /******************************************************************************
- * Draw all text defined for this window. *
- * It is assumed the window is all visible and cleared. *
- ******************************************************************************/
- void IntrTextWndwRefresh(int WindowID)
- {
- IntrRType RelativePosition, DisplayedFraction;
- _IntrWindowStruct
- *Window = _IntrFindWndwUsingID(WindowID);
- int i, j, NumOfDisplayedLines, FirstLine,
- LineLen = Window -> TextInfo -> LineLen,
- LinesInBuffer = Window -> TextInfo -> LinesInBuffer;
- char
- *TextData = Window -> TextInfo -> TextData;
- IntrBType
- LocalWasAPrintf = WasAPrintf;
- _IntrWndwTextStruct
- *TextInfo = Window -> TextInfo;
-
- WasAPrintf = FALSE;
-
- GRPushViewPort();
- GRPushTextSetting();
- GRSetTextJustify(GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_TOP);
- GRSetSTextStyle(GR_FONT_DEFAULT, GR_HORIZ_DIR, GR_TEXT_MAG_1);
-
- NumOfDisplayedLines = (Window -> BBox.Ymax - Window -> BBox.Ymin -
- (TEXT_BORDER << 1)) / TEXT_BASE_LINE - 2;
- if (TextInfo -> ReadBottomLine) NumOfDisplayedLines--;
- if (NumOfDisplayedLines < 0) NumOfDisplayedLines = 0;
-
- _GRSetViewPort(Window -> BBox.Xmin + TEXT_BORDER,
- Window -> BBox.Ymin + TEXT_BORDER,
- Window -> BBox.Xmax - TEXT_BORDER,
- Window -> BBox.Ymax - TEXT_BORDER);
-
- IntrAllocColor(TextInfo -> TextColor, INTR_INTENSITY_VHIGH);
- if (LinesInBuffer > NumOfDisplayedLines) {
- DisplayedFraction = ((IntrRType) NumOfDisplayedLines) / LinesInBuffer;
- if (LocalWasAPrintf) {
- RelativePosition = 1.0 - DisplayedFraction;
- for (i = 0; i <= NumOfDisplayedLines; i++)
- GRSText(0, i * TEXT_BASE_LINE,
- &TextData[LineLen * (NumOfDisplayedLines - i)]);
- TextInfo -> FirstDisplayed = 0; /* Allow smooth scroll. */
- }
- else {
- if (Window -> VScrlBar != INTR_SCRLBAR_NONE &&
- _IntrAsyncLastEvent.AsyncEvent == ASYNC_EVNT_VSCRLBAR) {
- RelativePosition = _IntrAsyncLastEvent.R;
- if (RelativePosition > 1.0 - DisplayedFraction)
- RelativePosition = 1.0 - DisplayedFraction;
- }
- else {
- RelativePosition = 1.0 - DisplayedFraction;
- }
- j = ((int) ((1.0 - DisplayedFraction - RelativePosition) *
- LinesInBuffer));
- for (i = 0; i <= NumOfDisplayedLines; i++) {
- if (NumOfDisplayedLines - i + j < TextInfo -> LinesInBuffer)
- GRSText(0, i * TEXT_BASE_LINE,
- &TextData[LineLen * (NumOfDisplayedLines - i + j)]);
- }
- TextInfo -> FirstDisplayed = j;
- }
- }
- else {
- RelativePosition = 0.0;
- DisplayedFraction = 1.0;
- FirstLine = NumOfDisplayedLines - LinesInBuffer;
- for (i = 1; i <= LinesInBuffer; i++)
- GRSText(0, (FirstLine + i) * TEXT_BASE_LINE,
- &TextData[LineLen * (LinesInBuffer - i)]);
- TextInfo -> FirstDisplayed = 0; /* Allow smooth scroll. */
- }
-
- switch (Window -> VScrlBar) {
- case INTR_SCRLBAR_LEFT:
- IntrWndwUpdateScrollBar(WindowID, TRUE,
- RelativePosition, DisplayedFraction);
- break;
- case INTR_SCRLBAR_RIGHT:
- IntrWndwUpdateScrollBar(WindowID, TRUE,
- RelativePosition, DisplayedFraction);
- break;
- }
-
- IntrPushKbdEvent(KEY_REFRESH);
-
- GRPopTextSetting();
- GRPopViewPort();
- }
-
- /******************************************************************************
- * Scroll one line and print the new line on the bottom. *
- ******************************************************************************/
- static void ScrollAndPrint(_IntrWindowStruct *Window)
- {
- int i, Xmax, Ymax;
- IntrRType RelativePosition, DisplayedFraction;
- VoidPtr LineBuffer;
- _IntrWndwTextStruct
- *TextInfo = Window -> TextInfo;
-
- TextInfo -> NumOfDisplayedLines = (Window -> BBox.Ymax -
- Window -> BBox.Ymin - (TEXT_BORDER << 1)) / TEXT_BASE_LINE - 2;
- if (TextInfo -> ReadBottomLine)
- TextInfo -> NumOfDisplayedLines--;
- if (TextInfo -> NumOfDisplayedLines < 0)
- TextInfo -> NumOfDisplayedLines = 0;
-
- if (IntrWndwIsAllVisible(Window -> WindowID)) {
- GRPushViewPort();
- _GRSetViewPort(0, 0, GRScreenMaxX, GRScreenMaxY);
- GRPushTextSetting();
- GRSetTextJustify(GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_TOP);
- GRSetSTextStyle(GR_FONT_DEFAULT, GR_HORIZ_DIR, GR_TEXT_MAG_1);
-
- if (SmoothScroll && TextInfo -> FirstDisplayed == 0) {
- IntrAllocColor(TextInfo -> TextColor, INTR_INTENSITY_VHIGH);
-
- #ifdef __MSDOS__
- LineBuffer = _IntrMalloc(GRGetImageBufferSize(Window -> BBox.Xmin, 0,
- Window -> BBox.Xmax, 0));
- #endif /* __MSDOS__ */
- _GRSetViewPort(Window -> BBox.Xmin + TEXT_BORDER,
- Window -> BBox.Ymin + TEXT_BORDER,
- Window -> BBox.Xmax - TEXT_BORDER,
- Window -> BBox.Ymax - TEXT_BORDER);
-
- /* Scroll full base line. */
- Xmax = Window -> BBox.Xmax - Window -> BBox.Xmin - (TEXT_BORDER << 1);
- Ymax = Window -> BBox.Ymax - Window -> BBox.Ymin - (TEXT_BORDER << 1);
- for (i = TEXT_BASE_LINE; i <= Ymax; i++) {
- #ifdef __MSDOS__
- GRGetImageBuffer(0, i, Xmax, i, LineBuffer);
- GRPutImageBuffer(0, i - TEXT_BASE_LINE, LineBuffer);
- #endif /* __MSDOS__ */
- #ifdef DJGCC
- GRPutImageBuffer(0, i - TEXT_BASE_LINE,
- GRGetImageBuffer(0, i, Xmax, i));
- #endif /* DJGCC */
- }
-
- #ifdef __MSDOS__
- _IntrFree(LineBuffer);
- #endif /* __MSDOS__ */
-
- /* Clear old bottom string and print new one. */
- IntrAllocColor(Window -> BackColor, INTR_INTENSITY_HIGH);
- GRSBar(0, TextInfo -> NumOfDisplayedLines * TEXT_BASE_LINE,
- Xmax, TextInfo -> NumOfDisplayedLines * TEXT_BASE_LINE + 8);
- IntrAllocColor(TextInfo -> TextColor, INTR_INTENSITY_VHIGH);
- GRSText(0, TextInfo -> NumOfDisplayedLines * TEXT_BASE_LINE,
- &TextInfo -> TextData[0]);
-
- if (TextInfo -> LinesInBuffer > TextInfo -> NumOfDisplayedLines) {
- RelativePosition =
- 1.0 - ((IntrRType) TextInfo -> NumOfDisplayedLines) /
- TextInfo -> LinesInBuffer;
- DisplayedFraction = 1.0 - RelativePosition;
- }
- else {
- RelativePosition = 0.0;
- DisplayedFraction = 1.0;
- }
-
- switch (Window -> VScrlBar) {
- case INTR_SCRLBAR_LEFT:
- IntrWndwUpdateScrollBar(Window -> WindowID, TRUE,
- RelativePosition, DisplayedFraction);
- break;
- case INTR_SCRLBAR_RIGHT:
- IntrWndwUpdateScrollBar(Window -> WindowID, TRUE,
- RelativePosition, DisplayedFraction);
- break;
- }
- }
- else { /* No smooth scrolling. */
- TextInfo -> FirstDisplayed = 0;
-
- IntrAllocColor(Window -> BackColor, INTR_INTENSITY_HIGH);
- GRSBar(Window -> BBox.Xmin, Window -> BBox.Ymin,
- Window -> BBox.Xmax, Window -> BBox.Ymax);
- WasAPrintf = TRUE;
- IntrTextWndwRefresh(Window -> WindowID);
- }
-
- GRPopViewPort();
- GRPopTextSetting();
- }
- else {
- /* Need to pop up the window which probably will refresh all text. */
- IntrWndwPop(Window -> WindowID, TRUE, FALSE);
- }
- }
-
- /******************************************************************************
- * Printf to the specified window. *
- ******************************************************************************/
- void IntrPrintf(int WindowID, IntrBType UpdateWindow, char *CtrlStr, ...)
- {
- va_list ArgPtr;
- _IntrWindowStruct
- *Window = _IntrFindWndwUsingID(WindowID);
- _IntrWndwTextStruct
- *TextInfo = Window -> TextInfo;
- int i,j,
- BufferSize = (Window -> TextInfo -> NumOfLines - 1) *
- (Window -> TextInfo -> LineLen);
- char Line[256], *p,
- *TempBuffer = _IntrMalloc(BufferSize);
-
- if (Window -> WindowType != INTR_WNDW_TEXT)
- IntrFatalError("Window is not initialized to support text.");
-
- /* Move all lines one place up. Since both source and destination share */
- /* the same space we do it in two spaces. */
- GEN_COPY(TempBuffer,
- &Window -> TextInfo -> TextData[0],
- BufferSize);
- GEN_COPY(&Window -> TextInfo -> TextData[Window -> TextInfo -> LineLen],
- TempBuffer,
- BufferSize);
- _IntrFree(TempBuffer);
-
- va_start(ArgPtr, CtrlStr);
- vsprintf(Line, CtrlStr, ArgPtr);
- va_end(ArgPtr);
-
- p = TextInfo -> TextData;
- for (i = j = 0; i < TextInfo -> LineLen - 1 && Line[j]; j++) {
- if (iscntrl(Line[j])) {
- if (Line[j] == 9) { /* It is a tab. */
- do p[i++] = ' ';
- while (i < TextInfo -> LineLen && (i & 0x07) != 0);
- }
- }
- else
- p[i++] = Line[j];
- }
- p[i] = 0;
-
- if (++TextInfo -> LinesInBuffer > TextInfo -> NumOfLines)
- TextInfo -> LinesInBuffer = TextInfo -> NumOfLines;
-
- if (UpdateWindow)
- ScrollAndPrint(Window);
- else
- TextInfo -> FirstDisplayed = -1; /* Enforce full window refresh. */
- }
-
- /******************************************************************************
- * Read a line input at a bottom of a given window into buffer. *
- ******************************************************************************/
- void IntrGetLineWindow(int WindowID, char *Buffer, int BufferLen)
- {
- int GRLastColor = GRGetColor();
- _IntrWindowStruct
- *Window = _IntrFindWndwUsingID(WindowID);
- _IntrWndwTextStruct
- *TextInfo = Window -> TextInfo;
- int WindowLen = (Window -> BBox.Xmax - Window -> BBox.Xmin -
- (TEXT_BORDER << 1)) / GRGetTextWidth("M");
-
- GRPushViewPort();
- _GRSetViewPort(Window -> BBox.Xmin, Window -> BBox.Ymin,
- Window -> BBox.Xmax, Window -> BBox.Ymax);
-
- GRGetGraphicLine(WindowID, TEXT_BORDER << 1,
- Window -> BBox.Ymax - Window -> BBox.Ymin -
- TEXT_BORDER - GRGetTextHeight("M"),
- Buffer, BufferLen, WindowLen,
- IntrAllocColor(TextInfo -> TextColor, INTR_INTENSITY_VHIGH),
- IntrAllocColor(Window -> BackColor, INTR_INTENSITY_HIGH));
-
- GRSetColor(GRLastColor);
- GRPopViewPort();
- }
-