All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jon Smirl <jonsmirl@gmail.com>
To: fbdev <linux-fbdev-devel@lists.sourceforge.net>
Subject: PATCH: Make sysfs color_map attribute work
Date: Sun, 12 Jun 2005 11:30:36 -0400	[thread overview]
Message-ID: <9e47339105061208305d0cf3cc@mail.gmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 956 bytes --]

These two patches make the sysfs color_map attribute work. There is a
minor bug in sysfs fixed by sysfs_offbyone.patch. I sent the sysfs fix
separately to GregKH.

Sysfs usually works in text instead of binary. That lets scripts set
the attributes. You can set an attribute from a program with normal
file writes. The values have to be less than PAGE_SIZE in size.

Color maps have up to 256 entries. 4096/256 allows for 16 characters per line.

The format for a cmap entry is "%02x%c%4x%4x%4x\n"
%02x entry %c transp %4x red %4x blue %4x green

You don't have to start at zero, you can change one or more entries
this way. Build up a line per entry and set the whole block into the
attribute.

You can read the color_map with cat fb0/color_map.

My assumption from looking at the code that transparent is a boolean
flag. If the "%c" column is not a space transparent will be set for
that entry.

-- 
Jon Smirl
jonsmirl@gmail.com

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: sysfs_offbyone.patch --]
[-- Type: text/x-diff; name="sysfs_offbyone.patch", Size: 362 bytes --]

diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -182,7 +182,7 @@ fill_write_buffer(struct sysfs_buffer * 
 		return -ENOMEM;
 
 	if (count >= PAGE_SIZE)
-		count = PAGE_SIZE - 1;
+		count = PAGE_SIZE;
 	error = copy_from_user(buffer->page,buf,count);
 	buffer->needs_read_fill = 1;
 	return error ? -EFAULT : count;

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: cmap_sysfs.patch --]
[-- Type: text/x-diff; name="cmap_sysfs.patch", Size: 3384 bytes --]

diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c
--- a/drivers/video/fbsysfs.c
+++ b/drivers/video/fbsysfs.c
@@ -244,10 +242,68 @@ static ssize_t show_virtual(struct class
 			fb_info->var.xres_virtual);
 }
 
-static ssize_t store_cmap(struct class_device *class_device, const char * buf,
+/* Format for cmap is "%02x%c%4x%4x%4x\n" */
+/* %02x entry %c transp %4x red %4x blue %4x green \n */
+/* 255 rows at 16 chars equals 4096 */
+/* PAGE_SIZE can be 4096 or larger */
+static ssize_t store_cmap(struct class_device *class_device, const char *buf,
 			  size_t count)
 {
-//	struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
+	struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device);
+	int rc, i, start, length, transp = 0;
+
+	if ((count > 4096) || ((count % 16) != 0) || (PAGE_SIZE < 4096))
+		return -EINVAL;
+
+	if (!fb_info->fbops->fb_setcolreg && !fb_info->fbops->fb_setcmap)
+		return -EINVAL;
+
+	sscanf(buf, "%02x", &start);
+	length = count / 16;
+
+	for (i = 0; i < length; i++)
+		if (buf[i * 16 + 2] != ' ')
+			transp = 1;
+
+	/* If we can batch, do it */
+	if (fb_info->fbops->fb_setcmap && length > 1) {
+		struct fb_cmap umap;
+
+		memset(&umap, 0, sizeof(umap));
+		if ((rc = fb_alloc_cmap(&umap, length, transp)))
+			return rc;
+
+		umap.start = start;
+		for (i = 0; i < length; i++) {
+			sscanf(&buf[i * 16 +  3], "%4hx", &umap.red[i]);
+			sscanf(&buf[i * 16 +  7], "%4hx", &umap.blue[i]);
+			sscanf(&buf[i * 16 + 11], "%4hx", &umap.green[i]);
+			if (transp)
+				umap.transp[i] = (buf[i * 16 +  2] != ' ');
+		}
+		rc = fb_info->fbops->fb_setcmap(&umap, fb_info);
+		fb_copy_cmap(&umap, &fb_info->cmap);
+		fb_dealloc_cmap(&umap);
+
+		return rc;
+	}
+	for (i = 0; i < length; i++) {
+		u16 red, blue, green, tsp;
+
+		sscanf(&buf[i * 16 +  3], "%4hx", &red);
+		sscanf(&buf[i * 16 +  7], "%4hx", &blue);
+		sscanf(&buf[i * 16 + 11], "%4hx", &green);
+		tsp = (buf[i * 16 +  2] != ' ');
+		if ((rc = fb_info->fbops->fb_setcolreg(start++,
+				      red, green, blue, tsp, fb_info)))
+			return rc;
+
+		fb_info->cmap.red[i] = red;
+		fb_info->cmap.blue[i] = blue;
+		fb_info->cmap.green[i] = green;
+		if (transp)
+			fb_info->cmap.transp[i] = tsp;
+	}
 	return 0;
 }
 
@@ -255,20 +311,24 @@ static ssize_t show_cmap(struct class_de
 {
 	struct fb_info *fb_info =
 		(struct fb_info *)class_get_devdata(class_device);
-	unsigned int offset = 0, i;
+	unsigned int i;
 
 	if (!fb_info->cmap.red || !fb_info->cmap.blue ||
-	    fb_info->cmap.green || fb_info->cmap.transp)
+	    !fb_info->cmap.green)
+		return -EINVAL;
+
+	if (PAGE_SIZE < 4096)
 		return -EINVAL;
 
+	/* don't mess with the format, the buffer is PAGE_SIZE */
+	/* 255 entries at 16 chars per line equals 4096 = PAGE_SIZE */
 	for (i = 0; i < fb_info->cmap.len; i++) {
-		offset += snprintf(buf, PAGE_SIZE - offset,
-				   "%d,%d,%d,%d,%d\n", i + fb_info->cmap.start,
-				   fb_info->cmap.red[i], fb_info->cmap.blue[i],
-				   fb_info->cmap.green[i],
-				   fb_info->cmap.transp[i]);
+		sprintf(&buf[ i * 16], "%02x%c%4x%4x%4x\n", i + fb_info->cmap.start,
+			((fb_info->cmap.transp && fb_info->cmap.transp[i]) ? '*' : ' '),
+			fb_info->cmap.red[i], fb_info->cmap.blue[i],
+			fb_info->cmap.green[i]);
 	}
-	return offset;
+	return 4096;
 }
 
 static ssize_t store_blank(struct class_device *class_device, const char * buf,

             reply	other threads:[~2005-06-12 15:30 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-06-12 15:30 Jon Smirl [this message]
2005-06-16  3:39 ` PATCH: Make sysfs color_map attribute work Jon Smirl
2005-06-21  0:02   ` James Simmons
2005-06-21  0:15     ` Jon Smirl
2005-06-21 22:10       ` James Simmons
2005-06-23 20:51         ` Jon Smirl

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=9e47339105061208305d0cf3cc@mail.gmail.com \
    --to=jonsmirl@gmail.com \
    --cc=linux-fbdev-devel@lists.sourceforge.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.