Thu, 10 Dec 2015 15:58:01 +0100
Manual mode added.
/***************************************************************************** * Copyright (C) 2015 * * Michiel Broek <mbroek at mbse dot eu> * * This file is part of the mbsePi-apps emulator * * The gui code is based on the gui from the emulator ARAnyM, * Copyright (c) 2004 Petr Stehlik of ARAnyM dev team * * This progrm 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. *****************************************************************************/ #include "brewpanel.h" #include "sdlgui.h" #include "sockio.h" #ifdef HAVE_SDL_SDL_H #include "lcdfont10x16.h" 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. */ static Uint32 LCDbg0 = 0; /* LCD background dark */ static Uint32 LCDbg1 = 0; /* LCD background light */ extern int my_shutdown; extern int debug; /*-----------------------------------------------------------------------*/ /* * Load an 1 plane XBM into a 8 planes SDL_Surface. */ static SDL_Surface *SDLGui_LoadXBM(int w, int h, const char *pXbmBits) { SDL_Surface *bitmap; Uint8 *dstbits; const Uint8 *srcbits; int x, y, srcpitch, mask; srcbits = (Uint8 *)pXbmBits; /* Allocate the bitmap */ if ((bitmap = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 8, 0, 0, 0, 0)) == NULL) { syslog(LOG_NOTICE, "Failed to allocate bitmap: %s", SDL_GetError()); return NULL; } srcpitch = ((w + 7) / 8); dstbits = (Uint8 *)bitmap->pixels; mask = 1; /* Copy the pixels */ for (y = 0 ; y < h ; y++) { for (x = 0 ; x < w ; x++) { dstbits[x] = (srcbits[x / 8] & mask) ? 1 : 0; mask <<= 1; mask |= (mask >> 8); mask &= 0xFF; } dstbits += bitmap->pitch; srcbits += srcpitch; } return bitmap; } /* * Initialize the GUI. */ int SDLGui_Init(void) { char *Pt = NULL; SDL_Color blackWhiteColors[2] = {{255, 255, 255, 0}, {53, 59, 61, 0}}; /* * Initialize the LCD font graphics: */ pFontGfx = SDLGui_LoadXBM(lcdfont10x16_width, lcdfont10x16_height, lcdfont10x16_bits); if (pFontGfx == NULL) { syslog(LOG_NOTICE, "Error: Can not init font graphics!"); return -1; } /* Set color palette of the LCD font graphics: */ SDL_SetColors(pFontGfx, blackWhiteColors, 0, 2); /* Set font color 0 as transparent: */ SDL_SetColorKey(pFontGfx, (SDL_SRCCOLORKEY|SDL_RLEACCEL), 0); if (TTF_Init() == -1) { syslog(LOG_NOTICE, "Could not init SDL_ttf"); return -1; } /* * Load TTF font for the dialogs */ Pt = calloc(1024, sizeof(char)); sprintf(Pt, "%s", "/usr/share/fonts/TTF/DejaVuSans.ttf"); if ((pFont = TTF_OpenFont(Pt, 14 )) == NULL) { sprintf(Pt, "%s", "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf"); if ((pFont = TTF_OpenFont(Pt, 14 )) == NULL) { sprintf(Pt, "%s", "/usr/share/fonts/truetype/freefont/DejaVuSans.ttf"); if ((pFont = TTF_OpenFont(Pt, 14 )) == NULL) { syslog(LOG_NOTICE, "Could not load DejaVuSans.ttf"); return -1; } } } syslog(LOG_NOTICE, "Using ttf font: %s\n", Pt); free(Pt); Pt = NULL; return 0; } /* * Uninitialize the GUI. */ int SDLGui_UnInit(void) { if (pFont) TTF_CloseFont(pFont); pFont = NULL; if (pFontGfx) SDL_FreeSurface(pFontGfx); pFontGfx = NULL; return 0; } /* * Inform the SDL-GUI about the actual SDL_Surface screen pointer and * prepare the font to suit the actual resolution. */ int SDLGui_SetScreen(SDL_Surface *pScrn) { pSdlGuiScrn = pScrn; if (pFontGfx == NULL) { syslog(LOG_NOTICE, "Error: A problem with the font occured!"); return -1; } /* Get the font width and height: */ fontwidth = pFontGfx->w/16; fontheight = pFontGfx->h/16; return 0; } /* * Center a dialog so that it appears in the middle of the screen. * Note: We only store the coordinates in the root box of the dialog, * all other objects in the dialog are positioned relatively to this one. */ void SDLGui_CenterDlg(SGOBJ *dlg) { dlg[0].x = (pSdlGuiScrn->w/1-dlg[0].w)/2; dlg[0].y = (pSdlGuiScrn->h/1-dlg[0].h)/2; } /* * Draw a text string using TTF */ static void SDLGui_TTF(int x, int y, const char *txt) { SDL_Rect offset; SDL_Color textColor = { 0, 0, 0 }; SDL_Surface* message = NULL; message = TTF_RenderText_Solid(pFont, txt, textColor); offset.x = x; offset.y = y; SDL_BlitSurface(message, NULL, pSdlGuiScrn, &offset); SDL_FreeSurface(message); message = NULL; } /* * Draw a dialog TTF text object. */ static void SDLGui_DrawTTF(const SGOBJ *tdlg, int objnum) { int x, y; x = (tdlg[0].x + tdlg[objnum].x); y = (tdlg[0].y + tdlg[objnum].y); SDLGui_TTF(x, y, tdlg[objnum].txt); } /* * Draw the cursor */ void SDLGui_Cursor(SGOBJ *dlg, int fd, int x, int y, int on, int blink) { SDL_Rect dr; Uint32 color = SDL_MapRGB(pSdlGuiScrn->format, 53, 59, 61); if (on) { dr.x = x; dr.y = y + fontheight - 2; dr.w = fontwidth; dr.h = 2; SDL_FillRect(pSdlGuiScrn, &dr, color); SDL_UpdateRect(pSdlGuiScrn, x, y, fontwidth, fontheight); } } 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 */ void SDLGui_Char(SGOBJ *dlg, int fd, int x, int y, Uint8 c) { SDL_Rect sr, dr; Uint32 bg; // if (dlg[1].state & SG_SELECTED) { // bg = LCDbg1; // } else { bg = LCDbg0; // } 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; Uint8 c; SDL_Rect sr, dr; for (i=0; txt[i]!=0; i++) { c = txt[i] & 0xff; sr.x=fontwidth*(c%16); sr.y=fontheight*(c/16); sr.w=fontwidth; sr.h=fontheight; dr.x=x+i*(fontwidth+2); dr.y=y; dr.w=fontwidth; dr.h=fontheight; SDL_BlitSurface(pFontGfx, &sr, pSdlGuiScrn, &dr); } } /* * Draw a dialog text object. */ static void SDLGui_DrawText(const SGOBJ *tdlg, int objnum) { int x, y; x = (tdlg[0].x + tdlg[objnum].x); y = (tdlg[0].y + tdlg[objnum].y); SDLGui_Text(x, y, tdlg[objnum].txt); } /* * Draw a dialog LCD object. */ void SDLGui_DrawLCD(SGOBJ *bdlg, int objnum) { SDL_Rect rect; int x, y, w, h, offset, border = 4; Uint32 bc = SDL_MapRGB(pSdlGuiScrn->format, 32, 32, 32); Uint32 bg; LCDbg0 = SDL_MapRGB(pSdlGuiScrn->format, 94,147, 69); LCDbg1 = SDL_MapRGB(pSdlGuiScrn->format,156,235, 4); /* * Width and height are given in character columns and rows, * so calculate the display size in pixels. */ w = bdlg[objnum].w * (fontwidth + 2) + 10; h = bdlg[objnum].h * (fontheight + 2) + 4; if (bdlg[objnum].x == -1) { /* * Auto center */ x = (bdlg[0].w - w) / 2; } else { x = bdlg[objnum].x; } y = bdlg[objnum].y; if (objnum > 0) { /* Since the root object is a box, too, */ /* we have to look for it now here and only */ x += bdlg[0].x; /* add its absolute coordinates if we need to */ y += bdlg[0].y; } // if (bdlg[objnum].state & SG_SELECTED) { // bg = LCDbg1; // } else { bg = LCDbg0; // } /* The root box should be bigger than the screen, so we disable the offset there: */ if (objnum != 0) offset = border; else offset = 0; /* Draw background: */ rect.x = x; rect.y = y; rect.w = w; rect.h = h; SDL_FillRect(pSdlGuiScrn, &rect, bg); /* Draw upper border: */ rect.x = x - offset; rect.y = y - offset; rect.w = w + offset + offset; rect.h = border; SDL_FillRect(pSdlGuiScrn, &rect, bc); /* Draw left border: */ rect.x = x - offset; rect.y = y; rect.w = border; rect.h = h; SDL_FillRect(pSdlGuiScrn, &rect, bc); /* Draw bottom border: */ rect.x = x - offset; rect.y = y + h - border + offset; rect.w = w + offset + offset; rect.h = border; SDL_FillRect(pSdlGuiScrn, &rect, bc); /* Draw right border: */ rect.x = x + w - border + offset; rect.y = y; rect.w = border; rect.h = h; SDL_FillRect(pSdlGuiScrn, &rect, bc); } /* * Draw a dialog box object. */ static void SDLGui_DrawBox(const SGOBJ *bdlg, int objnum) { SDL_Rect rect; int x, y, w, h, offset, shade = 2; Uint32 grey = SDL_MapRGB(pSdlGuiScrn->format,192,192,192); Uint32 upleftc, downrightc; x = bdlg[objnum].x; y = bdlg[objnum].y; if (objnum > 0) { /* Since the root object is a box, too, */ /* we have to look for it now here and only */ x += bdlg[0].x; /* add its absolute coordinates if we need to */ y += bdlg[0].y; } w = bdlg[objnum].w; h = bdlg[objnum].h; if (bdlg[objnum].state & SG_SELECTED) { upleftc = SDL_MapRGB(pSdlGuiScrn->format,128,128,128); downrightc = SDL_MapRGB(pSdlGuiScrn->format,255,255,255); } else { upleftc = SDL_MapRGB(pSdlGuiScrn->format,255,255,255); downrightc = SDL_MapRGB(pSdlGuiScrn->format,128,128,128); } /* The root box should be bigger than the screen, so we disable the offset there: */ if (objnum != 0) offset = shade; else offset = 0; /* Draw background: */ rect.x = x; rect.y = y; rect.w = w; rect.h = h; SDL_FillRect(pSdlGuiScrn, &rect, grey); /* Draw upper border: */ rect.x = x; rect.y = y - offset; rect.w = w; rect.h = shade; SDL_FillRect(pSdlGuiScrn, &rect, upleftc); /* Draw left border: */ rect.x = x - offset; rect.y = y; rect.w = shade; rect.h = h; SDL_FillRect(pSdlGuiScrn, &rect, upleftc); /* Draw bottom border: */ rect.x = x; rect.y = y + h - shade + offset; rect.w = w; rect.h = shade; SDL_FillRect(pSdlGuiScrn, &rect, downrightc); /* Draw right border: */ rect.x = x + w - shade + offset; rect.y = y; rect.w = shade; rect.h = h; SDL_FillRect(pSdlGuiScrn, &rect, downrightc); } /* * Draw a normal button. */ static void SDLGui_DrawButton(const SGOBJ *bdlg, int objnum) { int x, y, w, h; SDLGui_DrawBox(bdlg, objnum); /* * Use bold text and get outer dimensions of the text */ TTF_SetFontStyle(pFont, TTF_STYLE_BOLD); TTF_SizeText(pFont, bdlg[objnum].txt, &w, &h); x = bdlg[0].x + bdlg[objnum].x + (bdlg[objnum].w - w) / 2; y = bdlg[0].y + bdlg[objnum].y + (bdlg[objnum].h - h) / 2; if (bdlg[objnum].state & SG_SELECTED) { x += 1; y += 1; } if ((bdlg[objnum].flags & SG_HIDE) == 0) SDLGui_TTF(x, y, bdlg[objnum].txt); TTF_SetFontStyle(pFont, TTF_STYLE_NORMAL); } /* * SDL_Surface 32-bit circle-fill algorithm without using trig * * While I humbly call this "Celdecea's Method", odds are that the * procedure has already been documented somewhere long ago. All of * the circle-fill examples I came across utilized trig functions or * scanning neighbor pixels. This algorithm identifies the width of * a semi-circle at each pixel height and draws a scan-line covering * that width. * * The code is not optimized but very fast, owing to the fact that it * alters pixels in the provided surface directly rather than through * function calls. */ void SDLGui_fill_circle(SDL_Surface *surface, int cx, int cy, int radius, Uint32 pixel) { /* * Note that there is more to altering the bitrate of this * method than just changing this value. See how pixels are * altered at the following web page for tips: * http://www.libsdl.org/intro.en/usingvideo.html */ static const int BPP = 4; double r = (double)radius; double dy; for (dy = 1; dy <= r; dy += 1.0) { /* * This loop is unrolled a bit, only iterating through half of the * height of the circle. The result is used to draw a scan line and * its mirror image below it. * * The following formula has been simplified from our original. We * are using half of the width of the circle because we are provided * with a center and we need left/right coordinates. */ double dx = floor(sqrt((2.0 * r * dy) - (dy * dy))); int x = cx - dx; // Grab a pointer to the left-most pixel for each half of the circle Uint8 *target_pixel_a = (Uint8 *)surface->pixels + ((int)(cy + r - dy)) * surface->pitch + x * BPP; Uint8 *target_pixel_b = (Uint8 *)surface->pixels + ((int)(cy - r + dy)) * surface->pitch + x * BPP; for (; x <= cx + dx; x++) { *(Uint32 *)target_pixel_a = pixel; *(Uint32 *)target_pixel_b = pixel; target_pixel_a += BPP; target_pixel_b += BPP; } } } static void SDLGUI_DrawLEDRed(const SGOBJ *bdlg, int objnum) { Uint32 color; if (bdlg[objnum].state & SG_SELECTED) { color = SDL_MapRGB(pSdlGuiScrn->format, 255, 64, 0); } else { color = SDL_MapRGB(pSdlGuiScrn->format, 128, 16, 0); } SDLGui_fill_circle(pSdlGuiScrn, bdlg[objnum].x, bdlg[objnum].y, bdlg[objnum].w, color); } static void SDLGUI_DrawLEDBlue(const SGOBJ *bdlg, int objnum) { Uint32 color; if (bdlg[objnum].state & SG_SELECTED) { color = SDL_MapRGB(pSdlGuiScrn->format, 64, 160, 255); } else { color = SDL_MapRGB(pSdlGuiScrn->format, 16, 48, 112); } SDLGui_fill_circle(pSdlGuiScrn, bdlg[objnum].x, bdlg[objnum].y, bdlg[objnum].w, color); } static void SDLGUI_DrawLEDGreen(const SGOBJ *bdlg, int objnum) { Uint32 color; if (bdlg[objnum].state & SG_SELECTED) { color = SDL_MapRGB(pSdlGuiScrn->format, 80, 240, 0); } else { color = SDL_MapRGB(pSdlGuiScrn->format, 32, 112, 0); } SDLGui_fill_circle(pSdlGuiScrn, bdlg[objnum].x, bdlg[objnum].y, bdlg[objnum].w, color); } static void SDLGUI_DrawLEDYellow(const SGOBJ *bdlg, int objnum) { Uint32 color; if (bdlg[objnum].state & SG_SELECTED) { color = SDL_MapRGB(pSdlGuiScrn->format, 255, 255, 0); } else { color = SDL_MapRGB(pSdlGuiScrn->format, 160, 144, 0); } SDLGui_fill_circle(pSdlGuiScrn, bdlg[objnum].x, bdlg[objnum].y, bdlg[objnum].w, color); } void SDLGui_LED(SGOBJ *dlg, int fd, int LED, int on) { int i; for (i = 0; dlg[i].type != -1; i++) { if (dlg[i].type == LED) { if (debug) fprintf(stdout, "SDLGui_LED LED=%d on=%d\n", LED, on); if (on) { dlg[i].state |= SG_SELECTED; } else { dlg[i].state &= ~SG_SELECTED; } switch (dlg[i].type) { case SGLEDRED: SDLGUI_DrawLEDRed(dlg, i); break; case SGLEDBLUE: SDLGUI_DrawLEDBlue(dlg, i); break; case SGLEDGREEN: SDLGUI_DrawLEDGreen(dlg, i); break; case SGLEDYELLOW: SDLGUI_DrawLEDYellow(dlg, i); break; } SDL_UpdateRect(pSdlGuiScrn, dlg[i].x - dlg[i].w, dlg[i].y - dlg[i].w, dlg[i].w * 2, dlg[i].w * 2); } } } /* * Draw a whole dialog. */ void SDLGui_DrawDialog(SGOBJ *dlg) { int i; for (i = 0; dlg[i].type != -1; i++) { switch (dlg[i].type) { case SGBOX: SDLGui_DrawBox(dlg, i); break; case SGLCD: SDLGui_DrawLCD(dlg, i); break; case SGTEXT: SDLGui_DrawText(dlg, i); break; case SGTTF: SDLGui_DrawTTF(dlg, i); break; case SGBUTTON: SDLGui_DrawButton(dlg, i); break; case SGLEDRED: SDLGUI_DrawLEDRed(dlg, i); break; case SGLEDBLUE: SDLGUI_DrawLEDBlue(dlg, i); break; case SGLEDGREEN: SDLGUI_DrawLEDGreen(dlg, i); break; case SGLEDYELLOW: SDLGUI_DrawLEDYellow(dlg, i); break; } } SDL_UpdateRect(pSdlGuiScrn, 0,0,0,0); } /* * Search an object at a certain position. */ static int SDLGui_FindObj(const SGOBJ *dlg, int fx, int fy) { int len, i, ob = -1, xpos, ypos; len = 0; while (dlg[len].type != -1) len++; xpos = fx; ypos = fy; /* Now search for the object: */ for (i = len; i >= 0; i--) { if (xpos >= dlg[0].x + dlg[i].x && ypos >= dlg[0].y + dlg[i].y && xpos < dlg[0].x + dlg[i].x + dlg[i].w && ypos < dlg[0].y + dlg[i].y + dlg[i].h) { ob = i; break; } } return ob; } /* * Show dialog. */ int SDLGui_DoDialogInit(SGOBJ *dlg) { 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; dlgrect.w = dlg[0].w; dlgrect.h = dlg[0].h; bgrect.x = bgrect.y = 0; bgrect.w = dlgrect.w; bgrect.h = dlgrect.h; /* * Save background */ pBgSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, dlgrect.w, dlgrect.h, pSdlGuiScrn->format->BitsPerPixel, pSdlGuiScrn->format->Rmask, pSdlGuiScrn->format->Gmask, pSdlGuiScrn->format->Bmask, pSdlGuiScrn->format->Amask); if (pSdlGuiScrn->format->palette != NULL) { SDL_SetColors(pBgSurface, pSdlGuiScrn->format->palette->colors, 0, pSdlGuiScrn->format->palette->ncolors-1); } if (pBgSurface != NULL) { SDL_BlitSurface(pSdlGuiScrn, &dlgrect, pBgSurface, &bgrect); } else { syslog(LOG_NOTICE, "SDLGUI_DoDialog: CreateRGBSurface failed: %s", SDL_GetError()); } /* (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, retbutton = 0; SDL_Event sdlEvent; /* The main loop */ while (retbutton == 0 && !my_shutdown) { /* * Poll network for data */ socket_recv(dlg); if (SDL_PollEvent(&sdlEvent) == 1) { /* Wait for events */ switch (sdlEvent.type) { case SDL_QUIT: retbutton = SDLGUI_QUIT; break; case SDL_MOUSEBUTTONDOWN: if (sdlEvent.button.button != SDL_BUTTON_LEFT) { /* Not left mouse button -> unsupported event */ break; } /* It was the left button: Find the object under the mouse cursor */ obj = SDLGui_FindObj(dlg, sdlEvent.button.x, sdlEvent.button.y); if (obj > 0) { if (dlg[obj].type == SGBUTTON) { dlg[obj].state |= SG_SELECTED; SDLGui_DrawButton(dlg, obj); SDL_UpdateRect(pSdlGuiScrn, dlg[0].x + dlg[obj].x - 2, dlg[0].y + dlg[obj].y - 2, dlg[obj].w + 4, dlg[obj].h + 4); retbutton = obj + 1000; } } break; case SDL_MOUSEBUTTONUP: if (sdlEvent.button.button != SDL_BUTTON_LEFT) { /* Not left mouse button -> unsupported event */ break; } /* It was the left button: Find the object under the mouse cursor */ obj = SDLGui_FindObj(dlg, sdlEvent.button.x, sdlEvent.button.y); if (obj > 0) { if (dlg[obj].type == SGBUTTON) { dlg[obj].state &= ~SG_SELECTED; SDLGui_DrawButton(dlg, obj); SDL_UpdateRect(pSdlGuiScrn, dlg[0].x + dlg[obj].x - 2, dlg[0].y + dlg[obj].y - 2, dlg[obj].w + 4, dlg[obj].h + 4); retbutton = obj; } } break; case SDL_MOUSEMOTION: break; case SDL_KEYDOWN: /* Key pressed */ break; } } else { SDL_Delay(1); } } if (retbutton == SDLGUI_QUIT) my_shutdown = TRUE; return retbutton; } 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++; } if (debug) 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; } #endif