PERFORCE change 214148 for review

Brooks Davis brooks at FreeBSD.org
Mon Jul 9 22:33:23 UTC 2012


http://p4web.freebsd.org/@@214148?ac=10

Change 214148 by brooks at brooks_ecr_current on 2012/07/09 22:32:51

	Add reworked directory scanning code and support for scrolling
	through directories using left and right swipes.

Affected files ...

.. //depot/projects/ctsrd/beribsd/src/ctsrd/browser/browser.c#6 edit

Differences ...

==== //depot/projects/ctsrd/beribsd/src/ctsrd/browser/browser.c#6 (text+ko) ====

@@ -95,9 +95,10 @@
  * (either a line on the console or a space on the screen) or one of
  * these actions.  Internally it handles changing protection modes.
  */
-#define	ACT_QUIT	100
-#define	ACT_PREV	101
-#define	ACT_NEXT	102
+#define ACT_NEXT	100
+#define ACT_PREV	101
+#define	ACT_QUIT	102
+#define	ACT_REFRESH	103
 
 /* Beginning and ending colums of each sandbox type's name */
 #define	SB_IMG_SPACING		20
@@ -115,6 +116,12 @@
 /* Start offsets for browser columns */
 const int	colstart[] = {0, 267, 534};
 
+struct dent {
+	struct dirent	*entry;
+	char		*desc;
+	u_int32_t	*icon;
+};
+
 /*
  * List of mappings between icons in the icons.png file and values from
  * the get_desc() function.  Processing is first match so most specific
@@ -214,6 +221,7 @@
 static const char *
 get_magic(int fd)
 {
+
 	switch (sbtype) {
 	case SB_NONE:
 		return magic_descriptor(magic, fd);
@@ -338,201 +346,160 @@
 	    FROW + (RHEIGHT * (s % NROW)) + BORDER, ICON_WH, ICON_WH);
 }
 
-#ifdef TEXT_INPUT
 static int
-get_action(int next_slot, int prev_slot)
+get_action(void)
 {
-	int f;
-	char line[256];
-
-prompt:
-	printf("select a file or directory by number :\n");
-	if (fgets(line, sizeof(line), stdin) == NULL) {
-		if (feof(stdin))
-			return (-1);
-		else
-			errx(1, "fgets(): %s", strerror(ferror(stdin)));
-	}
-	printf("line '%s'\n", line);
-	f = 0; /* XXX: gcc warning*/
-	switch (line[0]) {
-	case '\n':
-	case 'n':
-		return (ACT_NEXT);
-	case 'p':
-		return (ACT_PREV);
-	case 'q':
-		return (ACT_QUIT);
-
-	default:
-		if (!isnumber(line[0])) {
-			printf("invalid file %s\n", line);
-			goto prompt;
-		}
-		f = atoi(line);
-		if (f < 0 || f >= NSLOTS - 1) {
-			printf("invalid file %s\n", line);
-			goto prompt;
-		}
-		return (f);
-	}
-}
-
-#else /* TEXT_INPUT */
-
-static int
-get_action(int next_slot, int prev_slot)
-{
 	struct tsstate *ts;
-	int action = -1, col, i, row, slot;
+	int action = -1, col, i, row;
 
 	printf("entering get_action\n");
 
 	while(action < 0) {
 		ts = ts_poll();
+		printf("gesture = %x\n", ts->ts_gesture);
 		if (ts->ts_gesture == TSG_CLICK) {
-			if (ts->ts_x1 < FROW) {
+			if (ts->ts_y1 < FROW) {
 				if (ts->ts_x1 > fb_width - 40)
 					return (ACT_QUIT);
 			} else if (ts->ts_y1 <= FROW + (NROW * RHEIGHT)) {
 				row = (ts->ts_y1 - FROW) / RHEIGHT;
 				for (col = NCOL - 1;
 				    col > 0 && ts->ts_x1 < colstart[col]; col--)
-					/* do nothing */
-				printf("row %d col %d\n", row, col);
-				slot = col * NROW + row;
-				if (slot == next_slot)
-					return (ACT_NEXT);
-				else if (slot == prev_slot)
-					return (ACT_PREV);
-				else
-					return (slot);
+					/* do nothing */;
+				printf("row = %d, col = %d\n", row, col);
+				return (col * NROW + row);
 			} else {
-				printf("in bottom bar, x = %d\n", ts->ts_x1);
 				if (ts->ts_x1 >= SB_MINCOL &&
 				    ts->ts_x1 <= SB_MAXCOL) {
 					for (i =0 ; ts->ts_x1 < sbdata[i].bcol ||
 					    ts->ts_x1 > sbdata[i].ecol; i++)
-						/* do nothing */
+						/* do nothing */;
 					assert(sbdata[i].sbtype != 0);
 					update_sandbox(sbdata[i].sbtype);
-					/* XXX: should trigger a rescan? */
+					return (ACT_REFRESH);
 				}
 			}
 		}
+		if (ts->ts_gesture == TSG_EAST)
+			return (ACT_PREV);
+		if (ts->ts_gesture == TSG_WEST)
+			return (ACT_NEXT);
 	}
 	/* NOTREACHED */
 	return (ACT_QUIT);
 }
-#endif /* TEXT_INPUT */
 
 static int
 browsedir(int dfd)
 {
-	int action, i, j, s;
-	long curloc, nextloc;
+	int action, topslot, j, curslot, maxdents, nfd, ndents, retfd;
 	DIR *dirp;
-	struct dirent *entry, *entry2;
-	const char *desc;
+	struct dirent *entry;
+	struct dent **dents, *dent;
 
 	if ((dirp = fdopendir(dfd)) == NULL)
 		err(1, "fdopendir()");
 
+	ndents = 0;
+	maxdents = 1024;
+	dents = malloc(sizeof(struct dent *) * maxdents);
+	if (dents == NULL)
+		err(1, "malloc dents");
+
+	while ((entry = readdir(dirp)) != NULL) {
+		if (ndents == maxdents) {
+			maxdents *= 2;
+			dents = realloc(dents, sizeof(struct dent) * maxdents);
+			if (dents == NULL)
+				err(1, "realloc dents");
+		}
+		if (strcmp(".", entry->d_name) == 0)
+			continue;
+		dents[ndents] = malloc(sizeof(struct dent));
+		if (dents[ndents] == NULL)
+			err(1, "malloc dent[%d]", ndents);
+		memcpy(&(dents[ndents]->entry), &entry, sizeof(entry));
+		dents[ndents]->desc = NULL;
+		dents[ndents]->icon = NULL;
+		ndents++;
+	}
+
 	fb_fill_region(black, colstart[0], FROW, fb_width, NROW * RHEIGHT);
 	
-	curloc = telldir(dirp);
-	nextloc = 0;
-	i = 0;
-start:
-	seekdir(dirp, curloc);
-	/* telldir() return values are only good once so make a new copy! */
-	curloc = telldir(dirp);
-	s = 0;
-	if (i > 0) {
-		printf("p %20s\n", "previous page");
-		update_slot(s, get_icon("prev"), "previous page");
-		s = 1;
+	topslot = 0;
+render:
+	for(curslot = 0; curslot < NSLOTS && topslot + curslot < ndents;
+	    curslot++) {
+		dent = dents[topslot + curslot];
+		if (dent->desc == NULL)
+			dent->desc = strdup(get_desc(dfd, dent->entry));
+		if (dent->icon == NULL)
+			dent->icon = get_icon(dent->desc);
+
+		printf("%2d %20s %s\n", curslot, dent->entry->d_name,
+		    dent->desc);
+		update_slot(curslot, dent->icon, dent->entry->d_name);
 	}
-	entry = NULL; /* XXX: gcc warning */
-	while(s < NSLOTS - 1 && (entry = readdir(dirp)) != NULL) {
-		desc = get_desc(dfd, entry);
-		printf("%2d %20s %s\n", s, entry->d_name, desc);
-		update_slot(s, get_icon(desc), entry->d_name);
-		s++;
-	}
+	if (curslot == NSLOTS)
+		curslot--;
 
-	nextloc = telldir(dirp);
-	if (s == NSLOTS - 1 && entry != NULL) {
-		/*
-		 * If there are at least two more files then we don't want to
-		 * display a "next" button and instead want either nothing or
-		 * the final entry.
-		 */
-		entry = readdir(dirp);
-		if (entry == NULL)
-			nextloc = 0;
-		else {
-			entry2 = readdir(dirp);
-			if (entry2 == NULL) {
-				desc = get_desc(dfd, entry);
-				printf("%2d %20s %s\n", s,
-				    entry->d_name, desc);
-				update_slot(s, get_icon(desc), entry->d_name);
-				s++;
+	for (;;) {
+		action = get_action();
+		printf("action %d\n", action);
+		switch (action) {
+		case ACT_NEXT:
+			if (topslot + curslot < ndents) {
+				topslot += NSLOTS;
+				goto render;
+			}
+			continue;
+		case ACT_PREV:
+			if (topslot != 0) {
+				topslot -= NSLOTS;
+				goto render;
+			}
+			continue;
+		case ACT_QUIT:
+			retfd = -1;
+			goto cleanup;
+		case ACT_REFRESH:
+			/* Reset descriptions and icons */ 
+			for (j = 0; j < ndents; j++) {
+				free(dents[j]->desc);
+				dents[j]->desc = NULL;
+				dents[j]->icon = NULL;
+			}
+			goto render;
+		default:
+			if (action < 0 || action >= NSLOTS - 1)
+				errx(1, "invalid action");
+			if (topslot + action >= ndents)
+				continue;
+			if (dents[topslot + action]->entry->d_type == DT_DIR) {
+				if ((nfd = openat(dfd,
+				    dents[topslot + action]->entry->d_name,
+				    O_RDONLY|O_DIRECTORY)) == -1)
+					goto render; /* XXX: display error */
+				retfd = nfd;
+				goto cleanup;
 			} else {
-				printf("n %20s\n", "next page");
-				update_slot(s, get_icon("next"), "next page");
+				printf ("opening non-directory not supported\n");
+				goto render;
 			}
 		}
 	}
 
-	action = get_action((s == NSLOTS - 1) && entry != NULL ? NSLOTS - 1 : -1,
-	    i == 0 ? -1 : 0);
-	printf("action %d\n", action);
-	switch (action) {
-	case ACT_NEXT:
-		/* This leaks an internal struct associted with curloc/ */
-		if (nextloc != 0) {
-			i += s;
-			curloc = nextloc;
-		}
-		goto start;
-	case ACT_PREV:
-		i -= s;
-		// XXX previous page
-		break;
-	case ACT_QUIT:
-		return (-1);
-	default:
-		if (action < 0 || action >= NSLOTS - 1)
-			errx(1, "invalid action");
+cleanup:
+	for (j = 0; j < ndents; j++) {
+		free(dents[j]->desc);
+		free(dents[j]);
 	}
-
-	/* Take action on the specified file */
-	seekdir(dirp, curloc);
-	curloc = telldir(dirp);
-	j = 0;
-	while((entry = readdir(dirp)) != NULL) {
-		printf("%s\n", entry->d_name);
-		if (j++ != action)
-			continue;
-		if (entry->d_type == DT_DIR) {
-			if ((dfd = openat(dfd, entry->d_name,
-			    O_RDONLY|O_DIRECTORY)) == -1)
-				err(1, "open(%s)", entry->d_name);
-			if (closedir(dirp) == -1)
-				err(1, "closedir()");
-			return (dfd);
-		} else {
-			printf ("opening non-directory not supported\n");
-			goto start;
-		}
-	}
+	free(dents);
 
 	if (closedir(dirp) == -1)
 		err(1, "closedir()");
 
-	return (-1);
+	return (retfd);
 }
 
 int


More information about the p4-projects mailing list