📄 fv.file.c
字号:
#ifndef lintstatic char sccsid[] = "@(#)fv.file.c 1.1 92/07/30 Copyr 1988 Sun Micro";#endif/* Copyright (c) 1987, 1988, Sun Microsystems, Inc. All Rights Reserved. Sun considers its source code as an unpublished, proprietary trade secret, and it is available only under strict license provisions. This copyright notice is placed here only to protect Sun in the event the source is deemed a published work. Dissassembly, decompilation, or other means of reducing the object code to human readable form is prohibited by the license agreement under which this code is provided to the user or company in possession of this copy. RESTRICTED RIGHTS LEGEND: Use, duplication, or disclosure by the Government is subject to restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in Technical Data and Computer Software clause at DFARS 52.227-7013 and in similar clauses in the FAR and NASA FAR Supplement. */#include <stdio.h>#include <errno.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/file.h>#include <sys/wait.h>#include <string.h>#ifdef OS3# include <sys/dir.h>#else# include <dirent.h>#endif#ifdef SV1#include <suntool/sunview.h>#include <suntool/panel.h>#include <suntool/tty.h>#include <suntool/textsw.h>#include <suntool/canvas.h>#include <suntool/scrollbar.h>#include <suntool/alert.h>#include <suntool/fullscreen.h>#else#include <view2/view2.h>#include <view2/panel.h>#include <view2/tty.h>#include <view2/textsw.h>#include <view2/canvas.h>#include <view2/scrollbar.h>#include <view2/alert.h>#include <view2/fullscreen.h>#include <view2/seln.h>#endif#include "fv.port.h"#include "fv.h"#include "fv.extern.h"/* The following three arrays contain the 8 or so RGB values for colors */#include "fv.colormap.h"u_char Fv_red[CMS_FVCOLORMAPSIZE];u_char Fv_blue[CMS_FVCOLORMAPSIZE];u_char Fv_green[CMS_FVCOLORMAPSIZE];#define COLOR_FILE "..color" /* Contains sorted pairs of color/name*/static short Ncolors; /* # color entries in COLOR_FILE*/static char *Color_fname[MAXFILES]; /* Name... */static SBYTE Color_code[MAXFILES]; /* ...and color pairs */static int Maxfilesperline; /* Maximum files per line */static int Incx; /* Columnar Increment */static int Startx; /* Starting location */static short Widest_name; /* Widest file name *//* Variable and fixed widths for List Options */static short Permission_width[2] = {8, 11}; static short Link_width[2] = {3, 5};static short Owner_width[2] = {5, 9};static short Group_width[2] = {5, 9};static short Size_width[2] = {5, 9};static short Date_width[2] = {9, 14};static char Last_edited[MAXPATH]; /* Last edited filename */#define ERASE 0177 /* Delete key on Sun-3 keyboards */#define MAXRENAMELEN 80 /* Max length of rename string */#define THRESHOLD 4 /* Move/copy mode (in pixels) */#define LIST_HEIGHT 20 /* Height of lines in List mode */static int compare_name(), compare_time(), compare_size(), compare_type(), compare_color();static ROUTINE Compare_fn[FV_SORTCOLOR+1] = { compare_name, compare_time, compare_size, compare_type, compare_color,};extern time_t time();static short If_image[] = {#include "folderwin.icon"};mpr_static_static(f_icon_pr, 64, 48, 1, If_image);static short Id_image[] = {#include "docwin.icon"};mpr_static_static(d_icon_pr, 64, 64, 1, Id_image);#ifdef SV1static struct icon F_icon;static struct icon D_icon;#endif#define MAX_TEXTSW 32#ifdef SV1static int Edit_id[MAX_TEXTSW];static Textsw Edit_sw[MAX_TEXTSW];#endifstatic Frame Edit_fr[MAX_TEXTSW];static int Edit_no;#define MAX_FOLDERS 16static Frame Folder_frame[MAX_FOLDERS]; /* Folder frames */static int Nfolders;static int Max_alloc; /* Number of allocated FV_FILE */#define SIX_MONTHS_IN_SECS 15552000#define HOUR_IN_SECS 3600#define ICON_AREA_HEIGHT 66 /* Icon height + text height + gap */static Panel Text_panel;static Panel_item Text_item;static int Scroll_increment;static int Renamed_file; /* Index in Fv_file */static void stop_editing();#ifdef SV1# define GET_SCROLL_VIEW_START (int)scrollbar_get(Fv_foldr.vsbar, SCROLL_VIEW_START)#else# define GET_SCROLL_VIEW_START ((int)scrollbar_get(Fv_foldr.vsbar, SCROLL_VIEW_START) * Scroll_increment)#endifvoidfv_create_folder() /* Create folder canvas */{ register int i; /* Index */ Notify_value folder_event(); static int display_folder(); struct singlecolor *color; Fv_foldr.canvas = window_create(Fv_frame, CANVAS, CANVAS_FAST_MONO, TRUE, CANVAS_AUTO_SHRINK, FALSE, CANVAS_AUTO_CLEAR, FALSE, CANVAS_RETAINED, FALSE, CANVAS_REPAINT_PROC, display_folder, CANVAS_FIXED_IMAGE, FALSE, WIN_BELOW, Fv_tree.canvas, WIN_X, 0, WIN_Y, 0, WIN_ROWS, 10, WIN_VERTICAL_SCROLLBAR, Fv_foldr.vsbar = scrollbar_create(#ifdef SV1 SCROLL_PLACEMENT, SCROLL_EAST, 0#endif ), 0);#ifdef SV1 Fv_foldr.pw = (PAINTWIN)canvas_pixwin(Fv_foldr.canvas); Fv_color = Fv_foldr.pw->pw_pixrect->pr_depth > 1;#else Fv_foldr.pw = (PAINTWIN)vu_get(Fv_foldr.canvas, CANVAS_NTH_PAINT_WINDOW, 0); Fv_color = (int)vu_get(Fv_frame, WIN_DEPTH) > 1;#endif if (Fv_color) { /* Apply color first; then decide whether this is a color monitor. * Otherwise we have problems with single color monitor systems that * have the monochrome and color framebuffer on the same device. * Later: * Shit! We still screwed. If you supply color on a monochrome * device we try and use it. (It appears black.) */ cms_fvcolormapsetup(Fv_red, Fv_green, Fv_blue); if (window_get(Fv_frame, FRAME_INHERIT_COLORS)) { /* Grab the current background and foreground color and * replace our generic colors (white and black). * Reverse video display and color inheritance cause * problems. */ color = (struct singlecolor *)window_get(Fv_frame, FRAME_FOREGROUND_COLOR); Fv_red[CMS_FVCOLORMAPSIZE-1] = Fv_red[1] = color->red; Fv_green[CMS_FVCOLORMAPSIZE-1] = Fv_green[1] = color->green; Fv_blue[CMS_FVCOLORMAPSIZE-1] = Fv_blue[1] = color->blue; color = (struct singlecolor *)window_get(Fv_frame, FRAME_BACKGROUND_COLOR); Fv_red[0] = color->red; Fv_green[0] = color->green; Fv_blue[0] = color->blue; } pw_setcmsname(Fv_foldr.pw, "FVCOLORMAP"); pw_putcolormap(Fv_foldr.pw, 0, CMS_FVCOLORMAPSIZE, Fv_red, Fv_green, Fv_blue); }#ifdef SV1 notify_interpose_event_func(Fv_foldr.canvas, folder_event, NOTIFY_SAFE);#else notify_interpose_event_func(Fv_foldr.pw, folder_event, NOTIFY_SAFE);#endif /* Look for events */ window_set(#ifdef SV1 Fv_foldr.canvas,#else Fv_foldr.pw,#endif WIN_CONSUME_PICK_EVENTS, LOC_WINENTER, LOC_WINEXIT, ERASE, SHIFT_CTRL, LOC_DRAG, KEY_LEFT(K_PROPS), KEY_LEFT(K_UNDO), KEY_LEFT(K_PUT), KEY_LEFT(K_GET), KEY_LEFT(K_FIND), KEY_LEFT(K_DELETE), 0, 0); /* Create a text panel for editing on the canvas */ Text_panel = window_create(Fv_frame, PANEL, WIN_SHOW, FALSE, WIN_HEIGHT, 20, 0); Text_item = panel_create_item(Text_panel, PANEL_TEXT, PANEL_VALUE_STORED_LENGTH, 255, PANEL_VALUE_X, 0, PANEL_VALUE_Y, 0, PANEL_NOTIFY_PROC, stop_editing, 0); /* Allocate enough memory for file structures. * Allocating memory dynamically instead of statically allows * us to swap pointers instead of copying structures whilst * sorting, etc. */ Max_alloc = 128; for (i=0; i<Max_alloc; i++) { Fv_file[i] = (FV_FILE *)fv_malloc(sizeof(FV_FILE)); if (Fv_file[i] == NULL) break; }}fv_file_scroll_height() /* Set scroll increment */{ Scroll_increment = Fv_style & FV_DICON ? ICON_AREA_HEIGHT : LIST_HEIGHT; scrollbar_set(Fv_foldr.vsbar, SCROLL_LINE_HEIGHT, Scroll_increment, 0);}static Notify_valuefolder_event(cnvs, evnt, arg, typ) /* Process canvas events */ Canvas cnvs; register Event *evnt; Notify_arg arg; Notify_event_type typ;{ static struct timeval last_click; /* Last click time */ struct timeval click; /* Click time */ static int last_selected=EMPTY; /* Last file selected */ int x, y; /* Name coordinates */ register int i; /* Index */ char *b_p; /* String pointer */#ifndef SV1 char buf[MAXPATH]; /* Move request buffer */ Fullscreen fs; /* Drag detect whilst but down */#endif#ifndef SV1 if (event_action(evnt) == ACTION_DRAG_LOAD) { /* Somebody is trying drop a file over me. Move the file * indicated by the primary selection into this folder. */ Seln_holder holder; Seln_request *sbuf; holder = seln_inquire(SELN_PRIMARY); if (holder.state == SELN_NONE) fv_putmsg(TRUE, "No selection!", 0, 0); else { fv_busy_cursor(TRUE); sbuf = seln_ask(&holder, SELN_REQ_CONTENTS_ASCII, 0, 0); /* This maybe a mail message... */ if (strncmp(sbuf->data+sizeof(Seln_attribute), "/tmp/MailItemsFor", 17) == 0 && (i = over_object(event_x(evnt), event_y(evnt))) != EMPTY) { if (!Fv_file[i]->selected) { fv_reverse(i); Fv_file[i]->selected = TRUE; } sprintf(buf, "/bin/cat %s %s > .X 2>/tmp/.err; /bin/mv .X %s 2>/tmp/.err", Fv_file[i]->name, sbuf->data+sizeof(Seln_attribute), Fv_file[i]->name); if (system(buf)) fv_showerr(); else Fv_current->mtime = time(0); fv_putmsg(FALSE, "Mail message appended to folder %s", Fv_file[i]->name, 0); } else { /* Move the file in */ sprintf(buf, "mv %s . 2>/tmp/.err", sbuf->data+sizeof(Seln_attribute)); if (system(buf)) fv_showerr(); else fv_display_folder(FV_BUILD_FOLDER); } fv_busy_cursor(FALSE); } }#endif if (event_is_down(evnt)) if (event_id(evnt) == MS_LEFT) { /* Clear old message */ fv_clrmsg(); /* Ensure that we're still in this folder, (we could * have changed to another by merely selecting another * folder in the tree...) */ if (Fv_treeview && Fv_tselected != Fv_current) { /* We're in deep shit if we can't open current folder */ if (chdir(Fv_openfolder_path)==-1) fv_putmsg(TRUE, Fv_message[MECHDIR], Fv_openfolder_path, sys_errlist[errno]); (void)strcpy(Fv_path, Fv_openfolder_path); } i=over_object_name(event_x(evnt), event_y(evnt)); if (i != EMPTY && Fv_file[i]->selected && Fv_write_access) { /* The user wishes to rename this file. Place a panel * text field over the existing filename. */ Renamed_file = i; y = trans(Renamed_file)-GET_SCROLL_VIEW_START; x = text_start(Renamed_file); if (Fv_style & FV_DICON) y += GLYPH_HEIGHT+Fv_fontsize.y-10; else y += LIST_HEIGHT-10; b_p = Fv_file[Renamed_file]->name; /* Get real length of text and approx. # characters */ panel_set(Text_item, PANEL_VALUE, b_p, PANEL_VALUE_DISPLAY_LENGTH, strlen(b_p), 0); window_set(Text_panel, WIN_X, x + window_get(Fv_foldr.canvas, WIN_X), WIN_Y, y + window_get(Fv_foldr.canvas, WIN_Y), WIN_WIDTH, Fv_file[Renamed_file]->width+ Fv_fontsize.x, WIN_SHOW, TRUE, 0); fv_putmsg(FALSE, Fv_message[MRENAME], (int)b_p, 0); return(notify_next_event_func(cnvs, evnt, arg, typ)); } else if (window_get(Text_panel, WIN_SHOW)) { /* Clicking elsewhere completes the rename operation */ stop_editing(); } if (Fv_tselected) { /* Turn off tree selection. Only 1 window can have * the selection. */ fv_treedeselect(); } if ((i = over_object(event_x(evnt), event_y(evnt))) != EMPTY) { if (!Fv_file[i]->selected) { /* If this file isn't already selected then * turn off other selections. If it is * selected, the user may wish to drag. */ fv_filedeselect(); Fv_file[i]->selected = TRUE; fv_reverse(i); } click = evnt->ie_time; if (last_selected == i && click.tv_sec-last_click.tv_sec <= 1) { /* Double click (inside a second) opens file */ fv_busy_cursor(TRUE); fv_file_open(i, FALSE, (char *)0, FALSE); last_selected = EMPTY; fv_busy_cursor(FALSE); return(notify_next_event_func(cnvs, evnt, arg, typ)); } last_click = click; last_selected = i; /* Maybe user wants to drag... */ x = event_x(evnt); y = event_y(evnt);#ifndef SV1 fs = (Fullscreen)vu_create(0, FULLSCREEN, FULLSCREEN_INPUT_WINDOW, cnvs, FULLSCREEN_SYNC, FALSE, WIN_CONSUME_EVENTS, WIN_MOUSE_BUTTONS, LOC_DRAG, LOC_MOVEWHILEBUTDOWN, 0, 0);#endif while (window_read_event(cnvs, evnt) != -1 && event_id(evnt) != MS_LEFT) { if (((i = x-event_x(evnt))>THRESHOLD) || i<-THRESHOLD || ((i = y-event_y(evnt))>THRESHOLD) || i<-THRESHOLD) {#ifndef SV1 fullscreen_destroy(fs); fs = 0;#endif drag(x, y, (BOOLEAN)event_ctrl_is_down(evnt)); break; } }#ifndef SV1 if (fs) fullscreen_destroy(fs);#endif } else fv_filedeselect(); } else if (event_id(evnt) == MS_MIDDLE) /* Extend selection */ { if ((i = over_object(event_x(evnt), event_y(evnt))) > EMPTY) { /* Ensure no tree object remains selected */ if (Fv_tselected) fv_treedeselect(); fv_reverse(i); Fv_file[i]->selected = !Fv_file[i]->selected; } } else if (event_id(evnt) == MS_RIGHT) { /* Put up floating edit menu */ fv_editmenu(cnvs, evnt, TRUE); } fv_check_keys(evnt); return(notify_next_event_func(cnvs, evnt, arg, typ));}staticdrag(x, y, copy) /* Drag icon */ register int x, y; /* From coordinates */ BOOLEAN copy; /* Copy instead of Move */{ int iconwidth, iconheight; Event ev; /* Current event */ register int i; /* Generic index */ register int x1, y1; /* New coordinates (relative from frame)*/ register BOOLEAN really_drag; /* Drag icons? */ register FV_FILE **f_p, **l_p; /* Files array pointers */ struct { short fno; /* Index to Fv_file array */ short x, y; /* Original coords on screen */ Pixrect *pr; /* Object's iconic image */ } Seln[64]; register int nseln; /* Number of selections */ int scroll_offset; /* Scroll offset into canvas */ int target; int lock; char target_tree_path[MAXPATH]; FV_TNODE *tree_target; FV_TNODE *tree_lock; FV_TNODE *t_p; register struct fullscreen *fs; static int fd=0; int rootfd; extern FV_TNODE *fv_infolder(); int winx, winy; BOOLEAN desktop_link; int x_off=0, y_off=0; int foldr_top, tree_top;#ifndef SV1 static Frame root_frame = 0; Cursor fv_get_drag_cursor();#endif #ifdef SV1 /* Enter fullscreen mode and grab all events */ if (!fd) fd = (int)window_get(Fv_frame, WIN_FD); fs = (struct fullscreen *)fullscreen_init(fd); win_grabio(fd); fv_cursor(fd, copy ? FV_COPYCURSOR : FV_MOVECURSOR);#ifdef PROTO i = PROTO_TOP_MARGIN;#else i = (int)window_get(Fv_frame, WIN_TOP_MARGIN);#endif tree_top = (int)window_get(Fv_tree.canvas, WIN_Y)+i; foldr_top = (int)window_get(Fv_foldr.canvas, WIN_Y)+i;#define PAINT fullscreen_pw_write(fs->fs_pixwin,#else#define PAINT pw_rop(root_frame, if (!root_frame) root_frame = vu_get(Fv_frame, VU_ROOT); win_translate_xy(Fv_foldr.canvas, root_frame, 0, 0, &x_off, &y_off); y_off += 7; /* KLUDGE */ fs = (struct fullscreen *)vu_create(0, FULLSCREEN, FULLSCREEN_INPUT_WINDOW, Fv_frame, WIN_CURSOR, fv_get_drag_cursor(copy), WIN_CONSUME_EVENTS, WIN_MOUSE_BUTTONS, LOC_DRAG, LOC_MOVEWHILEBUTDOWN,0, FULLSCREEN_SYNC, FALSE, 0);#endif if (Fv_style & FV_DICON) { iconwidth = GLYPH_WIDTH; iconheight = GLYPH_HEIGHT; } else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -