home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The CDPD Public Domain Collection for CDTV 3
/
CDPDIII.bin
/
pd
/
utilities
/
dirutils
/
visualshell
/
src
/
view.c
< prev
Wrap
C/C++ Source or Header
|
1992-10-29
|
15KB
|
498 lines
/*********************************
* *
* Visual Shell v1.17 10/92 *
* *
* by Torsten Jürgeleit *
* *
* view part *
* *
*********************************/
/* Includes */
#include "includes.h"
#include "imports.h"
#include "protos.h"
/* View file as ASCII or hex dump */
VOID
action_view(VOID)
{
struct FileRequest *freq = &file_req[active_freq];
struct FileNode *fnode;
if ((freq->fr_Mode == FREQ_MODE_NORMAL || freq->fr_Mode ==
FREQ_MODE_FIND) && freq->fr_CursorLine != -1) {
fnode = get_file_node_under_cursor(freq);
if (fnode->fn_Type == ENTRY_TYPE_FILE) { /* file selected ? */
print_status(view_file(freq, fnode));
}
}
}
/* View selected file */
SHORT
view_file(struct FileRequest *freq, struct FileNode *fnode)
{
struct ViewRequest *vreq = &view_req;
SHORT error = VSH_STATUS_NORMAL;
print_status(VSH_STATUS_READ_FILE);
hcomp_freq_cursor(freq);
print_info_line(INFO_LINE_MODE_EMPTY);
print_fkey_text(FKEY_MODE_NONE);
if ((error = read_view_file(freq, fnode, vreq)) == VSH_STATUS_NORMAL) {
USHORT vlines = vreq->vr_Display.d_VisibleLines;
print_view_page(vreq);
do {
ULONG signals = Wait(SIGF_INTUITION | SIGF_ACTION);
if (signals & SIGF_INTUITION) { /* timing events from Intuition */
struct IntuiMessage *msg;
if (msg = (struct IntuiMessage *)GetMsg(con_window->UserPort)) {
ULONG class = msg->Class;
ReplyMsg((struct Message *)msg);
switch (class) {
case REFRESHWINDOW :
print_view_page(vreq);
break;
case INTUITICKS :
if (status != VSH_STATUS_NORMAL) {
if (error_delay-- < 0) { /* remove error msg in status line */
print_vreq_status(vreq);
status = VSH_STATUS_NORMAL;
}
}
if (auto_repeat) {
scroll_view_req();
}
break;
}
}
}
if (signals & SIGF_ACTION) {
if (vreq->vr_MarkedEntries) {
print_vreq_lines(vreq, vreq->vr_Display.d_FirstVisibleNode,
(USHORT)0, vlines);
vreq->vr_MarkedEntries = 0;
}
switch (action) {
case VSH_ACTION_F1 : /* jump to line */
jump_to_view_line(vreq);
break;
case VSH_ACTION_F2 : /* start searching */
search_view_line(vreq, VIEW_SEARCH_MODE_FIRST);
break;
case VSH_ACTION_F3 : /* continue searching */
search_view_line(vreq, VIEW_SEARCH_MODE_NEXT);
break;
case VSH_ACTION_F4 : /* change view mode */
error = change_view_mode(vreq);
break;
case VSH_ACTION_F5 : /* print current page */
print_view_text(vreq, PRINT_MODE_PAGE);
break;
case VSH_ACTION_F6 : /* print whole text */
print_view_text(vreq, PRINT_MODE_ALL);
break;
case VSH_ACTION_SCROLL_UP :
case VSH_ACTION_SCROLL_DOWN :
case VSH_ACTION_SCROLL_PAGE_UP :
case VSH_ACTION_SCROLL_PAGE_DOWN :
case VSH_ACTION_SCROLL_TOP :
case VSH_ACTION_SCROLL_BOTTOM :
scroll_view_req();
break;
}
}
} while (error == VSH_STATUS_NORMAL && action != VSH_ACTION_QUIT &&
action != VSH_ACTION_ESC);
print_status(VSH_STATUS_FREE_LINE_LIST);
free_list(vreq->vr_Display.d_List, (LONG)sizeof(struct LineNode));
FreeMem(vreq->vr_Buffer, vreq->vr_BufferSize);
draw_requesters(DRAW_MODE_CLEAR);
} else {
hcomp_freq_cursor(freq);
print_info_line(INFO_LINE_MODE_NORMAL);
}
change_fkey_text();
return(error);
}
/* Display view page */
VOID
print_view_page(struct ViewRequest *vreq)
{
SetAPen(con_rport, (LONG)COLOR0);
RectFill(con_rport, (LONG)(BORDER_LEFT - 2), (LONG)(BORDER_TOP_HIDDEN
- 1), (LONG)(vsh_width - BORDER_RIGHT + 1), (LONG)(cli_vpos - 3));
draw_line(COLOR1, (USHORT)2, (USHORT)(BORDER_TOP_HIDDEN - 2), (USHORT)
(vsh_width - 3), (USHORT)(BORDER_TOP_HIDDEN - 2));
print_vreq_lines(vreq, vreq->vr_Display.d_FirstVisibleNode, (USHORT)0,
vreq->vr_Display.d_VisibleLines);
draw_line(COLOR1, (USHORT)2, (USHORT)(cli_vpos - 2), (USHORT)
(vsh_width - 3), (USHORT)(cli_vpos - 2));
print_fkey_text((USHORT)(FKEY_MODE_VIEW + vreq->vr_Mode));
print_vreq_status(vreq);
}
/* Read view file into buffer, check view mode and build line list */
SHORT
read_view_file(struct FileRequest *freq, struct FileNode *fnode,
struct ViewRequest *vreq)
{
USHORT len;
BPTR lock;
ULONG size;
BYTE *buffer;
BPTR fhandle;
SHORT error;
if (freq->fr_Mode == FREQ_MODE_FIND) {
strcpy(&path1_buffer[0], fnode->fn_Path);
} else {
strcpy(&path1_buffer[0], &freq->fr_DirName[0]); /* build path name */
}
len = strlen(&path1_buffer[0]);
if (path1_buffer[len - 1] != ':') {
path1_buffer[len] = '/';
len++;
}
vreq->vr_FileName = &path1_buffer[len];
strncpy(&path1_buffer[len], &fnode->fn_Text[0], (size_t)fnode->fn_NameLen);
path1_buffer[len + fnode->fn_NameLen] = '\0';
if (!(lock = quiet_lock(&path1_buffer[0], (LONG)SHARED_LOCK))) {
error = VSH_ERROR_LOCK_FAILED;
} else {
if (Examine(lock, fib) == DOSFALSE) {
error = VSH_ERROR_EXAMINE_FAILED;
} else {
if (!(size = fib->fib_Size)) {
error = VSH_ERROR_EMPTY_FILE;
} else {
if (!(buffer = AllocMem(size, MEMF_PUBLIC))) {
error = VSH_ERROR_OUT_OF_MEM;
} else {
if (!(fhandle = (BPTR)Open(&path1_buffer[0], (LONG)
MODE_OLDFILE))) {
error = VSH_ERROR_OPEN_FAILED;
} else {
if (Read(fhandle, buffer, size) == -1) {
error = VSH_ERROR_READ_FAILED;
} else {
vreq->vr_Buffer = buffer;
vreq->vr_BufferSize = size;
vreq->vr_MarkedEntries = 0;
print_status(VSH_STATUS_BUILD_LINE_LIST);
if (build_view_line_list(vreq, get_view_mode(vreq)) ==
FALSE) {
error = VSH_ERROR_OUT_OF_MEM;
} else {
vreq->vr_Display.d_FirstVisibleNode = vreq->vr_Display.d_List->mlh_Head;
Close(fhandle);
UnLock(lock);
return(VSH_STATUS_NORMAL);
}
free_list(vreq->vr_Display.d_List, (LONG)
sizeof(struct LineNode));
}
Close(fhandle);
}
FreeMem(buffer, size);
}
}
}
UnLock(lock);
}
return(error);
}
/* Jump to an line of viewed text or hex dump */
VOID
jump_to_view_line(struct ViewRequest *vreq)
{
struct MinNode *lnode;
ULONG line, num_entries = vreq->vr_Display.d_NumEntries;
USHORT vlines = vreq->vr_Display.d_VisibleLines;
if (num_entries > vlines) {
if (!get_input(INPUT_MODE_VIEW_LINE, NULL)) {
print_vreq_status(vreq);
} else {
line = gadget_info.LongInt;
if (! line || line > num_entries) {
print_status(VSH_ERROR_INVALID_LINE_NUM);
} else {
if (line > (num_entries - vlines)) {
line = num_entries - vlines + 1;
}
lnode = get_list_node(vreq->vr_Display.d_List,
vreq->vr_Display.d_NumEntries, line);
vreq->vr_Display.d_FirstVisibleNode = lnode;
print_vreq_lines(vreq, lnode, (USHORT)0, vlines);
print_vreq_status(vreq);
}
}
print_fkey_text((USHORT)(FKEY_MODE_VIEW + vreq->vr_Mode));
}
}
/* Search first line with specified text in viewed text or hex dump */
VOID
search_view_line(struct ViewRequest *vreq, USHORT mode)
{
struct LineNode *lnode = (struct LineNode *)
vreq->vr_Display.d_FirstVisibleNode;
BYTE hi, lo, *ptr, *string = &vreq->vr_LastSearchString[0];
ULONG num_entries = vreq->vr_Display.d_NumEntries;
USHORT i, len, vlines = vreq->vr_Display.d_VisibleLines;
SHORT error = VSH_STATUS_NORMAL;
if (mode == VIEW_SEARCH_MODE_FIRST) {
if (!(ptr = get_input(INPUT_MODE_VIEW_SEARCH, string))) {
len = 0;
} else {
if (len = strlen(ptr)) {
/* Save new search text */
strcpy(string, ptr);
}
}
} else {
print_fkey_text(FKEY_MODE_NONE);
if ((lnode->ln_Pos + vlines) < num_entries) {
lnode = (struct LineNode *)lnode->ln_Node.mln_Succ;
}
len = strlen(string);
}
if (len) {
/* Hex search ? */
if (*string == '$') {
if (len == 1 || !(len & 1)) {
error = VSH_ERROR_INVALID_HEX_NUM;
} else {
/* Convert hex to binary */
for (i = 1; i < len; i += 2) {
hi = toupper(*++string);
if (hi >= 'A' && hi <= 'F') {
hi -= 'A' - 10;
} else {
if (hi >= '0' && hi <= '9') {
hi -= '0';
} else {
error = VSH_ERROR_INVALID_HEX_NUM;
break;
}
}
lo = toupper(*++string);
if (lo >= 'A' && lo <= 'F') {
lo -= 'A' - 10;
} else {
if (lo >= '0' && lo <= '9') {
lo -= '0';
} else {
error = VSH_ERROR_INVALID_HEX_NUM;
break;
}
}
*ptr++ = (hi << 4) + lo;
}
len = (i - 1) / 2;
string = &gadget_buffer[0];
}
}
if (error == VSH_STATUS_NORMAL) {
/* Search and mark view lines */
if (!(lnode = search_line_node(lnode, string, len))) {
error = VSH_ERROR_SEARCH_FAILED;
} else {
mark_search_view_lines(vreq, lnode, string, len);
}
}
}
print_fkey_text((USHORT)(FKEY_MODE_VIEW + vreq->vr_Mode));
if (error == VSH_STATUS_NORMAL) {
print_vreq_status(vreq);
} else {
print_status(error);
}
}
/* Mark search view lines */
VOID
mark_search_view_lines(struct ViewRequest *vreq, struct LineNode *lnode,
BYTE *string, USHORT len)
{
struct MinNode *fv_lnode = (struct MinNode *)lnode;
ULONG fv_pos, num_entries = vreq->vr_Display.d_NumEntries;
USHORT i, vlines = vreq->vr_Display.d_VisibleLines;
if (num_entries > vlines) {
if (lnode->ln_Pos > (num_entries - vlines)) {
for (i = lnode->ln_Pos - (num_entries - vlines) - 1; i; i--) {
fv_lnode = fv_lnode->mln_Pred;
}
}
vreq->vr_Display.d_FirstVisibleNode = fv_lnode;
print_vreq_lines(vreq, fv_lnode, (USHORT)0, vlines);
} else {
fv_lnode = vreq->vr_Display.d_FirstVisibleNode;
}
fv_pos = ((struct LineNode *)fv_lnode)->ln_Pos;
do {
hcomp_vreq_line(vreq, (USHORT)(lnode->ln_Pos - fv_pos));
vreq->vr_MarkedEntries++;
lnode = search_line_node((struct LineNode *)lnode->ln_Node.mln_Succ,
string, len);
} while (lnode && (lnode->ln_Pos - fv_pos) < vlines);
}
/* Change view mode */
SHORT
change_view_mode(struct ViewRequest *vreq)
{
struct LineNode *fv_node;
ULONG num_entries, old_offset = ((struct LineNode *)
vreq->vr_Display.d_FirstVisibleNode)->ln_Offset;
USHORT i, vlines = vreq->vr_Display.d_VisibleLines;
SHORT error = VSH_STATUS_NORMAL;
print_status(VSH_STATUS_CHANGE_VIEW_MODE);
print_fkey_text(FKEY_MODE_NONE);
SetAPen(con_rport, (LONG)COLOR0);
RectFill(con_rport, (LONG)(BORDER_LEFT - 2), (LONG)(BORDER_TOP_HIDDEN -
1), (LONG)(vsh_width - BORDER_RIGHT + 1), (LONG)(cli_vpos - 3));
vreq->vr_Mode = (vreq->vr_Mode == VIEW_MODE_ASCII ? VIEW_MODE_HEX :
VIEW_MODE_ASCII);
free_list(vreq->vr_Display.d_List, (LONG)sizeof(struct LineNode));
if (build_view_line_list(vreq, vreq->vr_Mode) == FALSE) {
error = VSH_ERROR_OUT_OF_MEM;
action = VSH_ACTION_QUIT; /* quit view */
} else {
num_entries = vreq->vr_Display.d_NumEntries;
if (num_entries > vlines) {
fv_node = get_first_visible_line(vreq, old_offset);
if ((num_entries - fv_node->ln_Pos + 1) < vlines) {
for (i = vlines - (num_entries - fv_node->ln_Pos + 1); i; i--) {
fv_node = (struct LineNode *)fv_node->ln_Node.mln_Pred;
}
}
} else {
fv_node = (struct LineNode *)vreq->vr_Display.d_List->mlh_Head;
}
vreq->vr_Display.d_FirstVisibleNode = (struct MinNode *)fv_node;
print_vreq_lines(vreq, (struct MinNode *)fv_node, (USHORT)0,
vreq->vr_Display.d_VisibleLines);
print_fkey_text((USHORT)(FKEY_MODE_VIEW + vreq->vr_Mode));
print_vreq_status(vreq);
}
return(error);
}
/* Print viewed text as ASCII or hex dump */
VOID
print_view_text(struct ViewRequest *vreq, USHORT mode)
{
struct LineNode *lnode;
ULONG i, end;
BPTR fh;
SHORT error = VSH_STATUS_NORMAL;
print_status(VSH_STATUS_PRINT_TEXT);
print_fkey_text(FKEY_MODE_NONE);
if (mode == PRINT_MODE_PAGE) {
lnode = (struct LineNode *)vreq->vr_Display.d_FirstVisibleNode;
end = vreq->vr_Display.d_NumEntries - lnode->ln_Pos + 1;
/* Check if fewer lines are available than possible to view on page */
if (end > vreq->vr_Display.d_VisibleLines) {
end = vreq->vr_Display.d_VisibleLines;
}
} else {
lnode = (struct LineNode *)vreq->vr_Display.d_List->mlh_Head;
end = vreq->vr_Display.d_NumEntries;
}
if (!(fh = (BPTR)Open("PRT:", (LONG)MODE_NEWFILE))) {
error = VSH_ERROR_NO_PRINTER;
} else {
enable_abort = 1;
for (i = 0; i < end && error == VSH_STATUS_NORMAL; i++) {
if (CheckAbort(NULL)) {
error = VSH_ERROR_ABORTED;
} else {
if (FPrintf(fh, "%s\n", build_vreq_line(vreq, lnode,
LINE_MODE_NO_FILL)) < 0) {
error = VSH_ERROR_PRINTING_FAILED;
} else {
lnode = (struct LineNode *)lnode->ln_Node.mln_Succ;
}
}
}
enable_abort = 0;
Close(fh);
}
print_fkey_text((USHORT)(FKEY_MODE_VIEW + vreq->vr_Mode));
if (error != VSH_STATUS_NORMAL) {
print_status(error);
} else {
print_vreq_status(vreq);
}
}
/* Print quick view */
VOID
print_quick_view(struct FileRequest *freq1)
{
struct FileRequest *freq2 = (&file_req[0] == freq1 ? &file_req[1] :
&file_req[0]);
struct FileNode *fnode;
BPTR fhandle;
BYTE *buffer, *file = &path1_buffer[0];
USHORT len = 0;
LONG buffer_size = freq2->fr_Display.d_VisibleLines *
MAX_QVIEW_BYTES_PER_LINE;
SHORT error = VSH_STATUS_NORMAL;
if (!(buffer = AllocMem(buffer_size, MEMF_PUBLIC))) {
error = VSH_ERROR_OUT_OF_MEM;
} else {
/* Valid file requester mode? */
if (freq2->fr_Mode != FREQ_MODE_DEVS_ASN) {
/* Empty file requester? */
if (fnode = get_file_node_under_cursor(freq2)) {
/* File selected */
if (fnode->fn_Type == ENTRY_TYPE_FILE) {
/* Read start of file into allocated buffer */
build_path_name_from_file_node(file, freq2, fnode);
if (!(fhandle = (BPTR)Open(file, (LONG)MODE_OLDFILE))) {
error = VSH_ERROR_OPEN_FAILED;
} else {
if (Read(fhandle, buffer, buffer_size) != buffer_size) {
error = VSH_ERROR_READ_FAILED;
} else {
len = buffer_size;
}
Close(fhandle);
}
}
}
}
print_quick_view_lines(freq1, buffer, len);
FreeMem(buffer, buffer_size);
}
if (event_mode != EVENT_MODE_INPUT) {
print_status(error);
}
}