# HG changeset patch # User Michiel Broek # Date 1447001369 -3600 # Node ID f1a042a59b61822098fa47d35610f66cd40fc0af # Parent ae85e91dcc58b212460d6b410ea451c1f06a86ad Basic ideas to write to the simulated LCD display are in place. diff -r ae85e91dcc58 -r f1a042a59b61 brewpanel/Makefile --- 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 diff -r ae85e91dcc58 -r f1a042a59b61 brewpanel/dlgBrew.c --- 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; diff -r ae85e91dcc58 -r f1a042a59b61 brewpanel/dlgBrew.h --- 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 diff -r ae85e91dcc58 -r f1a042a59b61 brewpanel/sdlgui.c --- 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 diff -r ae85e91dcc58 -r f1a042a59b61 brewpanel/sdlgui.h --- 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 diff -r ae85e91dcc58 -r f1a042a59b61 brewpanel/slcd.c --- /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 + * + * 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 diff -r ae85e91dcc58 -r f1a042a59b61 brewpanel/slcd.h --- /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