Date: Mon, 9 Jul 2012 22:33:21 GMT From: Brooks Davis <brooks@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 214148 for review Message-ID: <201207092233.q69MXLaC065879@skunkworks.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@214148?ac=10 Change 214148 by brooks@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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201207092233.q69MXLaC065879>
