diff options
Diffstat (limited to 'gnu/games/chess/Xchess/scrollText')
-rw-r--r-- | gnu/games/chess/Xchess/scrollText/scrollText.c | 1858 | ||||
-rw-r--r-- | gnu/games/chess/Xchess/scrollText/scrollText.h | 32 |
2 files changed, 0 insertions, 1890 deletions
diff --git a/gnu/games/chess/Xchess/scrollText/scrollText.c b/gnu/games/chess/Xchess/scrollText/scrollText.c deleted file mode 100644 index aefb5999b2fd..000000000000 --- a/gnu/games/chess/Xchess/scrollText/scrollText.c +++ /dev/null @@ -1,1858 +0,0 @@ -/* - * A Scrollable Text Output Window - * - * David Harrison - * University of California, Berkeley - * 1986 - * - * The following is an implementation for a scrollable text output - * system. It handles exposure events only (other interactions are - * under user control). For scrolling, a always present scroll bar - * is implemented. It detects size changes and compensates accordingly. - */ - -#include <X11/X.h> -#include <X11/Xlib.h> -#include <X11/X10.h> -#include <sys/types.h> -#include "scrollText.h" - -extern char *malloc(); -extern char *realloc(); -#define alloc(type) (type *) malloc(sizeof(type)) -#define numalloc(type, num) (type *) malloc((unsigned) (num * sizeof(type))) -#define MAXINT 2147483647 - -extern XAssocTable *XCreateAssocTable(); -extern caddr_t XLookUpAssoc(); - -static XAssocTable *textWindows = (XAssocTable *) 0; - -#define NOOPTION -1 /* Option hasn't been set yet */ -#define NORMSCROLL 0 /* Smooth scroll on LineToTop and TopToHere */ -#define JUMPSCROLL 1 /* Jump scrolling on LineToTop and TopToHere */ - -static int ScrollOption = NOOPTION; - -typedef char *Generic; - -#define DEFAULT_GC textInfo->fontGC[textInfo->curFont] - -#define BARSIZE 15 -#define BARBORDER 1 -#define MAXFONTS 8 -#define INITBUFSIZE 1024 -#define INITLINES 50 -#define INITEXPARY 50 -#define XPADDING 2 -#define YPADDING 2 -#define INTERLINE 5 -#define INTERSPACE 1 -#define CURSORWIDTH 2 -#define EXPANDPERCENT 40 -#define BUFSIZE 1024 -#define CUROFFSET 1 -#define MAXFOREIGN 250 -#define NOINDEX -1 - -/* The wrap line indicator */ -#define WRAPINDSIZE 7 -#define STEMOFFSET 5 -#define arrow_width 7 -#define arrow_height 5 -static char arrow_bits[] = { - 0x24, 0x26, 0x3f, 0x06, 0x04}; - -#define NEWLINE '\n' -#define BACKSPACE '\010' -#define NEWFONT '\006' -#define LOWCHAR '\040' -#define HIGHCHAR '\176' - -#define CHARMASK 0x00ff /* Character mask */ -#define FONTMASK 0x0700 /* Character font */ -#define FONTSHIFT 8 /* Shift amount */ - -#define WRAPFLAG 0x01 /* Line wrap flag */ - -/* - * Lines are represented by a pointer into the overall array of - * 16-bit characters. The lower eight bits is used to indicate the character - * (in ASCII), and the next two bits are used to indicate the font - * the character should be drawn in. - */ - -typedef struct txtLine { - int lineLength; /* Current line length */ - int lineHeight; /* Full height of line in pixels */ - int lineBaseLine; /* Current baseline of the line */ - int lineWidth; /* Drawing position at end of line */ - int lineText; /* Offset into master buffer */ - int lineFlags; /* Line wrap flag is here */ -}; - - -/* - * For ExposeCopy events, we queue up the redraw requests collapsing - * them into line redraw requests until the CopyExpose event arrives. - * The queue is represented as a dynamic array of the following - * structure: - */ - -typedef struct expEvent { - int lineIndex; /* Index of line to redraw */ - int ypos; /* Drawing position of line */ -}; - - -/* - * The text buffer is represented using a dynamic counted array - * of 16-bit quantities. This array expands as needed. - * For the screen representation, a dynamic counted array - * of line structures is used. This array points into the - * text buffer to denote the start of each line and its parameters. - * The windows are configured as one overall window which contains - * the scroll bar as a sub-window along its right edge. Thus, - * the text drawing space is actually w-BARSIZE. - */ - -#define NOTATBOTTOM 0x01 /* Need to scroll to bottom before appending */ -#define FONTNUMWAIT 0x02 /* Waiting for font number */ -#define COPYEXPOSE 0x04 /* Need to process a copy expose event */ -#define SCREENWRONG 0x08 /* TxtJamStr has invalidated screen contents */ - -typedef struct txtWin { - /* Basic text buffer */ - int bufAlloc; /* Allocated size of buffer */ - int bufSpot; /* Current writing position in buffer */ - short *mainBuffer; /* Main buffer of text */ - - /* Line information */ - int numLines; /* Number of display lines in buffer */ - int allocLines; /* Number of lines allocated */ - struct txtLine **txtBuffer; /* Dynamic array of lines */ - - /* Current Window display information */ - Window mainWindow; /* Text display window */ - Window scrollBar; /* Subwindow for scroll bar */ - Pixmap arrowMap; /* line wrap indicator */ - int bgPix, fgPix; /* Background and cursor */ - GC CursorGC; /* gc for the cursor */ - GC bgGC; /* gc for erasing things */ - GC fontGC[MAXFONTS]; /* gc for doing fonts */ - XFontStruct theFonts[MAXFONTS];/* Display fonts */ - int theColors[MAXFONTS]; /* foregrounds of the fonts */ - int curFont; /* current font for tracking */ - int w, h; /* Current size */ - int startLine; /* Top line in display */ - int endLine; /* Bottom line in display */ - int bottomSpace; /* Space at bottom of screen */ - int flagWord; /* If non-zero, not at end */ - - /* For handling ExposeCopy events */ - int exposeSize; /* Current size of array */ - int exposeAlloc; /* Allocated size */ - struct expEvent **exposeAry;/* Array of line indices */ - - /* Drawing position information */ - int curLine; /* Current line in buffer */ - int curX; /* Current horizontal positi */ - int curY; /* Current vertical drawing */ -}; - -/* Flags for the various basic character handling functions */ - -#define DODISP 0x01 /* Update the display */ -#define NONEWLINE 0x02 /* Dont append newline */ - - - -static int InitLine(newLine) -struct txtLine *newLine; /* Newly created line structure */ -/* - * This routine initializes a newly created line structure. - */ -{ - newLine->lineLength = 0; - newLine->lineHeight = 0; - newLine->lineBaseLine = 0; - newLine->lineWidth = XPADDING; - newLine->lineText = NOINDEX; - newLine->lineFlags = 0; - return 1; -} - - - - -int TxtGrab(display, txtWin, program, mainFont, bg, fg, cur) -Display *display; /* display window is on */ -Window txtWin; /* Window to take over as scrollable text */ -char *program; /* Program name for Xdefaults */ -XFontStruct *mainFont; /* Primary text font */ -int bg, fg, cur; /* Background, foreground, and cursor colors */ -/* - * This routine takes control of 'txtWin' and makes it into a scrollable - * text output window. It will create a sub-window for the scroll bar - * with a background of 'bg' and an bar with color 'fg'. Both fixed width - * and variable width fonts are supported. Additional fonts can be loaded - * using 'TxtAddFont'. Returns 0 if there were problems, non-zero if - * everything went ok. - */ -{ - struct txtWin *newWin; /* Text package specific information */ - XWindowAttributes winInfo; /* Window information */ - int index; - XGCValues gc_val; - - if (textWindows == (XAssocTable *) 0) { - textWindows = XCreateAssocTable(32); - if (textWindows == (XAssocTable *) 0) return(0); - } - if (XGetWindowAttributes(display, txtWin, &winInfo) == 0) return 0; - - if (ScrollOption == NOOPTION) { - /* Read to see if the user wants jump scrolling or not */ - if (XGetDefault(display, program, "JumpScroll")) { - ScrollOption = JUMPSCROLL; - } else { - ScrollOption = NORMSCROLL; - } - } - - /* Initialize local structure */ - newWin = alloc(struct txtWin); - - /* Initialize arrow pixmap */ - newWin->arrowMap = XCreatePixmapFromBitmapData(display, txtWin, - arrow_bits, - arrow_width, arrow_height, - cur, bg, - DisplayPlanes(display, 0)); - - newWin->bufAlloc = INITBUFSIZE; - newWin->bufSpot = 0; - newWin->mainBuffer = numalloc(short, INITBUFSIZE); - - newWin->numLines = 1; - newWin->allocLines = INITLINES; - newWin->txtBuffer = numalloc(struct txtLine *, INITLINES); - for (index = 0; index < INITLINES; index++) { - newWin->txtBuffer[index] = alloc(struct txtLine); - InitLine(newWin->txtBuffer[index]); - } - - /* Window display information */ - newWin->mainWindow = txtWin; - newWin->w = winInfo.width; - newWin->h = winInfo.height; - newWin->startLine = 0; - newWin->endLine = 0; - newWin->bottomSpace = winInfo.height - - YPADDING - mainFont->ascent - mainFont->descent - INTERLINE; - newWin->flagWord = 0; - newWin->bgPix = bg; - newWin->fgPix = fg; - - /* Scroll Bar Creation */ - newWin->scrollBar = XCreateSimpleWindow(display, txtWin, - winInfo.width - BARSIZE, - 0, BARSIZE - (2*BARBORDER), - winInfo.height - (2*BARBORDER), - BARBORDER, - fg, bg); - XSelectInput(display, newWin->scrollBar, ExposureMask|ButtonReleaseMask); - XMapRaised(display, newWin->scrollBar); - - /* Font and Color Initialization */ - newWin->theFonts[0] = *mainFont; - newWin->theColors[0] = fg; - gc_val.function = GXcopy; - gc_val.plane_mask = AllPlanes; - gc_val.foreground = fg; - gc_val.background = bg; - gc_val.graphics_exposures = 1; - gc_val.font = mainFont->fid; - gc_val.line_width = 1; - gc_val.line_style = LineSolid; - - newWin->fontGC[0] = XCreateGC(display, txtWin, - GCFunction | GCPlaneMask | - GCForeground | GCBackground | - GCGraphicsExposures | GCFont, - &gc_val); - - gc_val.foreground = cur; - newWin->CursorGC = XCreateGC(display, txtWin, - GCFunction | GCPlaneMask | - GCForeground | GCBackground | - GCLineStyle | GCLineWidth, - &gc_val); - - gc_val.foreground = bg; - newWin->bgGC = XCreateGC(display, txtWin, - GCFunction | GCPlaneMask | - GCForeground | GCBackground | - GCGraphicsExposures | GCFont, - &gc_val); - - - for (index = 1; index < MAXFONTS; index++) { - newWin->theFonts[index].fid = 0; - newWin->fontGC[index] = 0; - } - - - /* Initialize size of first line */ - newWin->txtBuffer[0]->lineHeight = newWin->theFonts[0].ascent + - newWin->theFonts[0].descent; - newWin->txtBuffer[0]->lineText = 0; - - /* ExposeCopy array initialization */ - newWin->exposeSize = 0; - newWin->exposeAlloc = INITEXPARY; - newWin->exposeAry = numalloc(struct expEvent *, INITEXPARY); - for (index = 0; index < newWin->exposeAlloc; index++) - newWin->exposeAry[index] = alloc(struct expEvent); - /* Put plus infinity in last slot for sorting purposes */ - newWin->exposeAry[0]->lineIndex = MAXINT; - - /* Drawing Position Information */ - newWin->curLine = 0; - newWin->curX = 0; - newWin->curY = YPADDING + mainFont->ascent + mainFont->descent; - - /* Attach it to both windows */ - XMakeAssoc(display, textWindows, (XID) txtWin, (caddr_t) newWin); - XMakeAssoc(display, textWindows, (XID) newWin->scrollBar, (caddr_t) newWin); - return 1; -} - - -int TxtRelease(display, w) -Display *display; -Window w; /* Window to release */ -/* - * This routine releases all resources associated with the - * specified window which are consumed by the text - * window package. This includes the entire text buffer, line start - * array, and the scroll bar window. However, the window - * itself is NOT destroyed. The routine will return zero if - * the window is not owned by the text window package. - */ -{ - struct txtWin *textInfo; - int index; - - if ((textInfo = (struct txtWin *) XLookUpAssoc(display, - textWindows, (XID) w)) == 0) - return 0; - - for (index = 0; index < MAXFONTS; index++) - if (textInfo->fontGC[index] != 0) - XFreeGC(display, textInfo->fontGC[index]); - - free((Generic) textInfo->mainBuffer); - for (index = 0; index < textInfo->numLines; index++) { - free((Generic) textInfo->txtBuffer[index]); - } - free((Generic) textInfo->txtBuffer); - XDestroyWindow(display, textInfo->scrollBar); - for (index = 0; index < textInfo->exposeSize; index++) { - free((Generic) textInfo->exposeAry[index]); - } - free((Generic) textInfo->exposeAry); - XDeleteAssoc(display, textWindows, (XID) w); - free((Generic) textInfo); - return 1; -} - - - -static int RecompBuffer(textInfo) -struct txtWin *textInfo; /* Text window information */ -/* - * This routine recomputes all line breaks in a buffer after - * a change in window size or font. This is done by throwing - * away the old line start array and recomputing it. Although - * a lot of this work is also done elsewhere, it has been included - * inline here for efficiency. - */ -{ - int startPos, endSize, linenum; - register int index, chsize, curfont; - register short *bufptr; - register XFontStruct *fontptr; - register struct txtLine *lineptr; - char theChar; - - /* Record the old position so we can come back to it */ - for (startPos = textInfo->txtBuffer[textInfo->startLine]->lineText; - (startPos > 0) && (textInfo->mainBuffer[startPos] != '\n'); - startPos--) - /* null loop body */; - - /* Clear out the old line start array */ - for (index = 0; index < textInfo->numLines; index++) { - InitLine(textInfo->txtBuffer[index]); - } - - /* Initialize first line */ - textInfo->txtBuffer[0]->lineHeight = - textInfo->theFonts[0].ascent + textInfo->theFonts[0].descent; - textInfo->txtBuffer[0]->lineText = 0; - - /* Process the text back into lines */ - endSize = textInfo->w - BARSIZE - WRAPINDSIZE; - bufptr = textInfo->mainBuffer; - lineptr = textInfo->txtBuffer[0]; - linenum = 0; - fontptr = &(textInfo->theFonts[0]); - curfont = 0; - for (index = 0; index < textInfo->bufSpot; index++) { - theChar = bufptr[index] & CHARMASK; - - if ((bufptr[index] & FONTMASK) != curfont) { - int newFontNum, heightDiff; - - /* Switch fonts */ - newFontNum = (bufptr[index] & FONTMASK) >> FONTSHIFT; - if (textInfo->theFonts[newFontNum].fid != 0) { - /* Valid font */ - curfont = bufptr[index] & FONTMASK; - fontptr = &(textInfo->theFonts[newFontNum]); - heightDiff = (fontptr->ascent + fontptr->descent) - - lineptr->lineHeight; - if (heightDiff < 0) heightDiff = 0; - lineptr->lineHeight += heightDiff; - } - } - if (theChar == '\n') { - /* Handle new line */ - if (linenum >= textInfo->allocLines-1) - /* Expand number of lines */ - ExpandLines(textInfo); - linenum++; - lineptr = textInfo->txtBuffer[linenum]; - /* Initialize next line */ - lineptr->lineHeight = fontptr->ascent + fontptr->descent; - lineptr->lineText = index+1; - /* Check to see if its the starting line */ - if (index == startPos) textInfo->startLine = linenum; - } else { - /* Handle normal character */ - chsize = CharSize(textInfo, linenum, index); - if (lineptr->lineWidth + chsize > endSize) { - /* Handle line wrap */ - lineptr->lineFlags |= WRAPFLAG; - if (linenum >= textInfo->allocLines-1) - /* Expand number of lines */ - ExpandLines(textInfo); - linenum++; - lineptr = textInfo->txtBuffer[linenum]; - /* Initialize next line */ - lineptr->lineHeight = fontptr->ascent + fontptr->descent; - lineptr->lineText = index; - lineptr->lineLength = 1; - lineptr->lineWidth += chsize; - } else { - /* Handle normal addition of character */ - lineptr->lineLength += 1; - lineptr->lineWidth += chsize; - } - } - } - /* We now have a valid line array. Let's clean up some other fields. */ - textInfo->numLines = linenum+1; - if (startPos == 0) { - textInfo->startLine = 0; - } - textInfo->endLine = FindEndLine(textInfo, &(textInfo->bottomSpace)); - textInfo->curLine = linenum; - /* Check to see if we are at the bottom */ - if (textInfo->endLine >= textInfo->numLines-1) { - textInfo->curY = textInfo->h - textInfo->bottomSpace - - lineptr->lineHeight; - textInfo->flagWord &= (~NOTATBOTTOM); - } else { - textInfo->flagWord |= NOTATBOTTOM; - } - return 1; -} - - - - -int TxtAddFont(display, textWin, fontNumber, newFont, newColor) -Display *display; -Window textWin; /* Scrollable text window */ -int fontNumber; /* Place to add font (0-7) */ -XFontStruct *newFont; /* Font to add */ -int newColor; /* Color of font */ -/* - * This routine loads a new font so that it can be used in a previously - * created text window. There are eight font slots numbered 0 through 7. - * If there is already a font in the specified slot, it will be replaced - * and an automatic redraw of the window will take place. See TxtWriteStr - * for details on using alternate fonts. The color specifies the foreground - * color of the text. The default foreground color is used if this - * parameter is TXT_NO_COLOR. Returns a non-zero value if - * everything went well. - */ -{ - struct txtWin *textInfo; - int redrawFlag; - XGCValues gc_val; - - if ((fontNumber < 0) || (fontNumber >= MAXFONTS)) return 0; - if ((textInfo = (struct txtWin *) - XLookUpAssoc(display, textWindows, (XID) textWin)) == 0) - return 0; - if (newColor == TXT_NO_COLOR) { - newColor = textInfo->fgPix; - } - - gc_val.font = newFont->fid; - gc_val.foreground = newColor; - gc_val.background = textInfo->bgPix; - gc_val.plane_mask = AllPlanes; - gc_val.graphics_exposures = 1; - gc_val.function = GXcopy; - - if (textInfo->fontGC[fontNumber] != 0) - { - XChangeGC(display, textInfo->fontGC[fontNumber], - GCFont | GCForeground, &gc_val); - } - else - textInfo->fontGC[fontNumber] = XCreateGC(display, textWin, - GCFont | - GCForeground | - GCBackground | - GCFunction | - GCPlaneMask | - GCGraphicsExposures, - &gc_val); - - - redrawFlag = (textInfo->theFonts[fontNumber].fid != 0) && - (((newFont) && (newFont->fid != textInfo->theFonts[fontNumber].fid)) || - (newColor != textInfo->theColors[fontNumber])); - if (newFont) { - textInfo->theFonts[fontNumber] = *newFont; - } - textInfo->theColors[fontNumber] = newColor; - - if (redrawFlag) { - RecompBuffer(textInfo); - XClearWindow(display, textWin); - TxtRepaint(display, textWin); - } - return 1; -} - - - -int TxtWinP(display, w) -Display *display; -Window w; -/* - * Returns a non-zero value if the window has been previously grabbed - * using TxtGrab and 0 if it has not. - */ -{ - if (XLookUpAssoc(display, textWindows, (XID) w)) - return(1); - else return(0); -} - - - -static int FindEndLine(textInfo, botSpace) -struct txtWin *textInfo; -int *botSpace; -/* - * Given the starting line in 'textInfo->startLine', this routine - * determines the index of the last line that can be drawn given the - * current size of the screen. If there are not enough lines to - * fill the screen, the index of the last line will be returned. - * The amount of empty bottom space is returned in 'botSpace'. - */ -{ - int index, height, lineHeight; - - height = YPADDING; - index = textInfo->startLine; - while (index < textInfo->numLines) { - lineHeight = textInfo->txtBuffer[index]->lineHeight + INTERLINE; - if (height + lineHeight > textInfo->h) break; - height += lineHeight; - index++; - } - if (botSpace) { - *botSpace = textInfo->h - height; - } - return index - 1; -} - - - -static int UpdateScroll(display, textInfo) -Display *display; -struct txtWin *textInfo; /* Text window information */ -/* - * This routine computes the current extent of the scroll bar - * indicator and repaints the bar with the correct information. - */ -{ - int top, bottom; - - if (textInfo->numLines > 1) { - top = textInfo->startLine * (textInfo->h - 2*BARBORDER) / - (textInfo->numLines - 1); - bottom = textInfo->endLine * (textInfo->h - 2*BARBORDER) / - (textInfo->numLines - 1); - } else { - top = 0; - bottom = textInfo->h - (2*BARBORDER); - } - - /* Draw it - make sure there is a little padding */ - if (top == 0) top++; - if (bottom == textInfo->h-(2*BARBORDER)) bottom--; - - XFillRectangle(display, textInfo->scrollBar, - textInfo->bgGC, - 0, 0, BARSIZE, top-1); - XFillRectangle(display, textInfo->scrollBar, - DEFAULT_GC, top, BARSIZE - (2*BARBORDER) - 2, - bottom - top); - XFillRectangle(display, textInfo->scrollBar, DEFAULT_GC, - 0, bottom+1, BARSIZE, - textInfo->h - (2 * BARBORDER) - bottom); - - return 1; -} - - - - -int TxtClear(display, w) -Display *display; -Window w; -/* - * This routine clears a scrollable text window. It resets the current - * writing position to the upper left hand corner of the screen. - * NOTE: THIS ALSO CLEARS THE CONTENTS OF THE TEXT WINDOW BUFFER AND - * RESETS THE SCROLL BAR. Returns 0 if the window is not a text window. - * This should be used *instead* of XClear. - */ -{ - struct txtWin *textInfo; - int index; - - if ((textInfo = (struct txtWin *) XLookUpAssoc(display, textWindows, (XID) w)) == 0) - return 0; - - /* Zero out the arrays */ - textInfo->bufSpot = 0; - for (index = 0; index < textInfo->numLines; index++) { - InitLine(textInfo->txtBuffer[index]); - } - textInfo->txtBuffer[0]->lineHeight = - textInfo->theFonts[textInfo->curFont].ascent + - textInfo->theFonts[textInfo->curFont].descent; - - textInfo->numLines = 1; - textInfo->startLine = 0; - textInfo->endLine = 0; - textInfo->curLine = 0; - textInfo->curX = 0; - textInfo->curY = YPADDING + textInfo->theFonts[textInfo->curFont].ascent - + textInfo->theFonts[textInfo->curFont].descent; - - textInfo->bottomSpace = textInfo->h - YPADDING - - textInfo->theFonts[textInfo->curFont].ascent - INTERLINE - - textInfo->theFonts[textInfo->curFont].descent; - /* Actually clear the window */ - XClearWindow(display, w); - - /* Draw the current cursor */ - XFillRectangle(display, w, textInfo->CursorGC, - XPADDING + CUROFFSET, textInfo->curY, - CURSORWIDTH, - textInfo->theFonts[textInfo->curFont].ascent + - textInfo->theFonts[textInfo->curFont].descent); - - /* Update the scroll bar */ - UpdateScroll(display, textInfo); - return 1; -} - - -static int WarpToBottom(display, textInfo) -Display *display; -struct txtWin *textInfo; /* Text Information */ -/* - * This routine causes the specified text window to display its - * last screen of information. It updates the scroll bar - * to the appropriate spot. The implementation scans backward - * through the buffer to find an appropriate starting spot for - * the window. - */ -{ - int index, height, lineHeight; - - index = textInfo->numLines-1; - height = 0; - while (index >= 0) { - lineHeight = textInfo->txtBuffer[index]->lineHeight + INTERLINE; - if (height + lineHeight > textInfo->h) break; - height += lineHeight; - index--; - } - textInfo->startLine = index + 1; - textInfo->endLine = FindEndLine(textInfo, &(textInfo->bottomSpace)); - textInfo->curY = textInfo->h - textInfo->bottomSpace - - textInfo->txtBuffer[textInfo->endLine]->lineHeight; - XClearWindow(display, textInfo->mainWindow); - TxtRepaint(display, textInfo->mainWindow); - return 1; -} - - - -static int UpdateExposures(display, textInfo) -Display *display; -struct txtWin *textInfo; /* Text window information */ -/* - * Before a new scrolling action occurs, the text window package - * must handle all COPYEXPOSE events generated by the last scrolling - * action. This routine is called to do this. Foreign events (those - * not handled by TxtFilter) are queued up and replaced on the queue - * after the processing of the exposure events is complete. - */ -{ -#if 0 - XEvent foreignQueue[MAXFOREIGN]; - int index, lastItem = 0; - - while (textInfo->flagWord & COPYEXPOSE) { - XNextEvent(display, &(foreignQueue[lastItem])); - if (!TxtFilter(display, &(foreignQueue[lastItem]))) - lastItem++; - if (lastItem >= MAXFOREIGN) { - printf("Too many foreign events to queue!\n"); - textInfo->flagWord &= (~COPYEXPOSE); - } - } - for (index = 0; index < lastItem; index++) { - XPutBackEvent(display, &(foreignQueue[index])); - } -#endif - return 1; -} - - -static int ScrollDown(display,textInfo) -Display *display; -struct txtWin *textInfo; /* Text window information */ -/* - * This routine scrolls the indicated text window down by one - * line. The line below the current line must exist. The window - * is scrolled so that the line below the last line is fully - * displayed. This may cause many lines to scroll off the top. - * Scrolling is done using XCopyArea. The exposure events should - * be caught using ExposeCopy. - */ -{ - int lineSum, index, targetSpace, freeSpace, updateFlag; - - lineSum = 0; - if (textInfo->endLine + 1 >= textInfo->numLines) return 0; - targetSpace = textInfo->txtBuffer[textInfo->endLine+1]->lineHeight + - INTERLINE; - if (textInfo->bottomSpace < targetSpace) { - index = textInfo->startLine; - while (index < textInfo->endLine) { - lineSum += (textInfo->txtBuffer[index]->lineHeight + INTERLINE); - if (textInfo->bottomSpace + lineSum >= targetSpace) break; - index++; - } - - /* Must move upward by 'lineSum' pixels */ - XCopyArea(display, textInfo->mainWindow, textInfo->mainWindow, - DEFAULT_GC, 0, lineSum, - textInfo->w - BARSIZE, textInfo->h, - 0, 0); - - textInfo->flagWord |= COPYEXPOSE; - /* Repair the damage to the structures */ - textInfo->startLine = index + 1; - updateFlag = 1; - } else { - updateFlag = 0; - } - /* More lines might be able to fit. Let's check. */ - freeSpace = textInfo->bottomSpace + lineSum - targetSpace; - index = textInfo->endLine + 1; - while (index < textInfo->numLines-1) { - if (freeSpace - textInfo->txtBuffer[index+1]->lineHeight - INTERLINE < 0) - break; - freeSpace -= (textInfo->txtBuffer[index+1]->lineHeight + INTERLINE); - index++; - } - textInfo->endLine = index; - textInfo->bottomSpace = freeSpace; - if (updateFlag) { - UpdateExposures(display, textInfo); - } - UpdateScroll(display, textInfo); - return 1; -} - - - - -static int ExpandLines(textInfo) -struct txtWin *textInfo; /* Text Information */ -/* - * This routine allocates and initializes additional space in - * the line start array (txtBuffer). The new space - * is allocated using realloc. The expansion factor is a percentage - * given by EXPANDPERCENT. - */ -{ - int newSize, index; - - newSize = textInfo->allocLines; - newSize += (newSize * EXPANDPERCENT) / 100; - - textInfo->txtBuffer = (struct txtLine **) - realloc((char *) textInfo->txtBuffer, - (unsigned) (newSize * sizeof(struct txtLine *))); - for (index = textInfo->allocLines; index < newSize; index++) { - textInfo->txtBuffer[index] = alloc(struct txtLine); - InitLine(textInfo->txtBuffer[index]); - } - textInfo->allocLines = newSize; - return 1; -} - -static int ExpandBuffer(textInfo) -struct txtWin *textInfo; /* Text information */ -/* - * Expands the basic character buffer using realloc. The expansion - * factor is a percentage given by EXPANDPERCENT. - */ -{ - int newSize; - - newSize = textInfo->bufAlloc + (textInfo->bufAlloc * EXPANDPERCENT) / 100; - textInfo->mainBuffer = (short *) - realloc((char *) textInfo->mainBuffer, (unsigned) newSize * sizeof(short)); - textInfo->bufAlloc = newSize; - return 1; -} - - - -static int HandleNewLine(display, textInfo, flagWord) -Display *display; -struct txtWin *textInfo; /* Text Information */ -int flagWord; /* DODISP or NONEWLINE or both */ -/* - * This routine initializes the next line for drawing by setting - * its height to the current font height, scrolls the screen down - * one line, and updates the current drawing position to the - * left edge of the newly cleared line. If DODISP is specified, - * the screen will be updated (otherwise not). If NONEWLINE is - * specified, no newline character will be added to the text buffer - * (this is for line wrap). - */ -{ - struct txtLine *curLine, *nextLine; - - /* Check to see if a new line must be allocated */ - if (textInfo->curLine >= textInfo->allocLines-1) - /* Expand the number of lines */ - ExpandLines(textInfo); - textInfo->numLines += 1; - - /* Then we initialize the next line */ - nextLine = textInfo->txtBuffer[textInfo->numLines-1]; - nextLine->lineHeight = - textInfo->theFonts[textInfo->curFont].ascent + - textInfo->theFonts[textInfo->curFont].descent; - - curLine = textInfo->txtBuffer[textInfo->curLine]; - if (flagWord & DODISP) { - /* Scroll down a line if required */ - if ((textInfo->curY + curLine->lineHeight + - nextLine->lineHeight + (INTERLINE * 2)) > textInfo->h) - { - ScrollDown(display, textInfo); - } - else - { - /* Update the bottom space appropriately */ - textInfo->bottomSpace -= (nextLine->lineHeight + INTERLINE); - textInfo->endLine += 1; - } - /* Update drawing position */ - textInfo->curY = textInfo->h - - (textInfo->bottomSpace + nextLine->lineHeight); - } - - /* Move down a line */ - textInfo->curLine += 1; - if (!(flagWord & NONEWLINE)) { - /* Append end-of-line to text buffer */ - if (textInfo->bufSpot >= textInfo->bufAlloc) { - /* Allocate more space in main text buffer */ - ExpandBuffer(textInfo); - } - textInfo->mainBuffer[(textInfo->bufSpot)++] = - (textInfo->curFont << FONTSHIFT) | '\n'; - } - nextLine->lineText = textInfo->bufSpot; - textInfo->curX = 0; - return 1; -} - - - -static int CharSize(textInfo, lineNum, charNum) -struct txtWin *textInfo; /* Current Text Information */ -int lineNum; /* Line in buffer */ -int charNum; /* Character in line */ -/* - * This routine determines the size of the specified character. - * It takes in account the font of the character and whether its - * fixed or variable. The size includes INTERSPACE spacing between - * the characters. - */ -{ - register XFontStruct *charFont; - register short *theLine; - register short theChar; - - theLine = &(textInfo->mainBuffer[textInfo->txtBuffer[lineNum]->lineText]); - theChar = theLine[charNum] & CHARMASK; - charFont = &(textInfo->theFonts[(theChar & FONTMASK) >> FONTSHIFT]); - if (theChar <= charFont->min_char_or_byte2 || - theChar >= charFont->max_char_or_byte2 || - charFont->per_char == 0) - return charFont->max_bounds.width + 1; - else - return charFont->per_char[theChar].width + 1; -} - - - - - -static int HandleBackspace(display, textInfo, flagWord) -Display *display; -struct txtWin *textInfo; /* Text Information */ -int flagWord; /* DODISP or nothing */ -/* - * This routine handles a backspace found in the input stream. The - * character before the current writing position will be erased and - * the drawing position will move back one character. If the writing - * position is at the left margin, the drawing position will move - * up to the previous line. If it is a line that has been wrapped, - * the character at the end of the previous line will be erased. - */ -{ - struct txtLine *thisLine, *prevLine; - int chSize; - - thisLine = textInfo->txtBuffer[textInfo->curLine]; - /* First, determine whether we need to go back a line */ - if (thisLine->lineLength == 0) { - /* Bleep if at top of buffer */ - if (textInfo->curLine == 0) { - XBell(display, 50); - return 0; - } - - /* See if we have to scroll in the other direction */ - if ((flagWord & DODISP) && (textInfo->curY <= YPADDING)) { - /* This will display the last lines of the buffer */ - WarpToBottom(display, textInfo); - } - - /* Set drawing position at end of previous line */ - textInfo->curLine -= 1; - prevLine = textInfo->txtBuffer[textInfo->curLine]; - textInfo->numLines -= 1; - if (flagWord & DODISP) { - textInfo->curY -= (prevLine->lineHeight + INTERLINE); - textInfo->bottomSpace += (thisLine->lineHeight + INTERLINE); - textInfo->endLine -= 1; - } - - /* We are unlinewrapping if the previous line has flag set */ - if (prevLine->lineFlags & WRAPFLAG) { - /* Get rid of line wrap indicator */ - if (flagWord & DODISP) { - XFillRectangle(display, textInfo->mainWindow, - textInfo->bgGC, - textInfo->w - BARSIZE - WRAPINDSIZE, - textInfo->curY, WRAPINDSIZE, - prevLine->lineHeight); - } - prevLine->lineFlags &= (~WRAPFLAG); - /* Call recursively to wipe out the ending character */ - HandleBackspace(display, textInfo, flagWord); - } else { - /* Delete the end-of-line in the primary buffer */ - textInfo->bufSpot -= 1; - } - } else { - /* Normal deletion of character */ - chSize = - CharSize(textInfo, textInfo->curLine, - textInfo->txtBuffer[textInfo->curLine]->lineLength - 1); - /* Move back appropriate amount and wipe it out */ - thisLine->lineWidth -= chSize; - if (flagWord & DODISP) { - XFillRectangle(display, textInfo->mainWindow, - textInfo->bgGC, - thisLine->lineWidth, textInfo->curY, - chSize, thisLine->lineHeight); - } - /* Delete from buffer */ - textInfo->txtBuffer[textInfo->curLine]->lineLength -= 1; - textInfo->bufSpot -= 1; - } - return 1; -} - - - -static int DrawLineWrap(display, win, x, y, h, col) -Display *display; -Window win; /* What window to draw it in */ -int x, y; /* Position of upper left corner */ -int h; /* Height of indicator */ -int col; /* Color of indicator */ -/* - * This routine draws a line wrap indicator at the end of a line. - * Visually, it is an arrow of the specified height directly against - * the scroll bar border. The bitmap used for the arrow is stored - * in 'arrowMap' with size 'arrow_width' and 'arrow_height'. - */ -{ - struct txtWin *textInfo; - - textInfo = (struct txtWin *)XLookUpAssoc(display, textWindows, - (XID) win); - - /* First, draw the arrow */ - XCopyArea(display, textInfo->arrowMap, textInfo->mainWindow, - textInfo->CursorGC, - 0, 0, arrow_width, arrow_height, - x, y + h - arrow_height, 1); - - /* Then draw the stem */ - XDrawLine(display, textInfo->mainWindow, textInfo->CursorGC, - x + STEMOFFSET, y, - x + STEMOFFSET, y + h - arrow_height); - return 1; -} - - - - -static int DrawLine(display, textInfo, lineIndex, ypos) -Display *display; -struct txtWin *textInfo; /* Text window information */ -int lineIndex; /* Index of line to draw */ -int ypos; /* Y position for line */ -/* - * This routine destructively draws the indicated line in the - * indicated window at the indicated position. It does not - * clear to end of line however. It draws a line wrap indicator - * if needed but does not draw a cursor. - */ -{ - int index, startPos, curFont, theColor, curX, saveX, fontIndex; - struct txtLine *someLine; - char lineBuffer[BUFSIZE], *glyph; - short *linePointer; - XFontStruct *theFont; - XGCValues gc; - - /* First, we draw the text */ - index = 0; - curX = XPADDING; - someLine = textInfo->txtBuffer[lineIndex]; - linePointer = &(textInfo->mainBuffer[someLine->lineText]); - while (index < someLine->lineLength) { - startPos = index; - saveX = curX; - curFont = linePointer[index] & FONTMASK; - fontIndex = curFont >> FONTSHIFT; - theFont = &(textInfo->theFonts[fontIndex]); - theColor = textInfo->theColors[fontIndex]; - glyph = &(lineBuffer[0]); - while ((index < someLine->lineLength) && - ((linePointer[index] & FONTMASK) == curFont)) - { - *glyph = linePointer[index] & CHARMASK; - index++; - curX += CharSize(textInfo, lineIndex, index); - glyph++; - } - - /* Flush out the glyphs */ - XFillRectangle(display, textInfo->mainWindow, - textInfo->bgGC, - saveX, ypos, - textInfo->w - BARSIZE, - someLine->lineHeight + YPADDING + INTERLINE); - - XDrawString(display, textInfo->mainWindow, - textInfo->fontGC[fontIndex], - saveX, ypos, - lineBuffer, someLine->lineLength); - } - /* Then the line wrap indicator (if needed) */ - if (someLine->lineFlags & WRAPFLAG) { - DrawLineWrap(display, textInfo->mainWindow, - textInfo->w - BARSIZE - WRAPINDSIZE, - ypos, someLine->lineHeight, - textInfo->fgPix); - } - return 1; -} - - - - -static int HandleNewFont(display, fontNum, textInfo, flagWord) -Display *display; -int fontNum; /* Font number */ -struct txtWin *textInfo; /* Text information */ -int flagWord; /* DODISP or nothing */ -/* - * This routine handles a new font request. These requests take - * the form "^F<digit>". The parsing is done in TxtWriteStr. - * This routine is called only if the form is valid. It may return - * a failure (0 status) if the requested font is not loaded. - * If the new font is larger than any of the current - * fonts on the line, it will change the line height and redisplay - * the line. - */ -{ - struct txtLine *thisLine; - int heightDiff, baseDiff, redrawFlag; - - if (textInfo->theFonts[fontNum].fid == 0) { - return 0; - } else { - thisLine = textInfo->txtBuffer[textInfo->curLine]; - textInfo->curFont = fontNum; - redrawFlag = 0; - heightDiff = textInfo->theFonts[fontNum].ascent + - textInfo->theFonts[fontNum].descent - - thisLine->lineHeight; - - if (heightDiff > 0) { - redrawFlag = 1; - } else { - heightDiff = 0; - } - - if (redrawFlag) { - if (flagWord & DODISP) { - /* Clear current line */ - XFillRectangle(display, textInfo->mainWindow, - textInfo->bgGC, - 0, textInfo->curY, textInfo->w, - thisLine->lineHeight); - - /* Check to see if it requires scrolling */ - if ((textInfo->curY + thisLine->lineHeight + heightDiff + - INTERLINE) > textInfo->h) - { - /* - * General approach: "unscroll" the last line up - * and then call ScrollDown to do the right thing. - */ - textInfo->endLine -= 1; - textInfo->bottomSpace += thisLine->lineHeight + - INTERLINE; - - XFillRectangle(display, textInfo->mainWindow, - textInfo->bgGC, - 0, textInfo->h - textInfo->bottomSpace, - textInfo->w, textInfo->bottomSpace); - - thisLine->lineHeight += heightDiff; - ScrollDown(display, textInfo); - textInfo->curY = textInfo->h - - (textInfo->bottomSpace + INTERLINE + - thisLine->lineHeight); - } - else - { - /* Just update bottom space */ - textInfo->bottomSpace -= heightDiff; - thisLine->lineHeight += heightDiff; - } - /* Redraw the current line */ - DrawLine(display, textInfo, textInfo->curLine, textInfo->curY); - } else { - /* Just update line height */ - thisLine->lineHeight += heightDiff; - } - } - return 1; - } -} - - - -int TxtWriteStr(display, w, str) -Display *display; -Window w; /* Text window */ -register char *str; /* 0 terminated string */ -/* - * This routine writes a string to the specified text window. - * The following notes apply: - * - Text is always appended to the end of the text buffer. - * - If the scroll bar is positioned such that the end of the - * text is not visible, an automatic scroll to the bottom - * will be done before the appending of text. - * - Non-printable ASCII characters are not displayed. - * - The '\n' character causes the current text position to - * advance one line and start at the left. - * - Tabs are not supported. - * - Lines too long for the screen will be wrapped and a line wrap - * indication will be drawn. - * - Backspace clears the previous character. It will do the right - * thing if asked to backspace past a wrapped line. - * - A new font can be chosen using the sequence '^F<digit>' where - * <digit> is 0-7. The directive will be ignored if - * there is no font in the specified slot. - * Returns 0 if something went wrong. - */ -{ - register int fontIndex; - register struct txtWin *textInfo; - register struct txtLine *thisLine; - - if ((textInfo = (struct txtWin *) XLookUpAssoc(display, textWindows, (XID) w)) == 0) - return 0; - - /* See if screen needs to be updated */ - if (textInfo->flagWord & SCREENWRONG) { - TxtRepaint(display, textInfo->mainWindow); - } - - /* See if we have to scroll down to the bottom */ - if (textInfo->flagWord & NOTATBOTTOM) { - WarpToBottom(display, textInfo); - textInfo->flagWord &= (~NOTATBOTTOM); - } - - /* Undraw the current cursor */ - thisLine = textInfo->txtBuffer[textInfo->curLine]; - - XFillRectangle(display, w, textInfo->bgGC, - thisLine->lineWidth + CUROFFSET, - textInfo->curY, - CURSORWIDTH, - thisLine->lineHeight); - - for ( /* str is ok */ ; (*str != 0) ; str++) { - /* Check to see if we are waiting on a font */ - if (textInfo->flagWord & FONTNUMWAIT) { - textInfo->flagWord &= (~FONTNUMWAIT); - fontIndex = *str - '0'; - if ((fontIndex >= 0) && (fontIndex < MAXFONTS)) { - /* Handle font -- go get next character */ - if (HandleNewFont(display, fontIndex, textInfo, DODISP)) - continue; - } - } - - /* Inline code for handling normal character case */ - if ((*str >= LOWCHAR) && (*str <= HIGHCHAR)) { - register XFontStruct *thisFont; - register struct txtLine *thisLine; - register int charWidth; - int thisColor; - - /* Determine size of character */ - thisFont = &(textInfo->theFonts[textInfo->curFont]); - thisColor = textInfo->theColors[textInfo->curFont]; - if (*str <= thisFont->min_char_or_byte2 || - *str >= thisFont->max_char_or_byte2 || - thisFont->per_char == 0) - charWidth = thisFont->max_bounds.width + 1; - else - charWidth = thisFont->per_char[*str].width + 1; - - /* Check to see if line wrap is required */ - thisLine = textInfo->txtBuffer[textInfo->curLine]; - if (thisLine->lineWidth + charWidth > - (textInfo->w-BARSIZE-WRAPINDSIZE)) - { - DrawLineWrap(display, textInfo->mainWindow, - textInfo->w-BARSIZE-WRAPINDSIZE, - textInfo->curY, thisLine->lineHeight, - textInfo->fgPix); - thisLine->lineFlags |= WRAPFLAG; - /* Handle the spacing problem the same way as a newline */ - HandleNewLine(display, textInfo, DODISP | NONEWLINE); - thisLine = textInfo->txtBuffer[textInfo->curLine]; - } - - /* Ready to draw character */ - XDrawString(display, textInfo->mainWindow, - DEFAULT_GC, - textInfo->curX += charWidth, - textInfo->curY + thisLine->lineHeight, - str, 1); - - /* Append character onto main buffer */ - if (textInfo->bufSpot >= textInfo->bufAlloc) - /* Make room for more characters */ - ExpandBuffer(textInfo); - textInfo->mainBuffer[(textInfo->bufSpot)++] = - (textInfo->curFont << FONTSHIFT) | (*str); - - /* Update the line start array */ - thisLine->lineLength += 1; - thisLine->lineWidth += charWidth; - } else if (*str == NEWLINE) { - HandleNewLine(display, textInfo, DODISP); - } else if (*str == NEWFONT) { - /* Go into waiting for font number mode */ - textInfo->flagWord |= FONTNUMWAIT; - } else if (*str == BACKSPACE) { - HandleBackspace(display, textInfo, DODISP); - } else { - /* Ignore all others */ - } - } - /* Draw the cursor in its new position */ - thisLine = textInfo->txtBuffer[textInfo->curLine]; - - XFillRectangle(display, w, textInfo->CursorGC, - thisLine->lineWidth + CUROFFSET, - textInfo->curY /* + thisLine->lineHeight */, - CURSORWIDTH, thisLine->lineHeight); - - return 1; -} - - - -int TxtJamStr(display, w, str) -Display *display; -Window w; /* Text window */ -register char *str; /* NULL terminated string */ -/* - * This is the same as TxtWriteStr except the screen is NOT updated. - * After a call to this routine, TxtRepaint should be called to - * update the screen. This routine is meant to be used to load - * a text buffer with information and then allow the user to - * scroll through it at will. - */ -{ - register int fontIndex; - register struct txtWin *textInfo; - - if ((textInfo = (struct txtWin *) XLookUpAssoc(display, textWindows, (XID) w) - ) == 0) - return 0; - - for ( /* str is ok */ ; (*str != 0) ; str++) { - /* Check to see if we are waiting on a font */ - if (textInfo->flagWord & FONTNUMWAIT) { - textInfo->flagWord &= (~FONTNUMWAIT); - fontIndex = *str - '0'; - if ((fontIndex >= 0) && (fontIndex < MAXFONTS)) { - if (HandleNewFont(display, fontIndex, textInfo, 0)) { - /* Handled font -- go get next character */ - continue; - } - } - } - /* Inline code for handling normal character case */ - if ((*str >= LOWCHAR) && (*str <= HIGHCHAR)) { - register XFontStruct *thisFont; - register struct txtLine *thisLine; - register int charWidth; - - /* Determine size of character */ - thisFont = &(textInfo->theFonts[textInfo->curFont]); - - if (*str <= thisFont->min_char_or_byte2 || - *str >= thisFont->max_char_or_byte2 || - thisFont->per_char == 0) - charWidth = thisFont->max_bounds.width + 1; - else - charWidth = thisFont->per_char[*str].width + 1; - - /* Check to see if line wrap is required */ - thisLine = textInfo->txtBuffer[textInfo->curLine]; - if (thisLine->lineWidth + charWidth > - (textInfo->w-BARSIZE-WRAPINDSIZE)) - { - thisLine->lineFlags |= WRAPFLAG; - /* Handle the spacing problem the same way as a newline */ - HandleNewLine(display, textInfo, NONEWLINE); - thisLine = textInfo->txtBuffer[textInfo->curLine]; - } - /* Append character onto main buffer */ - if (textInfo->bufSpot >= textInfo->bufAlloc) - /* Make room for more characters */ - ExpandBuffer(textInfo); - textInfo->mainBuffer[(textInfo->bufSpot)++] = - (textInfo->curFont << FONTSHIFT) | (*str); - - /* Update the line start array */ - thisLine->lineLength += 1; - thisLine->lineWidth += charWidth; - } else if (*str == NEWLINE) { - HandleNewLine(display, textInfo, 0); - } else if (*str == NEWFONT) { - /* Go into waiting for font number mode */ - textInfo->flagWord |= FONTNUMWAIT; - } else if (*str == BACKSPACE) { - HandleBackspace(display, textInfo, 0); - } else { - /* Ignore all others */ - } - } - textInfo->flagWord |= SCREENWRONG; - return 1; -} - - - -int TxtRepaint(display,w) -Display *display; -Window w; -/* - * Repaints the given scrollable text window. The routine repaints - * the entire window. For handling exposure events, the TxtFilter - * routine should be used. - */ -{ - struct txtWin *textInfo; - int index, ypos; - - if ((textInfo = (struct txtWin *) XLookUpAssoc(display, textWindows, (XID) w) - ) == 0) - return 0; - - /* Check to see if the screen is up to date */ - if (textInfo->flagWord & SCREENWRONG) { - textInfo->endLine = FindEndLine(textInfo, &(textInfo->bottomSpace)); - textInfo->flagWord &= (~SCREENWRONG); - } - - ypos = YPADDING; - index = textInfo->startLine; - for (;;) { - DrawLine(display, textInfo, index, ypos); - if (index >= textInfo->endLine) break; - ypos += (textInfo->txtBuffer[index]->lineHeight + INTERLINE); - index++; - } - /* Draw the cursor (if on screen) */ - if (textInfo->endLine == textInfo->curLine) { - XFillRectangle(display, w, textInfo->CursorGC, - textInfo->txtBuffer[index]->lineWidth + CUROFFSET, - ypos /* + textInfo->txtBuffer[index]->lineHeight */, - CURSORWIDTH, textInfo->txtBuffer[index]->lineHeight); - - } - /* Update the scroll bar */ - UpdateScroll(display, textInfo); - return 1; -} - - - -static int InsertIndex(textInfo, thisIndex, ypos) -struct txtWin *textInfo; /* Text Window Information */ -int thisIndex; /* Line index of exposed line */ -int ypos; /* Drawing position of line */ -/* - * This routine inserts the supplied line index into the copy - * exposure array for 'textInfo'. The array is kept sorted - * from lowest to highest using insertion sort. The array - * is dynamically expanded if needed. - */ -{ - struct expEvent *newItem; - int newSize, index, downIndex; - - /* Check to see if we need to expand it */ - if ((textInfo->exposeSize + 3) >= textInfo->exposeAlloc) { - newSize = textInfo->exposeAlloc + - (textInfo->exposeAlloc * EXPANDPERCENT / 100); - textInfo->exposeAry = (struct expEvent **) - realloc((char *) textInfo->exposeAry, - (unsigned) (newSize * sizeof(struct expEvent *))); - for (index = textInfo->exposeAlloc; index < newSize; index++) - textInfo->exposeAry[index] = alloc(struct expEvent); - textInfo->exposeAlloc = newSize; - } - /* Find spot for insertion. NOTE: last spot has big number */ - for (index = 0; index <= textInfo->exposeSize; index++) { - if (textInfo->exposeAry[index]->lineIndex >= thisIndex) { - if (textInfo->exposeAry[index]->lineIndex > thisIndex) { - /* Insert before this entry */ - newItem = textInfo->exposeAry[textInfo->exposeSize+1]; - for (downIndex = textInfo->exposeSize; - downIndex >= index; - downIndex--) - { - textInfo->exposeAry[downIndex+1] = - textInfo->exposeAry[downIndex]; - } - /* Put a free structure at this spot */ - textInfo->exposeAry[index] = newItem; - /* Fill it in */ - textInfo->exposeAry[index]->lineIndex = thisIndex; - textInfo->exposeAry[index]->ypos = ypos; - /* Break out of loop */ - textInfo->exposeSize += 1; - } - break; - } - } - return 1; -} - - - -static int ScrollUp(display, textInfo) -Display *display; -struct txtWin *textInfo; /* Text window information */ -/* - * This routine scrolls the indicated text window up by one - * line. The line above the current line must exist. The - * window is scrolled so that the line above the start line - * is displayed at the top of the screen. This may cause - * many lines to scroll off the bottom. The scrolling is - * done using XCopyArea. The exposure events should be caught - * by ExposeCopy. - */ -{ - int targetSpace; - - /* Make sure all exposures have been handled by now */ - if (textInfo->startLine == 0) return 0; - targetSpace = textInfo->txtBuffer[textInfo->startLine-1]->lineHeight + - INTERLINE; - /* Move the area downward by the target amount */ - XCopyArea(display, textInfo->mainWindow, textInfo->mainWindow, - DEFAULT_GC, - 0, YPADDING, textInfo->w - BARSIZE, - textInfo->h, 0, targetSpace); - - textInfo->flagWord |= COPYEXPOSE; - /* Update the text window parameters */ - textInfo->startLine -= 1; - textInfo->endLine = FindEndLine(textInfo, &(textInfo->bottomSpace)); - - /* Clear out bottom space region */ - XClearArea(display, textInfo->mainWindow, - 0, textInfo->h - textInfo->bottomSpace, - textInfo->w, textInfo->bottomSpace); - - UpdateExposures(display, textInfo); - UpdateScroll(display, textInfo); - - return 1; -} - - -static int ScrollToSpot(display, textInfo, ySpot) -Display *display; -struct txtWin *textInfo; /* Text window information */ -int ySpot; /* Button position in scroll window */ -/* - * This routine scrolls the specified text window relative to the - * position of the mouse in the scroll bar. The center of the screen - * will be positioned to correspond to the mouse position. - */ -{ - int targetLine, aboveLines; - - targetLine = textInfo->numLines * ySpot / textInfo->h; - textInfo->startLine = targetLine; - textInfo->endLine = FindEndLine(textInfo, &(textInfo->bottomSpace)); - aboveLines = 0; - /* Make the target line the *center* of the window */ - while ((textInfo->startLine > 0) && - (aboveLines < textInfo->endLine - targetLine)) - { - textInfo->startLine -= 1; - textInfo->endLine = FindEndLine(textInfo, &(textInfo->bottomSpace)); - aboveLines++; - } - if (textInfo->endLine == textInfo->numLines-1) { - WarpToBottom(display, textInfo); - } else { - XClearWindow(display, textInfo->mainWindow); - TxtRepaint(display, textInfo->mainWindow); - } - return 1; -} - - - -static int LineToTop(display, textInfo, pos) -Display *display; -struct txtWin *textInfo; /* Text window information */ -int pos; /* Y position of mouse */ -/* - * This routine scrolls the screen down until the line at the - * mouse position is at the top of the screen. It stops - * if it can't scroll the buffer down that far. If the - * global 'ScrollOption' is NORMSCROLL, a smooth scroll - * is used. Otherwise, it jumps to the right position - * and repaints the screen. - */ -{ - int index, sum; - - /* First, we find the current line */ - sum = 0; - for (index = textInfo->startLine; index <= textInfo->endLine; index++) { - if (sum + textInfo->txtBuffer[index]->lineHeight + INTERLINE> pos) break; - sum += textInfo->txtBuffer[index]->lineHeight + INTERLINE; - } - /* We always want to scroll down at least one line */ - if (index == textInfo->startLine) index++; - if (ScrollOption == NORMSCROLL) { - /* Scroll down until 'index' is the starting line */ - while ((textInfo->startLine < index) && ScrollDown(display, textInfo)) - { - /* Empty Loop Body */ - } - } else { - /* Immediately jump to correct spot */ - textInfo->startLine = index; - textInfo->endLine = FindEndLine(textInfo, &(textInfo->bottomSpace)); - if (textInfo->endLine == textInfo->numLines-1) { - WarpToBottom(display, textInfo); - } else { - XClearWindow(display, textInfo->mainWindow); - TxtRepaint(display, textInfo->mainWindow); - } - } - /* Check to see if at end of buffer */ - if (textInfo->endLine >= textInfo->numLines-1) { - textInfo->flagWord &= (~NOTATBOTTOM); - } - return 1; -} - - - -static int TopToHere(display, textInfo, pos) -Display *display; -struct txtWin *textInfo; /* Text window information */ -int pos; /* Y position of mouse */ -/* - * This routine scrolls the screen up until the top line of - * the screen is at the current Y position of the mouse. Again, - * it will stop if it can't scroll that far. If the global - * 'ScrollOption' is NORMSCROLL, a smooth scroll is used. - * If it's not, it will simply redraw the screen at the - * correct spot. - */ -{ - int sum, target, linesup, index; - - target = pos - textInfo->txtBuffer[textInfo->startLine]->lineHeight; - /* We always want to scroll up at least one line */ - if (target <= 0) target = 1; - sum = 0; - linesup = 0; - /* Check to see if we are at the top anyway */ - if (textInfo->startLine == 0) return 0; - if (ScrollOption == NORMSCROLL) { - /* Scroll up until sum of new top lines greater than target */ - while ((sum < target) && ScrollUp(display, textInfo)) { - sum += textInfo->txtBuffer[textInfo->startLine]->lineHeight; - linesup++; - } - } else { - /* Search backward to find index */ - index = textInfo->startLine - 1; - while ((index > 0) && (sum < target)) { - sum += textInfo->txtBuffer[index]->lineHeight; - linesup++; - index--; - } - /* Go directly to the index */ - textInfo->startLine = index; - textInfo->endLine = FindEndLine(textInfo, &(textInfo->bottomSpace)); - XClearWindow(display, textInfo->mainWindow); - TxtRepaint(display, textInfo->mainWindow); - } - /* If we scrolled, assert we are not at bottom of buffer */ - if (linesup > 0) { - textInfo->flagWord |= NOTATBOTTOM; - } - return 1; -} - - - -int TxtFilter(display, evt) -Display *display; -XEvent *evt; -/* - * This routine handles events associated with scrollable text windows. - * It will handle all exposure events and any button released events - * in the scroll bar of a text window. It does NOT handle any other - * events. If it cannot handle the event, it will return 0. - */ -{ - XExposeEvent *expose = &evt->xexpose; - XButtonEvent *btEvt = &evt->xbutton; - XGraphicsExposeEvent *gexpose = &evt->xgraphicsexpose; - XNoExposeEvent *noexpose = &evt->xnoexpose; - struct txtWin *textInfo; - int index, ypos; - Window w, sw; - - if (textWindows == (XAssocTable *) 0) { - textWindows = XCreateAssocTable(32); - if (textWindows == (XAssocTable *) 0) return(0); - } - if (evt->type == Expose) { - w = expose->window; - sw = 0; - } - else if (evt->type == GraphicsExpose) { - w = gexpose->drawable; - sw = 0; - } - else if (evt->type == NoExpose) { - w = noexpose->drawable; - sw = 0; - } - else if (evt->type == ButtonRelease) { - w = btEvt->window; - sw = btEvt->subwindow; - } - else - return 0; - - if ((textInfo = (struct txtWin *) - XLookUpAssoc(display, textWindows, (XID) w)) == 0) - return 0; - - /* Determine whether it's main window or not */ - if ((w == textInfo->mainWindow) && (sw == 0)) { - /* Main Window - handle exposures */ - switch (evt->type) { - case Expose: - ypos = 0 /*YPADDING*/; - for (index = textInfo->startLine; - index <= textInfo->endLine; - index++) - { - int lh = textInfo->txtBuffer[index]->lineHeight; - - if (((ypos + lh) >= expose->y) && - (ypos <= (expose->y + expose->height))) - { - /* Intersection region */ - /* Draw line immediately */ - DrawLine(display, textInfo, index, ypos); - /* And possibly draw cursor */ - if (textInfo->curLine == index) { - XFillRectangle(display, w, textInfo->CursorGC, - textInfo->txtBuffer[index]->lineWidth + - CUROFFSET, - ypos, - CURSORWIDTH, - lh); - } - } - ypos += lh + INTERLINE; - } - break; - case GraphicsExpose: - ypos = 0 /*YPADDING*/; - for (index = textInfo->startLine; - index <= textInfo->endLine; - index++) - { - int lh = textInfo->txtBuffer[index]->lineHeight; - - if (((ypos + lh) >= gexpose->y) && - (ypos <= (gexpose->y + gexpose->height))) - { - /* Intersection region */ - /* Draw line immediately */ - DrawLine(display, textInfo, index, ypos); - /* And possibly draw cursor */ - if (textInfo->curLine == index) { - XFillRectangle(display, w, textInfo->CursorGC, - textInfo->txtBuffer[index]->lineWidth + - CUROFFSET, - ypos, - CURSORWIDTH, - lh); - } - } - ypos += lh + INTERLINE; - } - break; - case NoExpose: - break; - default: - /* Not one of our events */ - return 0; - } - } else { - switch (evt->type) { - case Expose: - UpdateScroll(display, textInfo); - break; - case ButtonRelease: - /* Find out which button */ - switch (btEvt->button) { - case Button1: - /* Scroll up until top line is at mouse position */ - TopToHere(display, textInfo, btEvt->y); - break; - case Button2: - /* Scroll to spot relative to position */ - ScrollToSpot(display, textInfo, btEvt->y); - if (textInfo->endLine >= textInfo->numLines-1) { - textInfo->flagWord &= (~NOTATBOTTOM); - } else { - textInfo->flagWord |= NOTATBOTTOM; - } - break; - case Button3: - /* Scroll down until pointed line is at top */ - LineToTop(display, textInfo, btEvt->y); - break; - } - break; - default: - /* Not one of our events */ - return 0; - } - } - return 1; -} diff --git a/gnu/games/chess/Xchess/scrollText/scrollText.h b/gnu/games/chess/Xchess/scrollText/scrollText.h deleted file mode 100644 index d9d05b08dc0b..000000000000 --- a/gnu/games/chess/Xchess/scrollText/scrollText.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Scrollable Text Window Header File - * - * David Harrison - * University of California, Berkeley - * 1986 - * - * This file contains definitions for a scrollable text window - * with scroll bar support. - */ - -int TxtGrab(); - /* Take hold of a previously created window */ - -#define TXT_NO_COLOR -1 - -int TxtAddFont(); - /* Loads a new font for use later */ -int TxtWinP(); - /* Returns non-zero value if the window is text window */ -int TxtClear(); - /* Clears text window and resets text buffer */ - -int TxtWriteStr(); - /* Writes a string to window with immediate update */ -int TxtJamStr(); - /* Write a string without causing update to screen */ - -int TxtRepaint(); - /* Repaints entire scrollable text window */ -int TxtFilter(); - /* Handles events related to text window */ |