⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scrolltext.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * 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		2147483647extern 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 5static 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. */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -