Changes relative to first patch version (20080628):
===================================================

concordance.1
- changed entry for IR learn option

concordance.c
Note: In contrast to Phil's belief, _getch will actually return only '\r'
when you hit return, as getchar wil return '\n', so the code is right
by design, not by accident.
- added comments about the _getch/getchar/set_canon stuff
- renamed USE_DEFAULT to ENTER_KEY
- no more function names with leading underscores
- fixed obscure increment/decrement of key index in learn_ir_commands
- some formatting fixes
Index: concordance/concordance.1
===================================================================
RCS file: /cvsroot/concordance/concordance/concordance/concordance.1,v
retrieving revision 1.9
diff -u -3 -p -r1.9 concordance.1
--- concordance/concordance.1	15 Apr 2008 02:32:32 -0000	1.9
+++ concordance/concordance.1	10 Oct 2008 18:14:24 -0000
@@ -60,7 +60,7 @@ Get time from the remote
 Set the time on the remote
 .TP
 .B \-l, \-\-learn-ir <filename>
-Learn IR from other remotes. Use <filename>.
+Learn IR commands from other remotes. Use <filename>. When you selected multiple commands to learn on the Logitech website, you can move through this command list and let the Harmony learn the IR code for each command.
 .TP
 .B \-r, \-\-reset
 Reset (power-cycle) the remote control
@@ -90,6 +90,7 @@ Enable verbose output.
 .TP
 .B \-w, \-\-no\-web
 Do not attempt to talk to the website. This is useful for re-programming the remote from a saved file, or for debugging.
+.TP
 .SH BUGS
 None known at time of release, but check the website.
 .SH BUG REPORTS
Index: concordance/concordance.c
===================================================================
RCS file: /cvsroot/concordance/concordance/concordance/concordance.c,v
retrieving revision 1.32
diff -u -3 -p -r1.32 concordance.c
--- concordance/concordance.c	15 Apr 2008 06:17:02 -0000	1.32
+++ concordance/concordance.c	10 Oct 2008 18:14:24 -0000
@@ -37,6 +37,7 @@
 #define strcasecmp stricmp
 #define strncasecmp strnicmp
 #define sleep(x) Sleep((x) * 1000)
+#define strdup _strdup
 
 /*
  * Windows, in it's infinite awesomeness doesn't include POSIX things
@@ -46,12 +47,25 @@
 char* basename(char* file_name)
 {
 	char* _basename = strrchr(file_name, '\\');
-
+	
 	return _basename ? _basename+1 : file_name;
 }
 
 HANDLE con;
 
+/*
+ * (see below) Windows does not need this, since _getch already
+ * does what we need - just make set_canon do nothing 
+ * Note that _getch returns '\r' when user hits the <Enter> key
+ */
+int set_canon(int flag)
+{
+	return(1);
+}
+
+#define read_key _getch
+#define ENTER_KEY '\r'
+
 #else
 /* NON-Windows */
 
@@ -59,6 +73,29 @@ HANDLE con;
 #include <strings.h>
 #include <libgen.h>
 #include <unistd.h>
+#include <termios.h>
+
+/*
+ * set_canon in LINUX modifies stdin such that getchar behaves like
+ * _getch in Windows, i.e. the next key is returned immediately.
+ * Note that getchar returns '\n' when user hits the <Enter> key
+ */
+int set_canon(int flag)
+{
+	struct termios t;
+
+	tcgetattr(0, &t);
+	if (flag) {
+		t.c_lflag |= ICANON;
+	} else {
+		t.c_lflag &= ~ICANON;
+	}
+	tcsetattr(0, TCSANOW, &t); 
+	return(1);
+}
+/* Thus, we can define: */
+#define read_key getchar
+#define ENTER_KEY '\n'
 
 #endif
 
@@ -140,6 +177,205 @@ void cb_print_percent_status(uint32_t co
 	fflush(stdout);
 }
 
+void print_ir_burst(uint32_t length)
+{
+	if (length < 250) {
+		printf("|");
+	} else if (length < 1000) {
+		printf("#");
+	} else {
+		printf("##");
+	}
+}
+
+void print_ir_space(uint32_t length)
+{
+	if (length < 250) {
+		printf(".");
+	} else if (length < 1000) {
+		printf("_");
+	} else if (length < 10000) {
+		printf("__");
+	} else {
+		printf("\n");
+	}
+}
+
+void print_received_ir_signal(uint32_t carrier_clock, uint32_t *ir_signal,
+	uint32_t ir_signal_length, struct options_t *options)
+{
+	uint32_t index;
+	printf("\nASCII-graph of received IR signal:\n");
+	for (index=0; index < ir_signal_length; index += 2){
+		print_ir_burst(ir_signal[index]);
+		print_ir_space(ir_signal[index+1]);
+	}
+	printf("\n");
+	printf("Carrier clock          : %u Hz\n", carrier_clock);
+	printf("Total mark/space pairs : %u\n\n", ir_signal_length/2);
+#ifdef _DEBUG
+	/*
+	 * full dump of new IR signal:
+	 */
+	for (index=0; index < ir_signal_length; index += 2){
+		printf("\tP:%6u\tS:%6u\n", ir_signal[index],
+			ir_signal[index+1]);
+	}
+#endif
+}
+
+char get_cmd(char *prompt, char *allowed, char def) {
+	char result = 0;
+	char got_key;
+	uint32_t index;
+	set_canon(0);
+	while ( result == 0 ) {
+		printf("%s (%c)?", prompt, def);
+		got_key = read_key();
+		printf("\n");
+		if (got_key == ENTER_KEY) {
+			result = def;
+		} else {
+			for (index = 0; index < strlen(allowed); index++) {
+				if (allowed[index] == got_key) {
+					result = got_key;
+					break;
+				}
+			}
+		}
+	}
+	set_canon(1);
+	return result;
+}	
+
+int learn_ir_commands(uint8_t *data, uint32_t size, struct options_t *options)
+{
+	int err = 0;
+	uint32_t carrier_clock = 0;
+	uint32_t *ir_signal = NULL;
+	uint32_t ir_signal_length = 0;
+	uint32_t index = 0;
+	char **key_names;
+	uint32_t key_names_length = 0;
+	char *post_string = NULL;
+	char user_cmd;
+
+	err = get_key_names(data, size, &key_names, &key_names_length);
+	if ((err != 0) || (key_names_length == 0)) { return err; }
+	
+	printf("Received file contains %u key names to be learned.\n",
+		key_names_length);
+	
+	while (1) {
+		if (index >= key_names_length) {
+			index--;
+			printf("Last key in list!\n");
+		}
+		printf("\nKey name : <%s> : \n", key_names[index]);
+		user_cmd = get_cmd(
+			"[L]earn, [N]ext, [P]revious, [Q]uit",
+			"LlHhNnPpQq", 'L');
+		err = -1; 
+		/* have no code yet */
+		switch (user_cmd) {
+			case 'L':
+			case 'l':
+				/* learn from remote: */
+				printf("press corresponding key ");
+				printf("on original remote within 5 sec:\n");
+				printf("Learning IR signal:  ");
+				cb_print_percent_status(0, 0, 1, NULL);
+				err = learn_from_remote(&carrier_clock,
+					&ir_signal, &ir_signal_length);
+				if (err == 0) {
+					cb_print_percent_status(1, 1, 1, NULL);
+					printf("       done\n");
+				}
+				break;
+			case 'P':
+			case 'p':
+				if (index > 0) {
+					index--;
+				} else {
+					printf("First key in list!\n");
+				}
+				break;
+			case 'N':
+			case 'n':
+				index++;
+				break;
+			default:
+				break;
+		}				
+		if ( err == 0 ) {
+			/* have new IR code: */
+			if ((*options).verbose) {
+				print_received_ir_signal(carrier_clock,
+					ir_signal, ir_signal_length, options);
+			}
+			err = encode_for_posting(carrier_clock, ir_signal,
+					ir_signal_length, &post_string);
+			/* done with learned signal, free memory: */
+			delete_ir_signal(ir_signal);
+		}
+			
+		if ( err == 0 ) {
+			/* have successfully encoded new code: */
+#ifdef _DEBUG				
+			if ((*options).verbose) {
+				printf("%s\n\n", post_string );
+			}
+#endif
+			if (!(*options).noweb) {
+				user_cmd = get_cmd(
+				"[U]pload new code, [R]etry same key, [N]ext key, [Q]uit",
+				"UuRrNnQq", 'U');
+			} else {
+				/* no upload: just skip to next key */
+				user_cmd = 'N';
+			}
+			switch (user_cmd) {
+				case 'U':
+				case 'u':
+					printf("Upload to website:   ");
+					cb_print_percent_status(
+						0, 0, 1, NULL);
+					err = post_new_code(data, size, 
+						key_names[index], post_string);
+						if ( err == 0 ) {
+						cb_print_percent_status(
+							1, 1, 1, NULL);
+						printf("       done\n");
+						index++;
+					} else {
+						printf("       failed\n");
+					}
+					break;
+				case 'N':
+				case 'n':
+					index++;
+					break;
+				default:
+					break;
+			}
+			/* done, free memory */
+			delete_encoded_signal(post_string);
+		} else {
+			if (err > 0) {
+				printf("\nError receiving IR signal:\n\t%s \n",
+					lc_strerror(err));
+			}
+		}
+		
+		if (user_cmd == 'Q' || user_cmd == 'q') {
+			break;
+		}
+	}
+	/* done, free memory */
+	delete_key_names(key_names, key_names_length);
+	return 0;
+}
+
 /*
  * Start helper functions
  */
@@ -222,7 +458,8 @@ int upload_config(uint8_t *data, uint32_
 	binary_size = size;
 
 	if (!(*options).binary) {
-		if ((err = find_config_binary(data, size, &binary_data, &binary_size)))
+		if ((err = find_config_binary(data, size,
+					       &binary_data, &binary_size)))
 			return LC_ERROR;
 
 		if (!(*options).noweb)
@@ -256,7 +493,8 @@ int upload_config(uint8_t *data, uint32_
 	printf("       done\n");
 
 	printf("Verifying Config:    ");
-	if ((err = verify_remote_config(binary_data, binary_size, cb, (void *)1))) {
+	if ((err = verify_remote_config(binary_data,
+				       binary_size, cb, (void *)1))) {
 		return err;
 	}
 	printf("       done\n");
@@ -1032,7 +1270,7 @@ int main(int argc, char *argv[])
 			break;
 
 		case MODE_LEARN_IR:
-			err = learn_ir_commands(data, size, !options.noweb);
+			err = learn_ir_commands(data, size, &options);
 			break;
 
 		case MODE_GET_TIME:
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
concordance-devel mailing list
concordance-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/concordance-devel

Reply via email to