Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 12 Nov 2012 00:28:42 GMT
From:      Brooks Davis <brooks@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 219751 for review
Message-ID:  <201211120028.qAC0SgJL036598@skunkworks.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@219751?ac=10

Change 219751 by brooks@brooks_zenith on 2012/11/12 00:28:05

	Checkpoint a revised cheripoint with the infrastructure to
	render to multiple screen widths.  No ability to change width
	or sandbox type yet but that should come soon.

Affected files ...

.. //depot/projects/ctsrd/cheribsd/src/ctsrd/cheripoint/cheripoint.c#2 edit

Differences ...

==== //depot/projects/ctsrd/cheribsd/src/ctsrd/cheripoint/cheripoint.c#2 (text+ko) ====

@@ -35,6 +35,7 @@
 #include <dirent.h>
 #include <err.h>
 #include <fcntl.h>
+#include <fnmatch.h>
 #include <imagebox.h>
 #include <stdlib.h>
 #include <stdio.h>
@@ -44,10 +45,18 @@
 #define black           vwhite(0)
 #define white           vwhite(0xFF)
 
+enum mtl_display_mode {
+	MTL_DM_800x480,		/* Full touch screen */
+	MTL_DM_720x480,		/* Full 480p HDMI out */
+	MTL_DM_640x480,		/* 640x480 VGA from 480p, left pixels */
+	MTL_DM_640x480_CENTER	/* 640x480 VGA from 480p, center pixels */
+};
+
 enum sbtype sb = SB_CAPSICUM;
 
-const uint32_t slide_width = 640;
-const uint32_t slide_height = 410;
+static uint32_t slide_fcol;
+static uint32_t slide_width;
+static uint32_t slide_height;
 
 static void __dead2
 usage(void)
@@ -57,6 +66,30 @@
 	exit(1);
 }
 
+static void
+set_display_mode(enum mtl_display_mode dm)
+{
+
+	slide_height = 410;
+	slide_fcol = 0;
+
+	switch (dm) {
+	case (MTL_DM_800x480):
+		slide_width = 800;
+		break;
+	case (MTL_DM_720x480):
+		slide_width = 720;
+		break;
+	case (MTL_DM_640x480):
+		slide_width = 640;
+		break;
+	case (MTL_DM_640x480_CENTER):
+		slide_width = 640;
+		slide_fcol = 40;
+		break;
+	}
+}
+
 static int
 strpcmp(const void *v1, const void *v2)
 {
@@ -70,46 +103,55 @@
 	s1 = *sp1;
 	s2 = *sp2;
 
-	/* sort title.png first */
-	if (strcmp(s1, "title.png") == 0)
-		return 1;
-	if (strcmp(s2, "title.png") == 0)
-		return -1;
-
 	return (strcmp(s1, s2));
 }
 
 static int
-render_slide(int dfd, const char *slide)
+render_cover(int dfd, const char *cover)
 {
 	int pfd;
-	uint32_t header_height;
 	struct iboxstate *is;
 
-	fb_fill_region(white, 0, 0, slide_width, fb_height);
+	printf("rendering cover %s\n", cover);
 
-	if (strcmp(slide, "title.png") == 0) {
-		if ((pfd = openat(dfd, slide, O_RDONLY)) == -1) {
-			warn("Failed to open title.png");
-			return (-1);
-		}
-		if ((is = png_read_start(pfd, slide_width, fb_height, sb)) ==
-		    NULL) {
-			warn("Failed to start PNG decode for title.png");
-			return (-1);
-		}
-		if (png_read_finish(is) != 0) {
-			warnx("png_read_finish() failed for title.png");
-			return (-1);
-		}
-		fb_post_region(__DEVOLATILE(uint32_t *, is->buffer), 0, 0,
-		    is->width, is->height);
-		iboxstate_free(is);
+	fb_fill_region(white, 0, 0, fb_width, fb_height);
 
-		return (0);
+	if ((pfd = openat(dfd, cover, O_RDONLY)) == -1) {
+		warn("Failed to open %s", cover);
+		return (-1);
+	}
+	if ((is = png_read_start(pfd, slide_width, fb_height, sb)) ==
+	    NULL) {
+		warn("Failed to start PNG decode for %s", cover);
+		return (-1);
+	}
+	if (png_read_finish(is) != 0) {
+		warnx("png_read_finish() failed for %s", cover);
+		return (-1);
 	}
+	fb_post_region(__DEVOLATILE(uint32_t *, is->buffer), 0, 0,
+	    is->width, is->height);
+	iboxstate_free(is);
+
+	return (0);
+}
+
+static int
+render_slide(int dfd, const char *slide)
+{
+	int pfd;
+	uint32_t r, header_height;
+	struct iboxstate *is;
 
-	/* stick a header on the top of the screen */
+	printf("rendering slide %s\n", slide);
+
+	fb_fill_region(white, 0, 0, fb_width, fb_height);
+
+	/*
+	 * Draw the header with image at the upper right.  Assume
+	 * the background color is the same on each row and that the
+	 * left most pixel of the image is that color.
+	 */
 	if ((pfd = open("/usr/share/images/header.png", O_RDONLY)) == -1) {
 		warn("Failed to open header.png");
 		return (-1);
@@ -122,8 +164,11 @@
 		warnx("png_read_finish() failed for header.png");
 		return (-1);
 	}
-	fb_post_region(__DEVOLATILE(uint32_t *, is->buffer), 0, 0,
-	    is->width, is->height);
+	/* Fill in the header's background. */
+	for (r = 0; r < is->height; r++)
+		fb_fill_region(is->buffer[r * is->width], 0, r, fb_width, 1);
+	fb_post_region(__DEVOLATILE(uint32_t *, is->buffer),
+	    slide_fcol + slide_width - is->width, 0, is->width, is->height);
 	header_height = is->height;
 	iboxstate_free(is);
 
@@ -141,7 +186,7 @@
 		return (-1);
 	}
 	fb_post_region(__DEVOLATILE(uint32_t *, is->buffer),
-	    0, fb_height - is->height, is->width, is->height);
+	    slide_fcol, fb_height - is->height, is->width, is->height);
 	iboxstate_free(is);
 
 	/* put a cambridge logo in the lower right corner */
@@ -158,7 +203,7 @@
 		return (-1);
 	}
 	fb_post_region(__DEVOLATILE(uint32_t *, is->buffer),
-	    slide_width - is->width, fb_height - is->height,
+	    slide_fcol + slide_width - is->width, fb_height - is->height,
 	    is->width, is->height);
 	iboxstate_free(is);
 
@@ -167,7 +212,7 @@
 		return (-1);
 	}
 	/* XXX: correct size limits */
-	if ((is = png_read_start(pfd, fb_width, fb_height,
+	if ((is = png_read_start(pfd, slide_width, fb_height,
 	    sb)) == NULL) {
 		warn("Failed to start PNG decode for %s", slide);
 		return (-1);
@@ -177,19 +222,46 @@
 		return (-1);
 	}
 	fb_post_region(__DEVOLATILE(uint32_t *, is->buffer),
-	    0, header_height, is->width,
-	    is->height < slide_height ? is->height : slide_height);
+	    slide_fcol + ((slide_width - is->width) / 2), header_height,
+	    is->width, is->height < slide_height ? is->height : slide_height);
 	iboxstate_free(is);
 
 	return (0);
 }
 
+static void
+addslide(int *np, int *maxp, char ***arrayp, const char *name)
+{
+
+	printf("n %d, max %d\n", *np, *maxp);
+	if (*maxp == 0) {
+		*maxp = 8;
+		if ((*arrayp = malloc(sizeof(**arrayp) * (*maxp))) == NULL)
+			err(1, "malloc slide array\n");
+	}
+	if (*np == *maxp) {
+		if (*maxp == 0)
+			*maxp = 512;
+		else
+			*maxp *= 2;
+		if ((*arrayp = realloc(*arrayp,
+		    sizeof(**arrayp) * (*maxp))) == NULL)
+			err(1, "realloc slide array");
+	}
+
+	if (((*arrayp)[*np] = strdup(name)) == NULL)
+		err(1, "strdup slide name");
+	(*np)++;
+}
+
 int
 main(int argc, char **argv)
 {
 	DIR *dirp;
 	struct dirent *entry;
-	char **slides = NULL;
+	char *coverpat;
+	char **covers, **slides;
+	int cover, ncovers, maxcovers;
 	int slide, nslides, maxslides;
 	struct tsstate *ts;
 
@@ -199,15 +271,17 @@
 	fb_init();
         ts_drain();
 	busy_indicator();
-	fb_fill_region(black, 0, 0, fb_width, fb_height);
+	fb_fill_region(white, 0, 0, fb_width, fb_height);
         fb_fade2on(); 
         fb_load_syscons_font(NULL, "/usr/share/syscons/fonts/iso-8x16.fnt");
         busy_indicator();
 
-	maxslides = 512;
-	nslides = 0;
-	if ((slides = malloc(sizeof(*slides) * maxslides)) == NULL)
-		err(1, "malloc slides");
+	set_display_mode(MTL_DM_720x480);
+
+	printf("reading slides\n");
+
+	maxcovers = ncovers = 0;
+	maxslides = nslides = 0;
 	if ((dirp = opendir(argv[1])) == NULL)
 		err(1, "opendir(%s)", argv[1]);
 	while ((entry = readdir(dirp)) != NULL) {
@@ -215,24 +289,30 @@
 		if (entry->d_type != DT_REG)
 			continue;
 
-		if (nslides == maxslides) {
-			maxslides *= 2;
-			if ((slides = realloc(slides,
-			    sizeof(*slides) * maxslides)) == NULL)
-				err(1, "realloc slides");
-		}
-
-		if ((slides[nslides] = strdup(entry->d_name)) == NULL)
-			err(1, "strdup slide name");
-		nslides++;
+		printf("checking it %s is a cover\n", entry->d_name);
+		if (fnmatch("*-cover-*.png", entry->d_name, 0) == 0)
+			addslide(&ncovers, &maxcovers, &covers, entry->d_name);
+		else
+			addslide(&nslides, &maxslides, &slides, entry->d_name);
 	}
+	printf("read %d covers and %d slides\n", ncovers, nslides);
 	qsort(slides, nslides, sizeof(*slides), &strpcmp);
+	qsort(covers, ncovers, sizeof(*covers), &strpcmp);
 	
 	slide = 0;
 	for (;;) {
-		render_slide(dirfd(dirp), slides[slide]);
-		printf("rendering %s\n", slides[slide]);
-		//ts_drain();
+		if (slide == 0) {
+			asprintf(&coverpat, "*-cover-%d.png", slide_width);
+			for (cover = 0; cover < ncovers; cover++)
+				if (fnmatch(coverpat, covers[cover], 0) == 0)
+					break;
+			free(coverpat);
+			if (cover == ncovers)
+				cover = 0;	/* Smallest cover due to sort */
+			render_cover(dirfd(dirp), covers[cover]);
+		} else
+			render_slide(dirfd(dirp), slides[slide - 1]);
+		ts_drain();
 nop:
 		ts = ts_poll();
 		printf("gesture 0x%x\n", ts->ts_gesture);
@@ -244,12 +324,12 @@
 			break;
 		case TSG_EAST:
 			if (slide == 0)
-				slide = nslides - 1;
+				slide = nslides;
 			else
 				slide--;
 			break;
 		case TSG_WEST:
-			if (slide == nslides - 1)
+			if (slide == nslides)
 				slide = 0;
 			else
 				slide++;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201211120028.qAC0SgJL036598>