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