home *** CD-ROM | disk | FTP | other *** search
- /*********************************SCREEN.C***************************************/
-
- /*
- * Author: Mark Nelson
- *
- * Date: October 28, 1989
- *
- * Description: This module contains the screen I/O routines used in
- * the heap debugger module. These are very simplified
- * screen I/O routines.
- */
-
- #include <stdio.h>
- #include <stdarg.h>
- #include <string.h>
- #include "_heap.h"
- /*
- * These are all the line drawing constants defined.
- */
- #define UL_CORNER 218
- #define UR_CORNER 191
- #define LL_CORNER 192
- #define LR_CORNER 217
- #define UPPER_TEE 194
- #define LOWER_TEE 193
- #define LEFT_TEE 195
- #define RIGHT_TEE 180
- #define CENTER_TEE 197
- #define HORIZONTAL_LINE 196
- #define VERTICAL_LINE 179
-
- /*
- * I create a structure so I can write directly to screen as if it were
- * a big array. That way the compiler takes care of computing the
- * addresses, all I have to do is insert the row and column.
- */
- struct video_element {
- unsigned char character;
- unsigned char attribute;
- };
- struct video_element (far *physical_screen)[25][80];
- struct video_element saved_screen[25][80];
-
- /*
- * This routine draws the box I use up on the screen. It is passed a
- * list of labels to draw at the head of the columns, plus a count
- * of how many rows are to be left open for data entry. It depends
- * on some earlier code somewhere to have initialized an array called
- * columns[] that tells it where to draw each column on the screen.
- * There is a lot of code here to draw the boxes, but it is all
- * straightforward.
- */
- int columns[10];
- int column_count=0;
-
- void draw_boxes_and_titles(char *labels[],int row_count)
- {
- int col;
- int row;
- int i;
- int j;
- int rows[3];
- /*
- * The three rows I define are the top and bottom of the box, plus the
- * line that divides the title lines from the data lines.
- */
- rows[0]=0;
- rows[1]=2;
- rows[2]=3+row_count;
- for (col=1;col<columns[column_count];col++)
- for (i=0;i<3;i++)
- (*physical_screen)[rows[i]][col].character = HORIZONTAL_LINE;
- for (i=0;i<=column_count;i++)
- for (row=0;row<(row_count+4);row++)
- (*physical_screen)[row][columns[i]].character = VERTICAL_LINE;
- (*physical_screen)[0][columns[0]].character = UL_CORNER;
- (*physical_screen)[row_count+3][columns[0]].character = LL_CORNER;
- (*physical_screen)[0][columns[column_count]].character = UR_CORNER;
- (*physical_screen)[row_count+3][columns[column_count]].character = LR_CORNER;
-
- (*physical_screen)[rows[1]][columns[0]].character = LEFT_TEE;
- (*physical_screen)[rows[1]][columns[column_count]].character = RIGHT_TEE;
- for (j=1;j<column_count;j++)
- (*physical_screen)[0][columns[j]].character = UPPER_TEE;
- for (j=1;j<column_count;j++)
- (*physical_screen)[row_count+3][columns[j]].character = LOWER_TEE;
-
- for (j=1;j<column_count;j++)
- (*physical_screen)[rows[1]][columns[j]].character = CENTER_TEE;
- /*
- * Here is where I draw the labels. They need to go in the center of
- * their little boxes.
- */
- for (i=0;i<column_count;i++)
- {
- col=columns[i]+1;
- col += (columns[i+1]-columns[i]-1)/2;
- col -= strlen(labels[i])/2;
- screenputs(1,col,labels[i]);
- }
- }
- /*
- * This is a general purpose routine to print a formatted string on
- * the screen.
- */
- void screenputf(int row,int col,char *format,...)
- {
- char buffer[81];
- va_list args;
-
- va_start(args,format);
- vsprintf(buffer,format,args);
- screenputs(row,col,buffer);
- }
- /*
- * This is a general purpose routine to put an unformatted string
- * out to the screen.
- */
- void screenputs(int row,int col,char *string)
- {
- char c;
-
- while (1)
- {
- c=*string++;
- if (c=='\0')
- break;
- (*physical_screen)[row][col++].character=c;
- }
- }
- /*
- * This is a general purpose routine to clear a whole line on the
- * screen.
- */
- void screenclearline(int row)
- {
- int col;
-
- for (col=0;col<80;col++)
- (*physical_screen)[row][col].character=' ';
- }
- /*
- * This is the screen initialization code. It is a trap door routine that
- * gets called all the time, but only executes once. It computes what
- * columns the vertical lines are going to go in, based on the widths needed
- * for each column, passed as a parameter.
- * Note that if you are using a monochrome monitor, you need to change
- * the screen pointer to be 0xb0000000L.
- * This routine also initializes the tag table
- */
- void initialize_screen(char *labels[],int widths[])
- {
- int row;
- int col;
- int i;
- static int first_time=0;
-
- if (first_time==0)
- {
- first_time=1;
- columns[0]=1;
- column_count=0;
- while (strlen(labels[column_count]) != 0)
- {
- columns[column_count+1] = columns[column_count]+widths[column_count]+1;
- column_count++;
- }
- }
- physical_screen=(struct video_element (far *)[25][80])0xb8000000L;
- for (row=0;row<25;row++)
- for (col=0;col<80;col++)
- {
- saved_screen[row][col]=(*physical_screen)[row][col];
- (*physical_screen)[row][col].character=' ';
- (*physical_screen)[row][col].attribute=0x1b;
- }
- }
-
- /*
- * Whenever the heap routines decide they need to print a screen message,
- * they set up the screen first by calling this guy.
- */
- void setup_screen(char *labels[],int widths[],int rows)
- {
- initialize_screen(labels,widths);
- draw_boxes_and_titles(labels,rows);
- }
-
- /*
- * After the heap routines are done printing debug information, they
- * have to restore the screen back to where it was when they got called.
- * This routine does that.
- */
- void restore_screen()
- {
- int row;
- int col;
-
- for (row=0;row<25;row++)
- for (col=0;col<80;col++)
- (*physical_screen)[row][col]=saved_screen[row][col];
- }
-
-