Basic ideas to write to the simulated LCD display are in place.

Sun, 08 Nov 2015 17:49:29 +0100

author
Michiel Broek <mbroek@mbse.eu>
date
Sun, 08 Nov 2015 17:49:29 +0100
changeset 412
f1a042a59b61
parent 411
ae85e91dcc58
child 413
299551b5dab5

Basic ideas to write to the simulated LCD display are in place.

brewpanel/Makefile file | annotate | diff | comparison | revisions
brewpanel/dlgBrew.c file | annotate | diff | comparison | revisions
brewpanel/dlgBrew.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/slcd.h file | annotate | diff | comparison | revisions
--- a/brewpanel/Makefile	Sat Nov 07 22:42:47 2015 +0100
+++ b/brewpanel/Makefile	Sun Nov 08 17:49:29 2015 +0100
@@ -57,7 +57,8 @@
 
 # DO NOT DELETE THIS LINE - MAKE DEPEND RELIES ON IT
 # Dependencies generated by make depend
+slcd.o: brewpanel.h slcd.h
 sdlgui.o: brewpanel.h sdlgui.h lcdfont10x16.h
-dlgBrew.o: brewpanel.h dlgBrew.h sdlgui.h
+dlgBrew.o: brewpanel.h dlgBrew.h sdlgui.h slcd.h
 brewpanel.o: brewpanel.h sdlgui.h dlgBrew.h
 # End of generated dependencies
--- a/brewpanel/dlgBrew.c	Sat Nov 07 22:42:47 2015 +0100
+++ b/brewpanel/dlgBrew.c	Sun Nov 08 17:49:29 2015 +0100
@@ -26,6 +26,8 @@
 #include "brewpanel.h"
 #include "dlgBrew.h"
 #include "sdlgui.h"
+#include "slcd.h"
+
 
 #ifdef HAVE_SDL_SDL_H
 
@@ -57,6 +59,17 @@
 
 
 
+int Dialog_LCDinit(int *x, int *y, int *w, int *h, int *cols, int *rows, int index)
+{
+    int	retval;
+
+    retval = SDLGui_LCDinit(maindlg, x, y, w, h, cols, rows, index);
+
+    fprintf(stdout, "SDLGui_LCDinit(maindlg, %d, %d, %d, %d, %d, %d, %d) = %d\n", *x, *y, *w, *h, *cols, *rows, index, retval);
+    return retval;
+}
+
+
 
 /*
  * This functions sets up the actual font and then displays the brew panel dialog.
@@ -66,6 +79,7 @@
     int retbut;
     int bOldMouseVisibility;
     int nOldMouseX, nOldMouseY;
+    int x, y, w, h, cols, rows, fd;
 
     if (SDLGui_SetScreen(PAN_surface)) {
 	syslog(LOG_NOTICE, "SDLGui_SetScreen(PAN_surface) failed: %s", SDL_GetError());
@@ -77,10 +91,14 @@
     SDL_ShowCursor(SDL_ENABLE);
 
     SDLGui_CenterDlg(maindlg);
+    SDLGui_DoDialogInit(maindlg);
+    fd = Dialog_LCDinit(&x, &y, &w, &h, &cols, &rows, 0);
+    fprintf(stdout, "Dialog_LCDinit(%d, %d, %d, %d, %d, %d, 0) = %d\n", x, y, w, h, cols, rows, fd);
+    slcdInit(fd, x, y, w, h, cols, rows);
 
     do {
-	retbut = SDLGui_DoDialog(maindlg, NULL);
- SDLGui_LCDwrite(maindlg, 0, 0, 'A', 0);
+	retbut = SDLGui_DoDialogLoop(maindlg);
+	slcdPuts(0, (char *)"Hello");
 
 	fprintf(stdout, "SDLGui_DoDialog retbut=%d\n", retbut);
 
@@ -99,6 +117,7 @@
 
     } while (retbut != SDLGUI_QUIT && retbut != SDLGUI_ERROR && !my_shutdown);
 
+    SDLGui_DoDialogEnd();
     SDL_ShowCursor(bOldMouseVisibility);
 
     return TRUE;
--- a/brewpanel/dlgBrew.h	Sat Nov 07 22:42:47 2015 +0100
+++ b/brewpanel/dlgBrew.h	Sun Nov 08 17:49:29 2015 +0100
@@ -3,7 +3,8 @@
 
 #ifdef HAVE_SDL_SDL_H
 
-int Dialog_BrewDlg(void);
+int  Dialog_LCDinit(int *x, int *y, int *w, int *h, int *cols, int *rows, int index);
+int  Dialog_BrewDlg(void);
 
 #endif
 #endif
--- a/brewpanel/sdlgui.c	Sat Nov 07 22:42:47 2015 +0100
+++ b/brewpanel/sdlgui.c	Sun Nov 08 17:49:29 2015 +0100
@@ -33,6 +33,8 @@
 
 static SDL_Surface	*pSdlGuiScrn;            	/* Pointer to the actual main SDL screen surface 	*/
 static SDL_Surface	*pFontGfx = NULL;        	/* The LCD font graphics 				*/
+static SDL_Surface	*pBgSurface;			/* Pointer to the application SDL screen surface	*/
+static SDL_Rect		dlgrect, bgrect;
 static int		fontwidth, fontheight;		/* Width & height of the actual font 			*/
 TTF_Font                *pFont = NULL;			/* TTF font for buttons etc.				*/
 
@@ -86,7 +88,7 @@
 {
     char	*Pt = NULL;
 
-    SDL_Color blackWhiteColors[2] = {{255, 255, 255, 0}, {0, 0, 0, 0}};
+    SDL_Color blackWhiteColors[2] = {{255, 255, 255, 0}, {53, 59, 61, 0}};
 
     /* 
      * Initialize the LCD font graphics: 
@@ -219,16 +221,64 @@
 
 
 /*
+ * Draw the cursor
+ */
+void SDLGui_Cursor(int x, int y)
+{
+    SDL_Rect	dr;
+    Uint32      color = SDL_MapRGB(pSdlGuiScrn->format, 53, 59, 61);
+
+    dr.x=x;
+    dr.y=y;
+    dr.w=fontwidth;
+    dr.h=fontheight;
+
+    SDL_FillRect(pSdlGuiScrn, &dr, color);
+    SDL_UpdateRect(pSdlGuiScrn, x, y, fontwidth, fontheight);
+}
+
+
+
+/*
+ * Draw a text character
+ */
+void SDLGui_Char(int x, int y, Uint8 c, int bLight)
+{
+    SDL_Rect    sr, dr;
+    Uint32	bg;
+
+    if (bLight)
+	bg = SDL_MapRGB(pSdlGuiScrn->format,156,235,  4);
+    else
+	bg = SDL_MapRGB(pSdlGuiScrn->format, 94,147, 69);
+
+    sr.x=fontwidth*(c%16);
+    sr.y=fontheight*(c/16);
+    sr.w=fontwidth;
+    sr.h=fontheight;
+    dr.x=x;
+    dr.y=y;
+    dr.w=fontwidth;
+    dr.h=fontheight;
+
+    SDL_FillRect(pSdlGuiScrn, &dr, bg);
+    SDL_BlitSurface(pFontGfx, &sr, pSdlGuiScrn, &dr);
+    SDL_UpdateRect(pSdlGuiScrn, x, y, fontwidth, fontheight);
+}
+
+
+
+/*
  * Draw a text string.
  */
 static void SDLGui_Text(int x, int y, const char *txt)
 {
     int		i;
-    char	c;
+    Uint8	c;
     SDL_Rect	sr, dr;
 
     for (i=0; txt[i]!=0; i++) {
-	c = txt[i];
+	c = txt[i] & 0xff;
 	sr.x=fontwidth*(c%16);
 	sr.y=fontheight*(c/16);
 	sr.w=fontwidth;
@@ -519,22 +569,14 @@
 
 
 /*
- * Show and process a dialog. Returns the button number that has been
- * pressed or SDLGUI_UNKNOWNEVENT if an unsupported event occured (will be
- * stored in parameter pEventOut).
+ * Show dialog.
  */
-int SDLGui_DoDialog(SGOBJ *dlg, SDL_Event *pEventOut)
+int SDLGui_DoDialogInit(SGOBJ *dlg)
 {
-    int		obj = 0, oldbutton = 0, retbutton = 0, i, j, b;
-    SDL_Event	sdlEvent;
-    SDL_Surface	*pBgSurface;
-    SDL_Rect	dlgrect, bgrect;
-
-//	if (pSdlGuiScrn->h / fontheight < dlg[0].h)
-//	{
-//		syslog(LOG_NOTICE, "Screen size too small for dialog!");
-//		return SDLGUI_ERROR;
-//	}
+    if ((pSdlGuiScrn->h < dlg[0].h) && (pSdlGuiScrn->w < dlg[0].w)) {
+	syslog(LOG_NOTICE, "Screen size too small for dialog!");
+	return SDLGUI_ERROR;
+    }
 
     dlgrect.x = dlg[0].x;
     dlgrect.y = dlg[0].y;
@@ -562,6 +604,18 @@
 
     /* (Re-)draw the dialog */
     SDLGui_DrawDialog(dlg);
+    return 0;
+}
+
+
+
+/*
+ * Process a dialog. Returns the button number that has been pressed
+ */
+int SDLGui_DoDialogLoop(SGOBJ *dlg)
+{
+    int         obj = 0, oldbutton = 0, retbutton = 0, b, i, j;
+    SDL_Event   sdlEvent;
 
     /* 
      * Is the left mouse button still pressed? Yes -> Handle TOUCHEXIT objects here
@@ -588,8 +642,6 @@
 		case SDL_MOUSEBUTTONDOWN:
 				if (sdlEvent.button.button != SDL_BUTTON_LEFT) {
 				    /* Not left mouse button -> unsupported event */
-				    if (pEventOut)
-					retbutton = SDLGUI_UNKNOWNEVENT;
 				    break;
 				}
 				/* It was the left button: Find the object under the mouse cursor */
@@ -608,11 +660,9 @@
 				}
 				break;
 
-			 case SDL_MOUSEBUTTONUP:
+		 case SDL_MOUSEBUTTONUP:
 				if (sdlEvent.button.button != SDL_BUTTON_LEFT) {
 				    /* Not left mouse button -> unsupported event */
-				    if (pEventOut)
-					retbutton = SDLGUI_UNKNOWNEVENT;
 				    break;
 				}
 				/* It was the left button: Find the object under the mouse cursor */
@@ -628,8 +678,7 @@
 				if (oldbutton > 0) {
 				    dlg[oldbutton].state &= ~SG_SELECTED;
 				    SDLGui_DrawButton(dlg, oldbutton);
-				    SDL_UpdateRect(pSdlGuiScrn, (dlg[0].x+dlg[oldbutton].x)*fontwidth-2, (dlg[0].y+dlg[oldbutton].y)*fontheight-2,
-						dlg[oldbutton].w*fontwidth+4, dlg[oldbutton].h*fontheight+4);
+				    SDL_UpdateRect(pSdlGuiScrn, dlg[0].x+dlg[oldbutton].x-2, dlg[0].y+dlg[oldbutton].y-2, dlg[oldbutton].w+4, dlg[oldbutton].h+4);
 				    oldbutton = 0;
 				}
 				if (obj >= 0 && (dlg[obj].flags & SG_EXIT)) {
@@ -637,36 +686,19 @@
 				}
 				break;
 
-			 case SDL_MOUSEMOTION:
+		 case SDL_MOUSEMOTION:
 				break;
 
-			 case SDL_KEYDOWN:                     /* Key pressed */
+		 case SDL_KEYDOWN:                     /* Key pressed */
 				if (sdlEvent.key.keysym.sym == SDLK_RETURN || sdlEvent.key.keysym.sym == SDLK_KP_ENTER) {
 				    retbutton = SDLGui_SearchFlaggedButton(dlg, SG_DEFAULT);
 				} else if (sdlEvent.key.keysym.sym == SDLK_ESCAPE) {
 				    retbutton = SDLGui_SearchFlaggedButton(dlg, SG_CANCEL);
-				} else if (pEventOut) {
-				    retbutton = SDLGUI_UNKNOWNEVENT;
 				}
 				break;
-
-			 default:
-				if (pEventOut)
-				    retbutton = SDLGUI_UNKNOWNEVENT;
-				break;
 	    }
     }
 
-    /* Restore background */
-    if (pBgSurface) {
-	SDL_BlitSurface(pBgSurface, &bgrect, pSdlGuiScrn,  &dlgrect);
-	SDL_FreeSurface(pBgSurface);
-    }
-
-    /* Copy event data of unsupported events if caller wants to have it */
-    if (retbutton == SDLGUI_UNKNOWNEVENT && pEventOut)
-	memcpy(pEventOut, &sdlEvent, sizeof(SDL_Event));
-
     if (retbutton == SDLGUI_QUIT)
 	my_shutdown = TRUE;
 
@@ -675,6 +707,58 @@
 
 
 
+void SDLGui_DoDialogEnd(void)
+{
+    /* Restore background */
+    if (pBgSurface) {
+	SDL_BlitSurface(pBgSurface, &bgrect, pSdlGuiScrn,  &dlgrect);
+	SDL_FreeSurface(pBgSurface);
+    }
+}
+
+
+
+/*
+ * Initialize a LCD object. Set the coordinates and dimenstions. Return index.
+ */
+int  SDLGui_LCDinit(SGOBJ *dlg, int *x, int *y, int *w, int *h, int *cols, int *rows, int lcdindex)
+{
+    int		i, index;
+
+    /*
+     * Search the LCD display
+     */
+    *x = *y = *w = *h = *cols = *rows = i = index = 0;
+    for (;;) {
+	if (dlg[i].type == -1) {
+	    syslog(LOG_NOTICE, "SDLGui_LCDinit() lcdindex=%d not found", lcdindex);
+	    return -1;
+	}
+	if (dlg[i].type == SGLCD) {
+	    if (index == lcdindex)
+		break;
+	    index++;
+	}
+	i++;
+    }
+    fprintf(stdout, "SDLGui_LCDinit=%d LCD=%dx%d %dx%d\n", i, dlg[i].x, dlg[i].y, dlg[i].w, dlg[i].h);
+
+    *cols = dlg[i].w;
+    *rows = dlg[i].h;
+    *w = dlg[i].w * (fontwidth + 2) + 10;
+    *h = dlg[i].h * (fontheight + 2) + 4;
+    if (dlg[i].x == -1) {
+	*x = (dlg[0].w - *w) / 2;
+    } else {
+	*x = dlg[i].x;
+    }
+    *y = dlg[i].y;
+
+    return lcdindex;
+}
+
+
+/*
 void SDLGui_LCDwrite(SGOBJ *dlg, int x, int y, Uint8 c, int lcdindex)
 {
     int		i, index;
@@ -697,6 +781,7 @@
     fprintf(stdout, "SDLGui_LCDwrite i=%d LCD=%dx%d\n", i, dlg[i].w, dlg[i].h);
 
 }
+*/
 
 #endif
 
--- a/brewpanel/sdlgui.h	Sat Nov 07 22:42:47 2015 +0100
+++ b/brewpanel/sdlgui.h	Sun Nov 08 17:49:29 2015 +0100
@@ -45,12 +45,17 @@
 
 
 
+void SDLGui_Cursor(int x, int y);
+void SDLGui_Char(int x, int y, Uint8 c, int);
 int  SDLGui_Init(void);
 int  SDLGui_UnInit(void);
 int  SDLGui_SetScreen(SDL_Surface *pScrn);
 void SDLGui_DrawDialog(const SGOBJ *dlg);
-int  SDLGui_DoDialog(SGOBJ *dlg, SDL_Event *pEventOut);
+int  SDLGui_DoDialogInit(SGOBJ *dlg);
+int  SDLGui_DoDialogLoop(SGOBJ *dlg);
+void SDLGui_DoDialogEnd(void);
 void SDLGui_CenterDlg(SGOBJ *dlg);
+int  SDLGui_LCDinit(SGOBJ *dlg, int *x, int *y, int *w, int *h, int *cols, int *rows, int lcdindex);
 void SDLGui_LCDwrite(SGOBJ *dlg, int x, int y, Uint8 c, int lcdindex);
 
 #endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/brewpanel/slcd.c	Sun Nov 08 17:49:29 2015 +0100
@@ -0,0 +1,251 @@
+/*****************************************************************************
+ * Copyright (C) 2015
+ *   
+ * Michiel Broek <mbroek at mbse dot eu>
+ *
+ * This file is part of the mbsePi-apps
+ *
+ * mbsePi-apps is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * mbsePi-apps is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with mbsePi-apps; see the file COPYING.  If not, write to the Free
+ * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *****************************************************************************/
+
+/*
+ * Simulated LCD driver based on HD44780U displays.
+ */
+
+#include "brewpanel.h"
+#include "slcd.h"
+#include "sdlgui.h"
+
+
+#ifdef HAVE_SDL_SDL_H
+
+// HD44780U Commands
+
+#define SLCD_CLEAR       0x01
+#define SLCD_HOME        0x02
+#define SLCD_ENTRY       0x04
+#define SLCD_CTRL        0x08
+#define SLCD_CDSHIFT     0x10
+#define SLCD_FUNC        0x20
+#define SLCD_CGRAM       0x40
+#define SLCD_DGRAM       0x80
+
+// // Bits in the entry register
+//
+// #define LCD_ENTRY_SH            0x01
+// #define LCD_ENTRY_ID            0x02
+//
+// // Bits in the control register
+//
+// #define LCD_BLINK_CTRL          0x01
+// #define LCD_CURSOR_CTRL         0x02
+// #define LCD_DISPLAY_CTRL        0x04
+
+
+struct slcdDataStruct
+{
+    int 	x;		/* Start x pixels		*/
+    int		y;		/* Start y pixels		*/
+    int		w;		/* Width in pixels		*/
+    int		h;		/* Height in pixels		*/
+    int		cols;		/* Width in characters		*/
+    int		rows;		/* Height in characters		*/
+    int		cx;		/* Cursor x position		*/
+    int		cy;		/* Cursor y position		*/
+    Uint8	cgram[8][8];	/* Characters in CGRAM		*/
+};
+struct slcdDataStruct *slcds [MAX_SLCDS] ;
+
+
+/* Low level */
+
+void sendDataCmd (struct slcdDataStruct *slcd, unsigned char data)
+{
+}
+
+
+void putCommand (struct slcdDataStruct *slcd, unsigned char command)
+{
+}
+
+
+
+void slcdHome(int fd)
+{
+    struct slcdDataStruct *lcd = slcds [fd];
+
+    lcd->cx = lcd->cy = 0;
+}
+
+
+
+void slcdClear(int fd)
+{
+    struct slcdDataStruct *lcd = slcds [fd];
+
+    lcd->cx = lcd->cy = 0;
+}
+
+
+
+void slcdDisplay(int fd, int state)
+{
+}
+
+
+
+void slcdCursor(int fd, int state)
+{
+}
+
+
+
+void slcdCursorBlink(int fd, int state)
+{
+}
+
+
+
+void slcdSendCommand(int fd, Uint8 command)
+{
+}
+
+
+
+void slcdPosition(int fd, int x, int y)
+{
+    struct slcdDataStruct *lcd = slcds [fd];
+
+    if ((x > lcd->cols) || (x < 0))
+	return ;
+    if ((y > lcd->rows) || (y < 0))
+	return ;
+
+    // putCommand (lcd, x + (LCD_DGRAM | rowOff [y])) ;
+
+    lcd->cx = x ;
+    lcd->cy = y ;
+}
+
+
+
+void slcdCharDef(int fd, int index, Uint8 data[8])
+{
+    struct slcdDataStruct *lcd = slcds [fd];
+    int i;
+
+    for (i = 0 ; i < 8 ; i++)
+	lcd->cgram[index][i] = data[i];
+}
+
+
+
+
+void slcdPutchar(int fd, Uint8 data)
+{
+    struct slcdDataStruct *lcd = slcds [fd];
+
+    SDLGui_Char(lcd->x + (lcd->cx * 12) + 12, lcd->y + (lcd->cy * 18) + 8, data, 0);
+
+    if (++lcd->cx == lcd->cols) {
+	lcd->cx = 0;
+	if (++lcd->cy == lcd->rows)
+	    lcd->cy = 0;
+    }
+    SDLGui_Cursor(lcd->x + (lcd->cx * 12) + 12, lcd->y + (lcd->cy * 18) + 8);
+}
+
+
+
+void slcdPuts(int fd, const char *string)
+{
+    while (*string)
+	slcdPutchar(fd, *string++);
+}
+
+
+
+void slcdPrintf(int fd, const char *message, ...)
+{
+    va_list	argp;
+    char	buffer[1024];
+
+    va_start(argp, message);
+    vsnprintf(buffer, 1023, message, argp);
+    va_end(argp);
+    slcdPuts(fd, buffer);
+}
+
+
+
+int slcdInit(int fd, int x, int y, int w, int h, int cols, int rows)
+{
+    static int			initialised = 0;
+    int				i, j;
+    struct slcdDataStruct	*lcd;
+
+    if (initialised == 0) {
+	initialised = 1 ;
+	for (i = 0 ; i < MAX_SLCDS ; ++i)
+	    slcds[i] = NULL ;
+    }
+
+    if ((rows < 0) || (rows > 20))
+	return -1 ;
+
+    if ((cols < 0) || (cols > 20))
+	return -1 ;
+
+    /*
+     * Create LCD
+     */
+    if (slcds[fd] != NULL) {
+	syslog(LOG_NOTICE, "slcdInit fd=%d already in use", fd);
+	return -1;
+    }
+    if ((lcd = (struct slcdDataStruct *)malloc (sizeof (struct slcdDataStruct))) == NULL) {
+	return -1;
+    }
+
+    lcd->x = x;
+    lcd->y = y;
+    lcd->w = w;
+    lcd->h = h;
+    lcd->cols = cols;
+    lcd->rows = rows;
+    lcd->cx = 0;
+    lcd->cy = 0;
+    for (i = 0; i < 8; i++)
+	for (j = 0; j < 8; j++)
+	    lcd->cgram[i][j] = 0;
+
+    slcds[fd] = lcd;
+
+    slcdDisplay(fd, TRUE);
+    slcdCursor(fd, FALSE);
+    slcdCursorBlink(fd, FALSE);
+    slcdClear(fd);
+
+    /*
+     * Most LCD's start with the top row filled with blocks.
+     */
+    for (i = 0; i < lcd->cols; i++)
+	slcdPutchar(fd, 0x0ff);
+
+    return fd;
+}
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/brewpanel/slcd.h	Sun Nov 08 17:49:29 2015 +0100
@@ -0,0 +1,23 @@
+#ifndef _SLCD_H
+#define	_SLCD_H
+#ifdef	HAVE_SDL_SDL_H
+
+#define	MAX_SLCDS	8
+
+void slcdHome        (int fd) ;
+void slcdClear       (int fd) ;
+void slcdDisplay     (int fd, int state) ;
+void slcdCursor      (int fd, int state) ;
+void slcdCursorBlink (int fd, int state) ;
+void slcdSendCommand (int fd, unsigned char command) ;
+void slcdPosition    (int fd, int x, int y) ;
+void slcdCharDef     (int fd, int index, unsigned char data [8]) ;
+void slcdPutchar     (int fd, unsigned char data) ;
+void slcdPuts        (int fd, const char *string) ;
+void slcdPrintf      (int fd, const char *message, ...) ;
+
+int  slcdInit        (int fd, int x, int y, int w, int h, int cols, int rows) ;
+
+
+#endif
+#endif

mercurial