Added programming display CGRAM. Added display of characters from CGRAM. Changed prompts to allow free prompt strings. More code for the brewsystem unit editor.

Wed, 02 Dec 2015 17:16:41 +0100

author
Michiel Broek <mbroek@mbse.eu>
date
Wed, 02 Dec 2015 17:16:41 +0100
changeset 443
6b80a37fdf8d
parent 442
1193bd7d460f
child 444
eafb140a1ddd

Added programming display CGRAM. Added display of characters from CGRAM. Changed prompts to allow free prompt strings. More code for the brewsystem unit editor.

brewco/brewco.c file | annotate | diff | comparison | revisions
brewco/brewco.h file | annotate | diff | comparison | revisions
brewco/prompt.c file | annotate | diff | comparison | revisions
brewco/prompt.h file | annotate | diff | comparison | revisions
brewco/setup.c file | annotate | diff | comparison | revisions
brewco/slcd.c file | annotate | diff | comparison | revisions
brewco/slcd.h file | annotate | diff | comparison | revisions
brewpanel/sdlgui.c file | annotate | diff | comparison | revisions
brewpanel/sdlgui.h file | annotate | diff | comparison | revisions
brewpanel/slcd.c file | annotate | diff | comparison | revisions
brewpanel/sockio.c file | annotate | diff | comparison | revisions
config.h.in file | annotate | diff | comparison | revisions
--- a/brewco/brewco.c	Sat Nov 28 21:00:29 2015 +0100
+++ b/brewco/brewco.c	Wed Dec 02 17:16:41 2015 +0100
@@ -48,6 +48,19 @@
 #endif
 
 
+/*
+ * CGRAM characters
+ */
+unsigned char	degC[8] 	= { 0b01000, 0b10100, 0b01000, 0b00111, 0b01000, 0b01000, 0b01000, 0b00111 };
+unsigned char	degF[8] 	= { 0b01000, 0b10100, 0b01000, 0b00111, 0b00100, 0b00110, 0b00100, 0b00100 };
+unsigned char	SP_Symbol[8]	= { 0b11100, 0b10000, 0b11100, 0b00111, 0b11101, 0b00111, 0b00100, 0b00100 };
+unsigned char	PumpONOFF[8]	= { 0b00000, 0b01110, 0b01010, 0b01110, 0b01000, 0b01000, 0b01000, 0b00000 };
+unsigned char	RevPumpONOFF[8]	= { 0b11111, 0b10001, 0b10101, 0b10001, 0b10111, 0b10111, 0b10111, 0b11111 };
+unsigned char	HeatONOFF[8]	= { 0b00000, 0b01010, 0b01010, 0b01110, 0b01110, 0b01010, 0b01010, 0b00000 };
+unsigned char	RevHeatONOFF[8]	= { 0b11111, 0b10101, 0b10101, 0b10001, 0b10001, 0b10101, 0b10101, 0b11111 };
+unsigned char	Language[8]	= { 0b11111, 0b00010, 0b01000, 0b11111, 0b00000, 0b10001, 0b10101, 0b11111 };
+
+
 void help(void);
 void die(int);
 
@@ -94,6 +107,22 @@
     long		t = 0;
 #endif
 
+    prompt(101, NULL);
+
+    /*
+     * Define special characters in the display CGRAM
+     */
+    if (Config.tempFormat == 'C')
+    	slcdCharDef(slcdHandle, 1, degC);
+    else
+	slcdCharDef(slcdHandle, 1, degF);
+    slcdCharDef(slcdHandle, 2, SP_Symbol);
+    slcdCharDef(slcdHandle, 3, PumpONOFF);
+    slcdCharDef(slcdHandle, 4, RevPumpONOFF);
+    slcdCharDef(slcdHandle, 5, HeatONOFF);
+    slcdCharDef(slcdHandle, 6, RevHeatONOFF);
+    slcdCharDef(slcdHandle, 7, Language);
+
 //    if (lockprog((char *)"brewco")) {
 //	syslog(LOG_NOTICE, "Can't lock");
 //	return 1;
@@ -170,13 +199,12 @@
 	}
     }
 
-    prompt(101);
     if (! Config.units) {
 	/*
 	 * No brewsystems defined, add the first
 	 */
-	prompt(218);	/*   Add Brewsystem?   */
-	prompt(407);    /* ---  ---   Ok   --- */
+	prompt(218, NULL);	/*   Add Brewsystem?   */
+	prompt(407, NULL);    /* ---  ---   Ok   --- */
 
 	do {
 	    key = keywait();
@@ -217,9 +245,10 @@
 	    /*
 	     * Not running.
 	     */
-	    prompt(0);
-	    prompt(101);
-	    prompt(401);
+	    prompt(0, NULL);
+	    prompt(101, NULL);
+	    prompt(300, (char *)"---\001-\002-\003-\004-\005-\006-\007----");
+	    prompt(401, NULL);
 	    key = keywait();
 	    if (key == KEY_ENTER)
 		setup();
@@ -233,9 +262,9 @@
     if (debug)
 	fprintf(stdout, (char *)"Out of loop\n");
 
-    prompt(0);
-    prompt(101);
-    prompt(302);
+    prompt(0, NULL);
+    prompt(101, NULL);
+    prompt(302, NULL);
 
     /*
      * Stop units processing in a neat way
@@ -249,7 +278,7 @@
      */
     usleep(1500000);
 
-    prompt(0);
+    prompt(0, NULL);
 //    stopLCD();
     if (sock != -1) {
 	if (shutdown(sock, SHUT_RDWR)) {
--- a/brewco/brewco.h	Sat Nov 28 21:00:29 2015 +0100
+++ b/brewco/brewco.h	Wed Dec 02 17:16:41 2015 +0100
@@ -83,6 +83,8 @@
 #define MBSE_SS(x) (x)?(x):"(null)"
 
 
+
+
 /*
  * Sensor strcuture
  */
--- a/brewco/prompt.c	Sat Nov 28 21:00:29 2015 +0100
+++ b/brewco/prompt.c	Wed Dec 02 17:16:41 2015 +0100
@@ -32,7 +32,7 @@
 
 
 
-void prompt(int index)
+void prompt(int index, char *text)
 {
     char	message[81];
     int		line;
@@ -48,7 +48,9 @@
 			piUnlock(LOCK_LCD);
 #endif
 			return;
-	case 101:	snprintf(message, Config.lcd_cols + 1, "    Brewco %s    ", VERSION);
+	case 100:	snprintf(message, Config.lcd_cols + 1, text);
+			break;
+	case 101:	snprintf(message, Config.lcd_cols + 1, "    Brewco %s   \007", VERSION);
 			break;
 	case 102:	snprintf(message, Config.lcd_cols + 1, "     SETUP MENU     ");
 			break;
@@ -58,21 +60,33 @@
 			break;
 	case 111:	snprintf(message, Config.lcd_cols + 1, "AUTO --> Mash In    ");
 			break;
-	case 112:	snprintf(message, Config.lcd_cols + 1, "AUTO --> Fitasi     ");
+	case 112:	snprintf(message, Config.lcd_cols + 1, "AUTO --> Phytase    ");
 			break;
-	case 113:	snprintf(message, Config.lcd_cols + 1, "AUTO --> Glucanasi  ");
+	case 113:	snprintf(message, Config.lcd_cols + 1, "AUTO --> Glucanase  ");
 			break;
-	case 114:	snprintf(message, Config.lcd_cols + 1, "AUTO --> Proteasi   ");
+	case 114:	snprintf(message, Config.lcd_cols + 1, "AUTO --> Protease   ");
 			break;
-	case 115:	snprintf(message, Config.lcd_cols + 1, "AUTO --> B-amilasi  ");
+	case 115:	snprintf(message, Config.lcd_cols + 1, "AUTO --> \342-Amylase  ");	/* Beta	*/
 			break;
-	case 116:	snprintf(message, Config.lcd_cols + 1, "AUTO --> A-amilasi 1");
+	case 116:	snprintf(message, Config.lcd_cols + 1, "AUTO --> \340-Amylase 1");	/* Alpha */
 			break;
-	case 117:	snprintf(message, Config.lcd_cols + 1, "AUTO --> A-amilasi 2");
+	case 117:	snprintf(message, Config.lcd_cols + 1, "AUTO --> \340-Amylase 2");
 			break;
 	case 118:	snprintf(message, Config.lcd_cols + 1, "AUTO --> Mash Out   ");
 			break;
-	case 121:	snprintf(message, Config.lcd_cols + 1, "AUTO --> Hop   xx   ");
+	case 119:	snprintf(message, Config.lcd_cols + 1, "AUTO --> Boil       ");
+			break;
+	case 120:	snprintf(message, Config.lcd_cols + 1, "AUTO --> Cooling    ");
+			break;
+	case 121:	snprintf(message, Config.lcd_cols + 1, "AUTO --> Whirlpool  ");
+			break;
+	case 122:	snprintf(message, Config.lcd_cols + 1, "AUTO --> Hop   xx   ");
+			break;
+	case 131:	snprintf(message, Config.lcd_cols + 1, "  Edit brewsystem   ");
+			break;
+	case 132:	snprintf(message, Config.lcd_cols + 1, "   Toggle Yes/No    ");
+			break;
+	case 200:	snprintf(message, Config.lcd_cols + 1, text);
 			break;
 	case 202:	snprintf(message, Config.lcd_cols + 1, "   Manage Recipes   ");
 			break;
@@ -108,9 +122,13 @@
 			break;
 	case 218:	snprintf(message, Config.lcd_cols + 1, "  Add Brewsystem?   ");
 			break;
-	case 301:	snprintf(message, Config.lcd_cols + 1, "     Finished       ");
+	case 300:	snprintf(message, Config.lcd_cols + 1, text);
+			break;
+	case 301:	snprintf(message, Config.lcd_cols + 1, "      Finished      ");
 			break;
-	case 302:	snprintf(message, Config.lcd_cols + 1, "    Shutting down   ");
+	case 302:	snprintf(message, Config.lcd_cols + 1, "   Shutting down    ");
+			break;
+	case 400:	snprintf(message, Config.lcd_cols + 1, text);
 			break;
 	case 401:       snprintf(message, Config.lcd_cols + 1, "---  MAN  AUTO SETUP");
 			break;
--- a/brewco/prompt.h	Sat Nov 28 21:00:29 2015 +0100
+++ b/brewco/prompt.h	Wed Dec 02 17:16:41 2015 +0100
@@ -1,6 +1,6 @@
 #ifndef _PROMPT_H
 #define	_PROMPT_H
 
-void prompt(int);
+void prompt(int, char *);
 
 #endif
--- a/brewco/setup.c	Sat Nov 28 21:00:29 2015 +0100
+++ b/brewco/setup.c	Wed Dec 02 17:16:41 2015 +0100
@@ -36,11 +36,166 @@
 
 
 
+int toggleYesNo(int value, char *text)
+{
+    int		key, new = value;
+    char	pmpt[81];
+
+    prompt(0, NULL);
+    prompt(132, NULL);
+
+    for (;;) {
+
+        snprintf(pmpt, Config.lcd_cols + 1, "%s: %s", text, new ? (char *)"Yes":(char *)"No ");
+	prompt(200, pmpt);
+	if (new) {
+	    prompt(404, NULL);
+	} else {
+	    prompt(402, NULL);
+	}
+
+	key = keywait();
+	if ((key == KEY_RETURN) || my_shutdown)
+	    return value;
+	if ((key == KEY_UP) && new)
+	    new = 0;
+	else if ((key == KEY_DOWN) && (new == 0))
+	    new = 1;
+	if (key == KEY_ENTER)
+	    return new;
+    }
+}
+
+
+
 void editUnit(units_list *unit)
 {
+    int		index = 1, key;
+    char	pmpt[81];
+
     if (debug)
     	fprintf(stdout, "Start edit brewsystem %d %s\n", unit->number, unit->uuid);
 
+    prompt(0, NULL);
+
+    for (;;) {
+
+	prompt(0, NULL);
+	prompt(131, NULL);
+
+	if (index == 1)
+	    prompt(402, NULL);
+	else if (index == 21)
+	    prompt(404, NULL);
+	else
+	    prompt(403, NULL);
+
+	switch (index) {				//   12345678901234567890
+	    case 1:	snprintf(pmpt, Config.lcd_cols + 1, "Unit name:");
+			prompt(200, pmpt);
+			snprintf(pmpt, Config.lcd_cols + 1, "%s", unit->name);
+			prompt(300, pmpt);
+			break;
+	    case 2:	snprintf(pmpt, Config.lcd_cols + 1, "  HLT sensor setup");
+			prompt(200, pmpt);
+			break;
+	    case 3:	snprintf(pmpt, Config.lcd_cols + 1, "  HLT heater setup");
+			prompt(200, pmpt);
+			break;
+	    case 4:	snprintf(pmpt, Config.lcd_cols + 1, "  MLT sensor setup");
+			prompt(200, pmpt);
+			break;
+	    case 5:	snprintf(pmpt, Config.lcd_cols + 1, "  MLT heater setup");
+			prompt(200, pmpt);
+			break;
+	    case 6:	snprintf(pmpt, Config.lcd_cols + 1, "   MLT pump setup");
+			prompt(200, pmpt);
+			break;
+	    case 7:	snprintf(pmpt, Config.lcd_cols + 1, "MLT heat b4 HLT: %s", unit->hlt_heater_mltfirst ? (char *)"Yes":(char *)"No");
+			prompt(200, pmpt);
+			break;
+	    case 8:	snprintf(pmpt, Config.lcd_cols + 1, "Pump cycle: %2d mins", unit->pump_cycle);
+			prompt(200, pmpt);
+			break;
+	    case 9:	snprintf(pmpt, Config.lcd_cols + 1, "Pump rest : %2d mins", unit->pump_rest);
+			prompt(200, pmpt);
+			break;
+	    case 10:	snprintf(pmpt, Config.lcd_cols + 1, " Pump pre-mash: %s", unit->pump_premash ? (char *)"Yes":(char *)"No");
+			prompt(200, pmpt);
+			break;
+	    case 11:	snprintf(pmpt, Config.lcd_cols + 1, " Pump on-mash: %s", unit->pump_onmash ? (char *)"Yes":(char *)"No");
+			prompt(200, pmpt);
+			break;
+	    case 12:	snprintf(pmpt, Config.lcd_cols + 1, " Pump mashout: %s", unit->pump_mashout ? (char *)"Yes":(char *)"No");
+			prompt(200, pmpt);
+			break;
+	    case 13:	snprintf(pmpt, Config.lcd_cols + 1, " Pump on-boil: %s", unit->pump_onboil ? (char *)"Yes":(char *)"No");
+			prompt(200, pmpt);
+			break;
+	    case 14:	snprintf(pmpt, Config.lcd_cols + 1, "  Pump stop: %3d\337C", unit->pump_stop);
+			prompt(200, pmpt);
+			break;
+	    case 15:	snprintf(pmpt, Config.lcd_cols + 1, "    Skip Add: %s", unit->skip_add ? (char *)"Yes":(char *)"No");
+			prompt(200, pmpt);
+			break;
+	    case 16:	snprintf(pmpt, Config.lcd_cols + 1, "  Skip Remove: %s", unit->skip_remove ? (char *)"Yes":(char *)"No");
+			prompt(200, pmpt);
+			break;
+	    case 17:	snprintf(pmpt, Config.lcd_cols + 1, "  Skip Iodine: %s", unit->skip_iodine ? (char *)"Yes":(char *)"No");
+			prompt(200, pmpt);
+			break;
+	    case 18:	snprintf(pmpt, Config.lcd_cols + 1, "Iodine time: %3d min", unit->iodine_time);
+			prompt(200, pmpt);
+			break;
+	    case 19:	snprintf(pmpt, Config.lcd_cols + 1, "   Whirlpool: %s", unit->whirlpool ? (char *)"Yes":(char *)"No");
+			prompt(200, pmpt);
+			break;
+	    case 20:	snprintf(pmpt, Config.lcd_cols + 1, "   HLT PID setup");
+			prompt(200, pmpt);
+			break;
+	    case 21:	snprintf(pmpt, Config.lcd_cols + 1, "   MLT PID setup");
+			prompt(200, pmpt);
+			break;
+	}
+
+	key = keywait();
+	if ((key == KEY_RETURN) || my_shutdown)
+	    return;
+
+	if ((key == KEY_UP) && (index > 1))
+	    index--;
+	if ((key == KEY_DOWN) && (index < 21))
+	    index++;
+
+	if (key == KEY_ENTER) {
+	    switch(index) {
+		case 7:	unit->hlt_heater_mltfirst = toggleYesNo(unit->hlt_heater_mltfirst , (char *)"MLT heat b4 HLT");
+			break;
+	    }
+	}
+    // name
+    // hlt_sensor  picklist
+    // hlt_heater  picklist + value range
+    // mlt_sensor  picklist
+    // mlt_heater  picklist + value range
+    // mlt_pump    picklist + value range
+    // hlt_heater_mltfirst  0/1
+    // pump_cycle 5..15
+    // pump_rest  1..5
+    // pump_premash 0/1
+    // pump_onmash  0/1
+    // pump_mashout 0/1
+    // pump_onboil  0/1
+    // pump_stop   80..110
+    // skip_add     0/1
+    // skip_remove  0/1
+    // skip_iodine  0/1
+    // iodine_time  0..90
+    // whirlpool    0/1
+    // PID_hlt
+    // PID_mlt
+    }
+
     if (debug)
 	fprintf(stdout, "End edit brewsystem %d %s\n", unit->number, unit->uuid);
 }
@@ -113,19 +268,19 @@
     for (;;) {
 	if (debug)
 	    fprintf(stdout, "setup() option=%d\n", option);
-	prompt(0);
-	prompt(102);
-	prompt(option);
+	prompt(0, NULL);
+	prompt(102, NULL);
+	prompt(option, NULL);
 	if (option == 202)
-	    prompt(402);
+	    prompt(402, NULL);
 #ifdef USE_SIMULATOR
 	else if (option == 205)
 #else
 	else if (option == 204)
 #endif
-	    prompt(404);
+	    prompt(404, NULL);
 	else
-	    prompt(403);
+	    prompt(403, NULL);
 
 	key = keywait();
 
@@ -142,6 +297,22 @@
 	    option++;
 	}
 
+	if (key == KEY_ENTER) {
+	    switch(option) {
+		case 202:	// recipes
+				break;
+		case 203:	editUnit(Config.units);	/* If more units, via a selector */
+				break;
+		case 204:	// devices
+				break;
+#ifdef USE_SIMULATOR
+		case 205:	// simulator
+				break;
+#endif
+	    }
+	    if (my_shutdown)
+		return;
+	}
     }
 }
 
--- a/brewco/slcd.c	Sat Nov 28 21:00:29 2015 +0100
+++ b/brewco/slcd.c	Wed Dec 02 17:16:41 2015 +0100
@@ -138,9 +138,21 @@
 
 
 
-//void slcdCharDef(int fd, int index, unsigned char data[8])
-//{
-//}
+void slcdCharDef(int fd, int index, unsigned char data[8])
+{
+    int		i;
+    uint16_t	byte;
+
+    if (debug)
+	fprintf(stdout, "CharDef(%d, %d, %02x, %02x, %02x, %02x, %02x, %02x, %02x, %02x)\n", fd, index, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
+
+    byte = SLCD_CGRAM | ((index & 7) << 3);
+    putLCDsocket(fd, byte);
+    for (i = 0; i < 8; i++) {
+	byte = data[i] & 0xff;
+	putLCDsocket(fd, byte);
+    }
+}
 
 
 
--- a/brewco/slcd.h	Sat Nov 28 21:00:29 2015 +0100
+++ b/brewco/slcd.h	Wed Dec 02 17:16:41 2015 +0100
@@ -6,6 +6,7 @@
 void slcdLEDs(int fd);
 void slcdClear(int fd);
 void slcdPosition(int fd, int x, int y);
+void slcdCharDef(int fd, int index, unsigned char data[8]);
 void slcdPutchar(int fd, unsigned char c);
 void slcdPuts(int fd, const char *string);
 void slcdPrintf(int fd, const char *message, ...);
--- a/brewpanel/sdlgui.c	Sat Nov 28 21:00:29 2015 +0100
+++ b/brewpanel/sdlgui.c	Wed Dec 02 17:16:41 2015 +0100
@@ -245,6 +245,63 @@
 
 
 
+void SDLGui_CGChar(SGOBJ *dlg, int fd, int x, int y, Uint8 data[8])
+{
+    int		i, j, x1, x2, y1, y2, dstpitch = 0;
+    SDL_Rect	sr, dr;
+    Uint32	bg;
+    Uint8	*dstbits = NULL, mask;
+    SDL_Surface	*CGchar;
+    SDL_Color	blackWhiteColors[2] = {{255, 255, 255, 0}, {53, 59, 61, 0}};
+
+    CGchar = SDL_CreateRGBSurface(SDL_SWSURFACE, 10, 16, 8, 0, 0, 0, 0);
+    if (CGchar == NULL) {
+	fprintf(stderr, "SDLGui_CGChar Can not init font graphics!\n");
+	return;
+    }
+    dstbits = (Uint8 *)CGchar->pixels;
+    dstpitch = CGchar->pitch;
+    mask = 0x10;
+    i = j = 0;
+
+    /*
+     * Create a bitmap with the character pixels
+     */
+    for (y1 = 0; y1 < 8; y1++) {
+	for (y2 = 0; y2 < 2; y2++) {
+	    j = 0;
+	    for (x1 = 0; x1 < 5; x1++) {
+		for (x2 = 0; x2 < 2; x2++) {
+		    dstbits[j] = (data[i] & mask) ? 1 : 0;
+		    j++;
+		}
+		mask >>= 1;
+		if (! mask)
+		    mask = 0x10;
+	    }
+	    dstbits += dstpitch;
+	}
+	i++;
+    }
+
+    SDL_SetColors(CGchar, blackWhiteColors, 0, 2);
+    SDL_SetColorKey(CGchar, (SDL_SRCCOLORKEY|SDL_RLEACCEL), 0);
+    bg = LCDbg0;
+
+    sr.x = sr.y = 0;
+    dr.x = x;
+    dr.y = y;
+    sr.w = dr.w = fontwidth;
+    sr.h = dr.h = fontheight;
+
+    SDL_FillRect(pSdlGuiScrn, &dr, bg);
+    SDL_BlitSurface(CGchar, &sr, pSdlGuiScrn, &dr);
+    SDL_UpdateRect(pSdlGuiScrn, x, y, fontwidth, fontheight);
+    SDL_FreeSurface(CGchar);
+}
+
+
+
 /*
  * Draw a text character
  */
--- a/brewpanel/sdlgui.h	Sat Nov 28 21:00:29 2015 +0100
+++ b/brewpanel/sdlgui.h	Wed Dec 02 17:16:41 2015 +0100
@@ -51,6 +51,7 @@
 
 void SDLGui_LED(SGOBJ *dlg, int fd, int LED, int on);
 void SDLGui_Cursor(SGOBJ *dlg, int fd, int x, int y, int on, int blink);
+void SDLGui_CGChar(SGOBJ *dlg, int fd, int x, int y, Uint8 dataf[8]);
 void SDLGui_Char(SGOBJ *dlg, int fd, int x, int y, Uint8 c);
 void SDLGui_DrawLCD(SGOBJ *bdlg, int objnum);
 int  SDLGui_Init(void);
--- a/brewpanel/slcd.c	Sat Nov 28 21:00:29 2015 +0100
+++ b/brewpanel/slcd.c	Wed Dec 02 17:16:41 2015 +0100
@@ -141,8 +141,9 @@
     struct slcdDataStruct *lcd = slcds [fd];
     int i;
 
-    for (i = 0 ; i < 8 ; i++)
+    for (i = 0 ; i < 8 ; i++) {
 	lcd->cgram[index][i] = data[i];
+    }
 }
 
 
@@ -152,7 +153,13 @@
 {
     struct slcdDataStruct *lcd = slcds [fd];
 
-    SDLGui_Char(dlg, fd, lcd->x + (lcd->cx * 12) + 12, lcd->y + (lcd->cy * 18) + 8, data);
+    if (data < 16)
+	/*
+	 * Character 0..7 and 8..15 are the same.
+	 */
+	SDLGui_CGChar(dlg, fd, lcd->x + (lcd->cx * 12) + 12, lcd->y + (lcd->cy * 18) + 8, lcd->cgram[data & 0x07]);
+    else
+    	SDLGui_Char(dlg, fd, lcd->x + (lcd->cx * 12) + 12, lcd->y + (lcd->cy * 18) + 8, data);
 
     if (++lcd->cx == lcd->cols) {
 	lcd->cx = 0;
--- a/brewpanel/sockio.c	Sat Nov 28 21:00:29 2015 +0100
+++ b/brewpanel/sockio.c	Wed Dec 02 17:16:41 2015 +0100
@@ -38,10 +38,11 @@
 void socket_recv(SGOBJ *dlg)
 {
     uint16_t		data;
+    unsigned char	cgdata[8];
     struct sockaddr_in	clntaddr;
     socklen_t		clntlen = sizeof(clntaddr);
     ssize_t		recv_len;
-    int			fd = 0, my_error;
+    int			i, index, fd = 0, my_error;
 
     recv_len = recvfrom(sock, &data, sizeof(uint16_t), MSG_DONTWAIT, (struct sockaddr *)&clntaddr, &clntlen);
     if (recv_len == sizeof(uint16_t)) {
@@ -55,6 +56,22 @@
 	    slcdClear(dlg, fd);
 	} else if ((data & SLCD_MHOME) == SLCD_HOME) {
 	    slcdHome(dlg, fd);
+	} else if ((data & SLCD_MCGRAM) == SLCD_CGRAM) {
+	    index = (data & 0x038) >> 3;
+	    for (i = 0; i < 8; i++) {
+		/*
+		 * Reply with the current keyboard state. Looks too early but the very last reply
+		 * will be sent at the end of this function and we need to take 8 data words.
+		 */
+		if (sendto(sock, &keys, sizeof(uint16_t), MSG_DONTWAIT, (struct sockaddr *) &clntaddr, clntlen) == -1) {
+		    syslog(LOG_NOTICE, "socket_recv() sendto error: %s", strerror(errno));
+		}
+		recv_len = recvfrom(sock, &data, sizeof(uint16_t), 0, (struct sockaddr *)&clntaddr, &clntlen);
+		cgdata[i] = data & 0x00ff;
+	    }
+	    fprintf(stdout, "Got new CGRAM index=%d, %02x %02x %02x %02x %02x %02x %02x %02x\n", index,
+			    cgdata[0], cgdata[1], cgdata[2], cgdata[3], cgdata[4], cgdata[5], cgdata[6], cgdata[7]);
+	    slcdCharDef(dlg, fd, index, cgdata);
 	} else if ((data & SLCD_MDGRAM) == SLCD_DGRAM) {
 	    slcdPosition(dlg, fd, data & 0x001f, (data & 0x0060) >> 5);
 	} else if ((data & 0xfe00) == SLCD_DATA) {
--- a/config.h.in	Sat Nov 28 21:00:29 2015 +0100
+++ b/config.h.in	Wed Dec 02 17:16:41 2015 +0100
@@ -11,6 +11,8 @@
 #define SLCD_MCLEAR     0x1fff
 #define SLCD_HOME       0x0002
 #define SLCD_MHOME      0x1ffe
+#define	SLCD_CGRAM	0x0040
+#define	SLCD_MCGRAM	0x1fc0
 #define SLCD_DGRAM      0x0080
 #define SLCD_MDGRAM     0x1f80
 #define SLCD_DATA       0x0200

mercurial