imonlcd: spinning disc and progess bars

"Karsten A. M. Günther" <[email protected]>
Newsgroups gmane.comp.sysutils.lcdproc
Message-ID <[email protected]>
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hello lcdproc'ers,

I would like to ask you a question regarding lcdproc 0.5.4 and the
imonlcd driver. I am working on a patch for XBMC media center for full
icon support in combination with Soundgraph's IMON LCD display and
lcdproc (http://trac.xbmc.org/ticket/8981). In fact, it is working quite
fine, but since lcdproc 0.5.4 there is an issue regarding the spinning
disc animation. Everytime, the progress bars are updated, the animation
stops for a short moment until the icons are updated again. I wrote the
attached perl script to verify this. This script executed with lcdproc
0.5.3 shows the spinning disc and a second later all progress bars and
lines. The disc keeps spinning as expected. With lcdproc 0.5.4 the disc
starts spinning, after a seconds it stops and the progress bars come up
and after another second it starts spinning again.

For my needs I reverted some changes in imonlcd.c, see attached patch file.

My question: am I doing or understanding something wrong or is this just
a bug in the code cleanup and rework you did in imonlcd.c between 0.5.3
and 0.5.4?

Best regards,
Karsten Guenther

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQEcBAEBAgAGBQJNr1A1AAoJEGeYm4AaNYHY1i4IAIDnk2KjUrIrq0363R3Kmez0
nIJKlGbZNepvISGK1ATpnPd14HCDfbDo0UJi1PPc4PMZsDJ0XkJoOd4sVTrKLyxr
unFQGBOxJFUBFXUUTvjjQG9mTZsrdAZagHmskt9C0oPBGZGJeCeu4JQUiegr3OvK
zBAgQi0ms3Fx3kcSjQQmMZ9/GjXOSMGl4mJ0gB9g+Us5GWg3eC3w8+mq0FeXWdYU
YFGD8a45kHxUDRM3PLv3vbWXB81D3hwyYaTzpEwSoGjmxJqvCLXIxtuwr1nHLfFw
fEsprXN75kvOc9Jt9Z6odx+XWzZEGrlHRI2wF593BR3vpb2lWoyppP5agFPWeX8=
=hzqM
-----END PGP SIGNATURE-----

_______________________________________________
LCDproc mailing list
[email protected]
http://lists.omnipotent.net/mailman/listinfo/lcdproc
imon_disc_and_progress.pl (application/x-perl, 911 B)
#!/usr/bin/perl -w

use IO::Socket; 

my $sockres;
my $sock;

#see here for details of imon lcd driver output control bits
#http://lcdproc.cvs.sourceforge.net/viewvc/lcdproc/lcdproc/server/drivers/imonlcd.c?view=markup

$sock = new IO::Socket::INET (PeerAddr => 'localhost', PeerPort => '13666', Proto => 'tcp', ); 
die "Could not create socket: $!\n" unless $sock; 
print $sock "hello\n";
$sockres = readline $sock;

my $icondata = 0;

### turn on spinning disc
$icondata = $icondata | (1<<0);
printf $sock "output %i\n",$icondata;
$sockres = readline $sock;

sleep 1;

### turn on all bars
$progress  =   100 * 32 / 100;
printf $sock "output %i\n",(($progress) | ($progress << 6) | ($progress << 12) | ($progress << 18) | (1<<28));
$sockres = readline $sock;

sleep 1;

### turn on spinning disc
$icondata = $icondata | (1<<0); 
printf $sock "output %i\n",$icondata;
$sockres = readline $sock;

close $sock;
imonlcd.c.diff (text/x-patch, 4.9 KB)
--- lcdproc-0.5.4.orig/server/drivers/imonlcd.c
+++ lcdproc-0.5.4/server/drivers/imonlcd.c
@@ -123,11 +123,16 @@
 	uint64_t command_display_on;
 	uint64_t command_clear_alarm;
 
-	/* last "state" of the CD icon so that we can animate it */
+	/*
+	 * record the last "state" of the CD icon so that we can "animate"
+	 * it.
+	 */
 	int last_cd_state;
+	time_t last_cd_state_change;
 
-	/* save the last output state so we don't needlessly reset the icons */
-	int last_output_state;
+	/* remind the last state for setting the icons */
+	uint64_t last_icon_state;
+	int lastPrivateIconState;
 } PrivateData;
 
 /*
@@ -291,7 +296,8 @@
 	p->cellheight = LCD_DEFAULT_CELL_HEIGHT; /* height of a character, in pixels */
 
 	p->last_cd_state = 0;
-	p->last_output_state = 0x0;	/* no icons turned on at startup */
+	p->last_icon_state = 0x0;	/* no icons turned on at startup */
+	p->lastPrivateIconState = 0x0;	/* no icons turned on at startup */
 	p->discMode = 0;
 
 	/* Get settings from config file */
@@ -864,14 +870,10 @@
 	PrivateData *p = drvthis->private_data;
 	uint64_t icon = 0x0;
 
-	if (state == p->last_output_state)
-		return;
-
-	p->last_output_state = state;
-
 	if (state == -1) {	/* the value for "on" in the lcdproc-protocol */
 		icon = (uint64_t) IMON_ICON_ALL;
 		send_command_data(COMMANDS_SET_ICONS | icon, p);
+		p->lastPrivateIconState = state;
 		setLineLength(32, 32, 32, 32, p);
 
 		return;
@@ -879,6 +881,7 @@
 					 * lcdproc-protocol */
 		icon = (uint64_t) 0x0;;
 		send_command_data(COMMANDS_SET_ICONS | icon, p);
+		p->lastPrivateIconState = state;
 		setLineLength(0, 0, 0, 0, p);
 		return;
 	}
@@ -896,35 +899,50 @@
 		topLine = topLine > 32 ? -(topLine - 32) : topLine;
 
 		setLineLength(topLine, botLine, topProgress, botProgress, p);
-		return;
+
+		/* continue and set all other icons as before */
+		state = p->lastPrivateIconState;
 	}
 	/* bit 0 : disc icon (0=off, 1='spin') */
-	if (state & IMON_OUTPUT_CD_MASK) {
-		/* Each icon bit represents a section of the cd,
-		 * starting at the top as msb, and going counter-clockwise.
-		 * Start with the top-right & bottom-left on.
-		 */
-		unsigned char tmp_cd_bitmap = (0x01 | (0x01 << 4));
-
-		if (p->last_cd_state >= 3 )
+	if ((state & IMON_OUTPUT_CD_MASK) != 0) {
+		switch (p->last_cd_state) {
+		case 0:
+			p->last_cd_state = 1;
+			if (p->discMode == 1)
+				/* all on except top & bottom */
+				icon |= ((uint64_t) (255 - 128 - 8) << 40);
+			else
+				/* top & bottom on */
+				icon |= ((uint64_t) (128 | 8) << 40);
+			break;
+		case 1:
+			p->last_cd_state = 2;
+			if (p->discMode == 1)
+				/* all on except top-right & bottom-left */
+				icon |= ((uint64_t) (255 - 16 - 1) << 40);
+			else
+				/* top-right & bottom-left on */
+				icon |= ((uint64_t) (1 | 16) << 40);
+			break;
+		case 2:
+			p->last_cd_state = 3;
+			if (p->discMode == 1)
+				/* all on except right & left */
+				icon |= ((uint64_t) (255 - 32 - 2) << 40);
+			else
+				/* right & left on */
+				icon |= ((uint64_t) (32 | 2) << 40);
+			break;
+		default:
 			p->last_cd_state = 0;
-		else
-			p->last_cd_state++;
-
-		/* Shift the bits to the left, and the cd moves clock-wise. */
-		tmp_cd_bitmap <<= p->last_cd_state;
-
-		if (p->discMode == 1)
-			tmp_cd_bitmap = ~tmp_cd_bitmap;
-
-		icon |= ((uint64_t)tmp_cd_bitmap) << 40;
-
-		/* Change the cached output state so that we will continue to
-		 * update / spin the cd. The set value makes a missed refresh
-		 * or clear very unusual.  The server core makes sure we get
-		 * the correct value next time around.
-		 */
-		p->last_output_state = (~IMON_OUTPUT_PBARS_MASK & ~IMON_OUTPUT_CD_MASK);
+			if (p->discMode == 1)
+				/* all on except top-left & bottom-right */
+				icon |= ((uint64_t) (255 - 64 - 4) << 40);
+			else
+				/* top-left & bottom-right on */
+				icon |= ((uint64_t) (4 | 64) << 40);
+			break;
+		}
 	}
 	/*
 	 * bit 1,2,3 : top row (0=none, 1=music, 2=movie, 3=photo, 4=CD/DVD,
@@ -958,14 +976,17 @@
 		}
 	}
 	/* bit 4,5 : 'speaker' icons (0=off, 1=L+R, 2=5.1ch, 3=7.1ch) */
-	if (state & IMON_OUTPUT_SPEAKER_MASK) {
+	if (((state & IMON_OUTPUT_SPEAKER_MASK) != 0)) {
 		switch (((state & IMON_OUTPUT_SPEAKER_MASK) >> 4)) {
-		case 3:
-			icon |= (IMON_SPKR_SL | IMON_SPKR_SR);
-		case 2:
-			icon |= (IMON_SPKR_FC | IMON_SPKR_RL | IMON_SPKR_RR);
 		case 1:
-			icon |= (IMON_SPKR_FL | IMON_SPKR_FR);
+			icon |= IMON_SPKR_FL | IMON_SPKR_FR;
+			break;
+		case 2:
+			icon |= IMON_SPKR_FL | IMON_SPKR_FC | IMON_SPKR_FR | IMON_SPKR_RL | IMON_SPKR_RR;
+			break;
+		case 3:
+			icon |= IMON_SPKR_FL | IMON_SPKR_FC | IMON_SPKR_FR | IMON_SPKR_RL | IMON_SPKR_RR | IMON_SPKR_SL | IMON_SPKR_SR;
+			break;
 		default:
 			break;
 		}
@@ -1065,7 +1086,9 @@
 	/* bit 29 : 'disc-in' */
 	icon = ((state & IMON_OUTPUT_DISK_IN_MASK) != 0) ? (icon | IMON_ICON_DISK_IN) : (icon & ~IMON_ICON_DISK_IN);
 
-	send_command_data(COMMANDS_SET_ICONS | icon, p);
+	p->last_icon_state = (uint64_t) icon;
+	p->lastPrivateIconState = state;
+	send_command_data(COMMANDS_SET_ICONS | p->last_icon_state, p);
 }
 
 /**
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.