Beispiel #1
0
static void cb_keyboard(GLFWwindow* window, int k, int scancode, int action, int mods)
{
	if(action != 1) return;

	if(k == '-') opt_levels--;
	if(k == '=') opt_levels++;
	if(k == '0') opt_levels = 4;
	if(k == GLFW_KEY_ESCAPE) exit(0);
	if(k == 'Q') exit(0);
	if(k == 'A') opt_apparent = !opt_apparent;
	if(k == 'C') opt_count = !opt_count;
	if(k == 'B') opt_bytes = !opt_bytes;
	if(k == 'F') fuzz = (fuzz == 0) ? opt_fuzz : 0;
	if(k == 'G') opt_gradient = !opt_gradient;
	if(k == ',') if(opt_ring_gap > 0) opt_ring_gap --;
	if(k == '.') opt_ring_gap ++;
	if(k == 'P') palette = (palette + 1) % 5;
	if(k == GLFW_KEY_BACKSPACE) {
		duc_dir *dir2 = duc_dir_openat(dir, "..");
		if(dir2) {
			duc_dir_close(dir);
			dir = dir2;
		}
	}
}
Beispiel #2
0
int gui_main(duc *duc, int argc, char *argv[])
{
	char *path = ".";
	if(argc > 0) path = argv[0];

	fuzz = opt_fuzz;

	if(opt_palette) {
		char c = tolower(opt_palette[0]);
		if(c == 's') palette = DUC_GRAPH_PALETTE_SIZE;
		if(c == 'r') palette = DUC_GRAPH_PALETTE_RAINBOW;
		if(c == 'g') palette = DUC_GRAPH_PALETTE_GREYSCALE;
		if(c == 'm') palette = DUC_GRAPH_PALETTE_MONOCHROME;
	}

	int r = duc_open(duc, opt_database, DUC_OPEN_RO);
	if(r != DUC_OK) {
		duc_log(duc, DUC_LOG_FTL, "%s", duc_strerror(duc));
		return -1;
	}
	
	dir = duc_dir_open(duc, path);
	if(dir == NULL) {
		duc_log(duc, DUC_LOG_FTL, "%s", duc_strerror(duc));
		return -1;
	}
	
	dpy = XOpenDisplay(NULL);
	if(dpy == NULL) {
		duc_log(duc, DUC_LOG_FTL, "ERROR: Could not open display");
		exit(1);
	}

	int scr = DefaultScreen(dpy);
	rootwin = RootWindow(dpy, scr);

	Window win = XCreateSimpleWindow(
			dpy, 
			rootwin, 
			1, 1, 
			win_w, win_h, 0, 
			BlackPixel(dpy, scr), WhitePixel(dpy, scr));

	XSelectInput(dpy, win, ExposureMask | ButtonPressMask | StructureNotifyMask | KeyPressMask | PointerMotionMask);
	XMapWindow(dpy, win);
	
	cs = cairo_xlib_surface_create(dpy, win, DefaultVisual(dpy, 0), win_w, win_h);
	cr = cairo_create(cs);



	graph = duc_graph_new_cairo(duc, cr);

	do_gui(duc, graph, dir);

	duc_dir_close(dir);

	return 0;
}
Beispiel #3
0
void cb_mouse_button(GLFWwindow* window, int b, int action, int mods)
{
	if(action != 1) return;

	double x, y;
	glfwGetCursorPos(window, &x, &y);
	sc2fb(window, &x, &y);

	if(b == 0) {
		duc_dir *dir2 = duc_graph_find_spot(graph, dir, x, y, NULL);
		if(dir2) {
			duc_dir_close(dir);
			dir = dir2;
		}
	}
	if(b == 3) {
		duc_dir *dir2 = duc_dir_openat(dir, "..");
		if(dir2) {
			duc_dir_close(dir);
			dir = dir2;
		}
	}
}
Beispiel #4
0
duc_dir *duc_dir_open(struct duc *duc, const char *path)
{
	/* Canonicalized path */

	char *path_canon = duc_canonicalize_path(path);
	if(!path_canon) {
		duc->err = DUC_E_PATH_NOT_FOUND;
		return NULL;
	}

	/* Find top path in database */

	char *path_try = duc_strdup(path_canon);
	int l = strlen(path_try);
	struct duc_devino devino = { 0, 0 };
	while(l > 0) {
		path_try[l] = '\0';
		struct duc_index_report *report;
		report = db_read_report(duc, path_try);
		if(report) {
			devino = report->devino;
			free(report);
			break;
		}
		l--;
	}
	free(path_try);

	if(l == 0) {
		duc_log(duc, DUC_LOG_FTL, "Path %s not found in database", path_canon);
		duc->err = DUC_E_PATH_NOT_FOUND;
		free(path_canon);
		return NULL;
	}

	struct duc_dir *dir;

	dir = duc_dir_new(duc, &devino);

	if(dir == NULL) {
		duc->err = DUC_E_PATH_NOT_FOUND;
		free(path_canon);
		return NULL;
	}
	
	char rest[DUC_PATH_MAX];
	strncpy(rest, path_canon+l, sizeof rest);

	char *name = strtok(rest, "/");

	while(dir && name) {

		struct duc_dirent *ent = duc_dir_find_child(dir, name);

		struct duc_dir *dir_next = NULL;

		if(ent) {
			dir_next = duc_dir_openent(dir, ent);
		}

		duc_dir_close(dir);
		dir = dir_next;
		name = strtok(NULL, "/");
	}

	if(dir) {
		dir->path = strdup(path_canon);
	}

	free(path_canon);

	return dir;
}
Beispiel #5
0
Datei: dir.c Projekt: MSU-RCG/duc
duc_dir *duc_dir_open(struct duc *duc, const char *path)
{
	/* Canonicalized path */

	char *path_canon = stripdir(path);
	if(!path_canon) {
		duc->err = DUC_E_PATH_NOT_FOUND;
		return NULL;
	}

	/* Find top path in database */

	int l = strlen(path_canon);
	dev_t dev = 0;
	ino_t ino = 0;
	while(l > 0) {
		struct duc_index_report *report;
		size_t report_len;
		report = db_get(duc->db, path_canon, l, &report_len);
		if(report && report_len == sizeof(*report)) {
			dev = report->dev;
			ino = report->ino;
			free(report);
			break;
		}
		l--;
		while(l > 1  && path_canon[l] != '/') l--;
	}

	if(l == 0) {
		duc_log(duc, DUC_LOG_WRN, "Path %s not found in database", path_canon);
		duc->err = DUC_E_PATH_NOT_FOUND;
		free(path_canon);
		return NULL;
	}

	struct duc_dir *dir;

	dir = db_read_dir(duc, dev, ino);

	if(dir == NULL) {
		duc->err = DUC_E_PATH_NOT_FOUND;
		free(path_canon);
		return NULL;
	}
	
	char rest[PATH_MAX];
	strncpy(rest, path_canon+l, sizeof rest);

	char *name = strtok(rest, "/");

	while(dir && name) {

		struct duc_dirent *ent = duc_dir_find_child(dir, name);

		struct duc_dir *dir_next = NULL;

		if(ent) {
			dir_next = duc_dir_openent(dir, ent);
		}

		duc_dir_close(dir);
		dir = dir_next;
		name = strtok(NULL, "/");
	}

	if(dir) {
		dir->path = strdup(path_canon);
	}

	return dir;
}
Beispiel #6
0
static int handle_event(XEvent e)
{
	KeySym k;
	int x, y, b;

	switch(e.type) {

		case ConfigureNotify: 
			win_w = e.xconfigure.width;
			win_h = e.xconfigure.height;
			cairo_xlib_surface_set_size(cs, win_w, win_h);
			redraw = 1;
			break;
			

		case Expose:
			if(e.xexpose.count < 1) redraw = 1;
			break;

		case KeyPress: 

			k = XLookupKeysym(&e.xkey, 0);

			if(k == XK_minus) opt_levels--;
			if(k == XK_equal) opt_levels++;
			if(k == XK_0) opt_levels = 4;
			if(k == XK_Escape) return 1;
			if(k == XK_q) return 1;
			if(k == XK_a) opt_apparent = !opt_apparent;
			if(k == XK_b) opt_bytes = !opt_bytes;
			if(k == XK_f) fuzz = (fuzz == 0) ? opt_fuzz : 0;
			if(k == XK_comma) if(opt_ring_gap > 0) opt_ring_gap --;
			if(k == XK_period) opt_ring_gap ++;
			if(k == XK_p) {
				palette = (palette + 1) % 4;
			}
			if(k == XK_BackSpace) {
				duc_dir *dir2 = duc_dir_openat(dir, "..");
				if(dir2) {
					duc_dir_close(dir);
					dir = dir2;
				}
			}

			redraw = 1;
			break;

		case ButtonPress: 

			x = e.xbutton.x;
			y = e.xbutton.y;
			b = e.xbutton.button;

			if(b == 1) {
				duc_dir *dir2 = duc_graph_find_spot(graph, dir, x, y, NULL);
				if(dir2) {
					duc_dir_close(dir);
					dir = dir2;
				}
			}
			if(b == 3) {
				duc_dir *dir2 = duc_dir_openat(dir, "..");
				if(dir2) {
					duc_dir_close(dir);
					dir = dir2;
				}
			}

			if(b == 4) opt_levels --;
			if(b == 5) opt_levels ++;

			redraw = 1;
			break;

		case MotionNotify: 

			tooltip_x = e.xmotion.x;
			tooltip_y = e.xmotion.y;
			tooltip_moved = 1;
			break;

		default:
			break;
	}

	return 0;
}
Beispiel #7
0
static duc_dir *do_dir(duc_dir *dir, int depth)
{
	int top = 0;
	int cur = 0;

	for(;;) {

		int attr_size, attr_name, attr_class, attr_graph, attr_bar, attr_cursor;

		if(opt_color) {
			attr_size = COLOR_PAIR(PAIR_SIZE);
			attr_name = COLOR_PAIR(PAIR_NAME);
			attr_bar = COLOR_PAIR(PAIR_BAR);
			attr_cursor = COLOR_PAIR(PAIR_CURSOR);
			attr_graph = COLOR_PAIR(PAIR_GRAPH);
			attr_class = COLOR_PAIR(PAIR_CLASS);
		} else {
			attr_size = 0;
			attr_name = A_BOLD;
			attr_class = 0;
			attr_graph = 0;
			attr_bar = A_REVERSE;
			attr_cursor = A_REVERSE;
			use_default_colors();
		}
	
		duc_size_type st = opt_apparent ? DUC_SIZE_TYPE_APPARENT : DUC_SIZE_TYPE_ACTUAL;

		/* Iterate all dirents to find largest size */

		duc_dir_seek(dir, 0);

		off_t size_max = 1;
		struct duc_dirent *e;
		while( (e = duc_dir_read(dir, st)) != NULL) {
			off_t size = opt_apparent ? e->size.apparent : e->size.actual;
			if(size > size_max) size_max = size;
		}

		int count = duc_dir_get_count(dir);
		int pgsize = rows - 2;
		
		/* Check boundaries */

		if(cur < 0) cur = 0;
		if(cur > count - 1) cur = count - 1;
		if(cur < top) top = cur;
		if(cur > top + pgsize - 1) top = cur - pgsize + 1;
		if(top < 0) top = 0;


		/* Draw header */

		char *path = duc_dir_get_path(dir);
		attrset(attr_bar);
		mvhline(0, 0, ' ', cols);
		mvprintw(0, 1, " %s ", path);
		attrset(0);
		free(path);


		/* Draw footer */

		struct duc_size size;
		duc_dir_get_size(dir, &size);
		char siz[32], cnt[32];
		duc_human_size(&size, st, opt_bytes, siz, sizeof siz);
		duc_human_number(count, opt_bytes, cnt, sizeof cnt);
		attrset(attr_bar);
		mvhline(rows-1, 0, ' ', cols);
		mvprintw(rows-1, 0, " Total %sB in %s files/directories", siz, cnt);
		attrset(0);

		/* Draw dirents */
	
		duc_dir_seek(dir, top);

		int i;
		int y = 1;

		for(i=top; i<top + pgsize; i++) {
			
			struct duc_dirent *e = duc_dir_read(dir, st);

			attrset(cur == i ? attr_cursor : 0);
			mvhline(y, 0, ' ', cols);

			if(e) {

				off_t size = opt_apparent ? e->size.apparent : e->size.actual;
		
				size_t max_size_len = opt_bytes ? 12 : 7;

				char class = duc_file_type_char(e->type);

				char siz[32];
				duc_human_size(&e->size, st, opt_bytes, siz, sizeof siz);
				if(cur != i) attrset(attr_size);
				printw("%*s", max_size_len, siz);

				printw(" ");
				char *p = e->name;
				if(cur != i) attrset(attr_name);
				while(*p) {
					if(*(uint8_t *)p >= 32) {
						printw("%c", *p);
					} else {
						printw("^%c", *p+64);
					}
					p++;
				}
				if(cur != i) attrset(attr_class);
				printw("%c", class);

				int w = cols - 30;
				if(w > cols / 2) w = cols / 2;
				if(opt_graph && w > 2) {
					int j;
					off_t g = w * size / size_max;
					if(cur != i) attrset(attr_graph);
					mvprintw(y, cols - w - 4, " [");
					for(j=0; j<w; j++) printw("%s", j < g ? "=" : " ");
					printw("] ");
				}

			} else {

				attrset(A_DIM);
				mvprintw(y, 0, "~");
			}

			y++;
		}

		duc_dir *dir2 = NULL;

		/* Handle key */

		int c = getch();

		switch(c) {
			case 'k':
			case KEY_UP: cur--; break;
			case 'j':
			case KEY_DOWN: cur++; break;
			case 21: cur -= pgsize/2; break;
			case KEY_PPAGE: cur -= pgsize; break;
			case 4: cur += pgsize/2; break;
			case KEY_NPAGE: cur += pgsize; break;
			case KEY_RESIZE: getmaxyx(stdscr, rows, cols); break;
			case 'a': opt_apparent ^= 1; break;
			case 'b': opt_bytes ^= 1; break;
			case 'c': opt_color ^= 1; break;
			case 'g': opt_graph ^= 1; break;
			case 'h': help(); break;

			case 27:
			case 'q': 
				  exit(0); break;

			case KEY_BACKSPACE:
			case KEY_LEFT:
				  if(depth > 0) {
					  return NULL;
				  } else {
					  dir2 = duc_dir_openat(dir, "..");
					  if(dir2) {
						  do_dir(dir2, 0);
						  duc_dir_close(dir2);
					  }
				  }
				  break;

			case KEY_RIGHT:
			case '\r':
			case '\n': 
				  duc_dir_seek(dir, cur);
				  struct duc_dirent *e = duc_dir_read(dir, st);
				  if(e->type == DUC_FILE_TYPE_DIR) {
					dir2 = duc_dir_openent(dir, e);
					if(dir2) {
						do_dir(dir2, depth + 1);
						duc_dir_close(dir2);
					}
				  }
				  break;
			default:
				  break;
		}

	}