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

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