source: trunk/athena/bin/xmore/pages.c @ 6954

Revision 6954, 7.6 KB checked in by probe, 31 years ago (diff)
Initial revision
  • Property svn:executable set to *
Line 
1#ifndef lint
2  static char rcsid_module_c[] = "$Header: /afs/dev.mit.edu/source/repository/athena/bin/xmore/pages.c,v 1.1 1993-10-12 05:34:45 probe Exp $";
3#endif lint
4
5/*      This is the file pages.c for the Xmore, a file browsing utility
6 *      built upon Xlib and the XToolkit.
7 *      It Contains: InitPage() and PrintPage().
8 *     
9 *      Created:        November 10, 1987
10 *      By:             Chris D. Peterson
11 *
12 *      $Source: /afs/dev.mit.edu/source/repository/athena/bin/xmore/pages.c,v $
13 *      $Author: probe $
14 *      $Header: /afs/dev.mit.edu/source/repository/athena/bin/xmore/pages.c,v 1.1 1993-10-12 05:34:45 probe Exp $
15 *     
16 *      Copyright 1987, 1988 by the Massachusetts Institute of Technology.
17 *
18 *      For further information on copyright and distribution
19 *      see the file mit-copyright.h
20 */
21
22#include "globals.h"
23#include "mit-copyright.h"
24
25#define ADD_MORE_MEM 100
26#define CHAR_PER_LINE 40
27
28/*      Function Name: InitPage
29 *      Description: This function reads a file and sets it up for
30 *                   display in the scrollbyline widget.
31 *      Arguments: widget - the scrollled widget we are initializing.
32 *                 file - a file pointer to the file that we are opening.
33 *      Returns: none.
34 */
35
36void
37InitPage(widget,file)
38Widget widget;
39FILE * file;
40{
41  char *page,*top_of_page;      /* a pointer to the manpage,
42                                   stored in dynamic memory. */
43  char **line_pointer,**top_line; /* pointers to beginnings of the
44                                     lines of the file. */
45  int nlines;                   /* the current number of allocated lines. */
46  Arg arglist[5];               /* the arglist. */
47  Cardinal num_args;            /* the number of arguments. */
48  struct stat fileinfo;         /* file information from fstat. */
49  MemoryStruct * memory_struct; /* the memory information to pass to the
50                                   next file. */
51 
52  memory_struct = global_memory_struct;
53
54  if ( memory_struct->top_line != NULL) {
55    free(memory_struct->top_line);
56    free(memory_struct->top_of_page);
57  }
58
59/*
60 * Get file size and allocate a chunk of memory for the file to be
61 * copied into.
62 */
63
64  if (fstat(fileno(file), &fileinfo)) {
65    printf("Failure in fstat\n");
66    exit(1);
67  }
68
69  page = (char *) malloc(fileinfo.st_size + 1); /* leave space for the NULL */
70  top_of_page = page;
71
72/*
73 * Allocate a space for a list of pointer to the beginning of each line.
74 */
75
76  nlines = fileinfo.st_size/CHAR_PER_LINE;
77  line_pointer = (char**) malloc( nlines * sizeof(char *) );
78  top_line = line_pointer;
79
80  *line_pointer++ = page;
81
82/*
83 * Copy the file into memory.
84 */
85
86  fread(page,sizeof(char),fileinfo.st_size,file);
87
88/* put NULL at end of buffer. */
89
90  *(page + fileinfo.st_size) = '\0';
91
92/*
93 * Go through the file setting a line pointer to the character after each
94 * new line.  If we run out of line pointer space then realloc that space
95 * with space for more lines.
96 */
97
98  while (*page != '\0') {
99
100    if ( *page == '\n' ) {
101      *line_pointer++ = page + 1;
102
103      if (line_pointer >= top_line + nlines) {
104        top_line = (char **) realloc( top_line,
105                              (nlines + ADD_MORE_MEM) * sizeof(char *) );
106        line_pointer = top_line + nlines;
107        nlines += ADD_MORE_MEM;
108      }
109    }
110    page++;
111  }
112   
113/*
114 *  Realloc the line pointer space to take only the minimum amount of memory
115 */
116
117  nlines = line_pointer - top_line - 1;
118  top_line = (char **) realloc(top_line,nlines * sizeof(char *));
119
120/*
121 * Store the memory pointers into a structure that will be returned with
122 * the widget callback.
123 */
124
125  memory_struct->top_line = top_line;
126  memory_struct->top_of_page = top_of_page;
127
128  num_args = 0;
129  XtSetArg(arglist[num_args], XtNlines, nlines);
130  num_args++;
131   
132  XtSetValues(widget,arglist,num_args);
133}
134
135
136/*      Function Name: PrintPage
137 *      Description: This function prints a man page in a ScrollByLine widget.
138 *      Arguments: w - the ScrollByLine widget.
139 *                 structure_pointer - a pointer to the ManpageStruct.
140 *                 data - a pointer to the call data.
141 *      Returns: none.
142 */
143
144void
145PrintPage(w,struct_pointer,data)
146Widget w;
147caddr_t struct_pointer,data;
148{
149  MemoryStruct * info;
150  ScrollByLineStruct * scroll_info;
151  register char *bufp;
152  char **line;
153  int current_line;
154  char buf[BUFSIZ],*c;
155  int col,height,width,cur_pos;
156  int italicflag = 0;
157  int y_loc;                    /* vertical postion of text on screen. */
158  GC normal_gc,italic_gc;
159  Display * disp;
160  Window window;
161  Pixel fg;                     /* The foreground color. */
162  Arg arglist[1];               /* An argument list. */
163  Cardinal num_args;            /* The number of arguments. */
164
165  scroll_info = (ScrollByLineStruct *) data;
166  info = (MemoryStruct *) struct_pointer;
167
168  current_line = scroll_info->start_line;
169
170/* Use get values to get the foreground colors from the widget. */
171
172  num_args = 0;
173  XtSetArg(arglist[num_args], XtNforeground, &fg);
174  num_args++;
175  XtGetValues(w,arglist,num_args);
176
177  line = scroll_info->start_line + info->top_line;
178  c = *line;
179
180  disp = XtDisplay(w);
181  window = XtWindow(XtScrollByLineWidget(w));
182
183  /* find out how tall the font is. */
184
185  height = (fonts.normal->max_bounds.ascent +
186                   fonts.normal->max_bounds.descent);
187
188  normal_gc = XCreateGC(disp,window,0,NULL);
189  XSetForeground(disp,normal_gc,(unsigned long) fg);
190  XSetFont(disp,normal_gc,fonts.normal->fid);
191
192  italic_gc = XCreateGC(disp,window,0,NULL);
193  XSetForeground(disp,italic_gc,(unsigned long) fg);
194  XSetFont(disp,italic_gc,fonts.italic->fid);
195
196  /*
197   * Ok, here's the more than mildly heuristic page formatter.
198   * We put chars into buf until either a font change or newline
199   * occurs (at which time we flush it to the screen.)
200   */
201
202/*
203 * Because XDrawString uses the bottom of the text as a position
204 * reference, add one font height to the ScollByLine position reference.
205 */
206
207  y_loc = scroll_info->location + height;
208
209  for(buf[0] = '\0',bufp = buf,col=INDENT;;) {
210
211    switch(*c) {
212
213    case '\0':                /* If we reach the end of the file then return */
214      XFreeGC(disp,normal_gc);
215      XFreeGC(disp,italic_gc);
216      return;
217
218    case '\n':
219      *bufp = '\0';
220      if (*bufp != buf[0]) {
221        if(italicflag)          /* print the line as italic. */
222          XDrawString(disp,window,italic_gc,col,y_loc,buf,strlen(buf));
223        else {
224          XDrawString(disp,window,normal_gc,col,y_loc,buf,
225                      strlen(buf));
226        }
227      }
228      if (current_line++ == scroll_info->start_line +
229                            scroll_info->num_lines ) {
230        XFreeGC(disp,normal_gc);
231        XFreeGC(disp,italic_gc);
232        return;
233      }
234      col = INDENT;             
235      bufp = buf;
236      *bufp = '\0';
237      italicflag = 0;
238      y_loc += height;
239      break;
240
241    case '\t':                  /* TAB */
242      *bufp = '\0';
243
244      if (italicflag)
245        XDrawString(disp,window,italic_gc,col,y_loc,buf,strlen(buf));
246      else
247        XDrawString(disp,window,normal_gc,col,y_loc,buf,strlen(buf));
248      bufp = buf;
249      italicflag = 0;
250      cur_pos = XTextWidth(fonts.normal,buf,strlen(buf)) + col;
251      width =  XTextWidth(fonts.normal,"        ",8);
252      col = cur_pos - (cur_pos % width) + width;
253      break;
254
255    case '\033':                /* ignore esc sequences for now */
256      c++;                      /* should always be esc-x */
257      break;
258
259   case '_':                    /* look for underlining [italicize] */
260      c++;
261      if(*c != BACKSPACE) {
262
263        /* oops real underscore, fall through to default. */
264        c--;
265      }
266      else {
267        if(!italicflag) {       /* font change? */
268          *bufp = '\0';
269          XDrawString(disp,window,normal_gc,col,y_loc,
270                      buf,strlen(buf));
271          col += XTextWidth(fonts.normal,buf,strlen(buf));
272          bufp = buf;
273          *bufp = '\0';
274          italicflag = 1;
275        }
276        c++;
277        *bufp++ = *c;
278        break;
279      }
280
281    default:
282      if(italicflag) {                  /* font change? */
283        *bufp = '\0';
284        XDrawString(disp,window,italic_gc,col,y_loc,buf,strlen(buf));
285        col += XTextWidth(fonts.italic,buf,strlen(buf));       
286        bufp = buf;
287        *bufp = '\0';
288        italicflag = 0;
289      }
290      *bufp++ = *c;
291      break;
292    }
293    c++;
294  }
295}
Note: See TracBrowser for help on using the repository browser.