OOP344
As your first assignment this semester, you are to write a multi-platform direct terminal library and later use that library to create a text editor.
Console Input Output Library
Due date: October 10, 2009
Basic Console Input Output
You are to write a program that places characters at various positions on a screen using a direct terminal library module. Your library module is named io and contains the following functions:
Specifications
void io_init(void)
Initializes the io routines. Your application calls this function before calling any other io function and only once before calling io_end().
void io_end(void)
Shuts down the io routines and ensures that the cursor is not left in the middle of the screen, which may be partly filled with characters. Any application that has called io_init() should call this function before terminating.
int io_rows(void)
Returns the number of rows on the screen.
int io_cols(void)
Returns the number of columns on the screen.
void io_clrscr(void)
Clears the screen and leaves the cursor in the upper left-hand corner of the screen.
void io_flush(void)
Ensures that any output sent to the screen is displayed on the screen (that is, this function flushes the output buffer). ===int io_getch(void)=== returns the virtual key code identifying the key pressed by the user. This function first displays all output that has been sent to the screen (if any is pending to be displayed), waits for a key to be pressed and returns an int value that uniquely identifies the key pressed. To accommodate platform dependency, define the following symbolic names for the non-ASCII keys in each platform:
- UP_KEY - the up arrow key value,
- DOWN_KEY - the down arrow key value,
- LEFT_KEY - the left arrow key value,
- RIGHT_KEY - the right arrow key value,
- PGUP_KEY - the Page Up key value,
- PGDN_KEY - the Page Down key value,
- HOME_KEY - the Home key value,
- END_KEY - the End key value,
- ENTER_KEY - the Enter key value,
- TAB_KEY - the Tab key value,
- BACKSPACE_KEY - the Backspace key value,
- ESCAPE_KEY - the Escape key value,
- DEL_KEY - the Delete key value,
- INSERT_KEY - the Insert key value,
- F1_KEY to F12_KEY - the function key value,
You must use platform specific and unique non-ASCII values for the keys, and then you must use these specific symbolic names in your definitions.
void io_move(int r, int c)
Positions the cursor at row r and column c, where row 0 is the top row and column 0 is the leftmost column. If either parameter is invalid, your function has undefined results. Your function does not flush any output buffer.
void io_putch(int c)
Displays the character c at the current cursor position and advances the cursor by one position to the right. If the cursor is already at the rightmost column of the screen, the advance is system dependent. This function does not flush any output buffer.
void io_putstr(const char *s)
Displays the null-terminated string pointed to by s starting at the current cursor position. Your function leaves the cursor just after the last character displayed. If the string exceeds in length the available space on the current line of output, your function has undefined results. Your function does not flush any output buffer.
void io_display(const char *str, int row, int col, int len)
Outputs the null-terminated string pointed to by "str", on the screen starting at row "row" and column "col" on the screen, upto "len" characters. As with io_move(), 0 is the top row, and 0 is the leftmost column. If the string is longer than "len", then only "len" characters are displayed, but if it is shorter than "len", then the entire string is displayed left-justified in the field. However, if "len" is 0 or less, then the field length is considered to be the actual length of the string (i.e. the entire string is displayed). Afterwards, the cursor is positioned after the last character of the field. (Note that on systems where output is buffered, this function should not flush the output buffer). The results are undefined if the specified values indicate a field that does not fit on the screen.
Line and Selection Editor
Line Editor: int io_edit(........)
int io_edit(char* str, int row, int col, int fieldlen, int maxdatalen, int *insertmode, int* offset, int* curpos, int IsTextEditor)
Allows the user to perform full screen editing of the null-terminated string pointed to by "str". The parameter "row" identifies the row of the screen for the field (O is the top row), while "col" indicates the starting column of the field (0 is the left-most column). The parameter "maxdatalen" specifies the maximum length of the string "str". The parameter "fieldlen" specifies the length of the field in which editing is to be performed (visible area of “str”). The pointer "offset" points to an integer, holding the index of the first character of "str", shown in the field. The pointer "curpos" points to an integer holding the position of the cursor in the field (0 is the first position). "insertmode" is a pointer pointing to an integer flag, that is true (1) for insert mode being on, or false (0) for insert mode being off.
If any of insertmode, curpos or offset is NULL then a local integer variable will be used instead. If local variables are used for any of insertmode, curpos, or offset, the default values will be 1, 0, and 0 respectively.
Editing begins with the display of "str" from where "*offset" is referring to, and the cursor will be standing at the position which "*curpos" is indicating. NOTE: Following corrections should be done to "*curpos" and "*offset" in case they hold invalid values before editing begins:
- Set the "*curpos" so that cursor stands at the last position of the field if it exceeds fieldlen.
- If "*offset" is greater than the length of the string, set the "*offset" so the “last character of str” is hidden right before the first space in the field.
- After the above, if cursor is past last character of “str” set "*curpos" so the cursor stands right after the last character of "str".
The cursor is never allowed to move before the start of the field, more than one position past the last character in the string, or after the end of the field.
Editing is terminated by pressing ENTER, TAB, UP, DOWN, PGUP, PGDN or any of the function keys, F1 to F12. Pressing ESCAPE will terminate the io_edit(). If ESCAPE is used, Then editing is aborted - the string is left containing the data originally passed to io_edit().
Note that the conditions of termination are changed if “IsTextEditor” flag is true (non-zero). See “IsTextEditor” section for detail.
The function returns an int identifying the key that was pressed to exit. (This function uses the same key codes as io_getch())
The function takes no action if the user tries to enter too many characters (if, for example, the string is full in insert mode, or the cursor is positioned after the last character of a full string in overstrike mode). However if curser reaches the end of the field and the string is not full then after inserting the character string will be scrolled to left, positioning the curser right after the last character in the string.
The function handles at least the following special keys:
- LEFT - move cursor left one character. If cursor is at the beginning of the field and there is hidden data before the cursor, then shift string to right instead.
- RIGHT - move cursor right one character. If cursor is at the end of the field but not at the end of the string, then scroll one to left.
- HOME – move cursor to the beginning of the string. Scroll all the way to right if necessary. (i.e. if there is hidden data at the beginning)
- END - go to the end of the data in the string, i.e. just past the last character in the string. Scroll all the way to left if necessary.
- INSERT - toggle Insert/Overstrike mode
In Insert mode, printable characters are inserted into the string, moving the remainder of the string to the right to make room. In Overstrike mode, printable characters overwrite existing characters (if any). Note that if you are past the end of the string, printable characters are appended to the string (as long as the string isn't full) regardless of the mode. Also note that, regardless of the mode, the cursor advances as printable characters are typed into the string. Finally, if the cursor is at the end of the field, instead of moving to right, the characters are shifted to left. - DEL – eat the current character above the cursor and move all subsequent characters one position to the left.
- BACKSPACE - move the rest of the field (including the cursor) one position to the left, eating the previous character.
IsTextEditor:
If IsTextEditor is true, then it means that the function is being used to edit a text by editing one line of the text at a time. Doing so, since shifting a line to left or right should not only cause the editing line to be shifted, but also the rest of the lines in the text. To do this io_edit should let the calling function take care of shifting instead of doing it, itself. Since shifting essentially means modifying “*offset”, if “IsTextEditor” is true, then at anytime you find “*offset” needs to be modified, you should terminate the function instead and return the terminating key. Also when IsTextEditor is true, When Escape is hit do not abort the editing but simply terminate the function returning the Escape key.
Any normal printable key is simply placed into the string according to the rules laid out in the discussion of the INSERT key above. (The keys from the space character to the tilde character in the ASCII table are considered "printable".)
The io_edit() function always shows blanks in any the part of the field that is not occupied by the data in the string. UNDER NO CIRCUMSTANCES DOES THE FUNCTION CHANGE ANY POSITION ON THE SCREEN OUTSIDE OF THE FIELD.
Like most C library functions, your io_edit() may assume that it is the calling program's responsibility to ensure that the array is large enough to handle the specified number of characters, and that the starting screen position provides enough room (on the screen) for the field, etc.
Note:
If memory allocation for aborting the edit (ESCAPE KEY) fails, quit the function returning -1.
Selection Editor
int io_displayflag(..........)
int io_displayflag(const char *format, int row, int col, int status);
Allows the user to display a checkbox at row and col on the screen. Depending on the value of status; being zero or non-zero, the checkbox will be checked or unchecked respectively.
The checkbox will be always shown using 3 characters; two surrounding characters and one character in the middle as the checkmark. If the status argument is zero, then the checkmark will be replaced with space. The 3 characters and held in “format” array; format[0] and format[2] are surrounding characters and format[1] is the check-mark.
After the checkbox is displayed, the cursor is always place under the checkmark (in centre).
int io_flag(..........)
int io_flag(const char *format, int row, int col, int* status, int radio);
io_flag() allows the user to make a single true/false selection. "status" points to the status of the selection, that can be zero or non-zero. If "status" is initially set to anything but zero, io_flag() corrects value to one. "format" holds the shape of the checkbox as io_displayflag() function.
io_flag() begins the selection by displaying the checkbox according to its “*status”. (Remember that the value of "*status" is corrected before the editing begins). Then the function waits for the user input.
- If the user input is any of the printable keys (' ' < key <= '~') excluding space, it should be ignored (no action taken). If the user input is any of the function keys, the function is terminated returning the key.
- If the user input is SPACE:
- If “radio” is true, then the *status is set to one, checkbox is displayed and function is terminated returning space.
- If “radio” is false, then the value of *status is toggled between 0 and 1, the checkbox is displayed and function is exited returning space.