Annotation of hatari/src/gui-sdl/sdlgui.c, revision 1.1.1.4

1.1       root        1: /*
                      2:   Hatari - sdlgui.c
                      3: 
                      4:   This file is distributed under the GNU Public License, version 2 or at
                      5:   your option any later version. Read the file gpl.txt for details.
                      6: 
                      7:   A tiny graphical user interface for Hatari.
                      8: */
1.1.1.4 ! root        9: const char SDLGui_rcsid[] = "Hatari $Id: sdlgui.c,v 1.13 2006/02/09 21:55:44 eerot Exp $";
1.1       root       10: 
                     11: #include <SDL.h>
                     12: #include <ctype.h>
                     13: #include <string.h>
                     14: 
                     15: #include "main.h"
                     16: #include "sdlgui.h"
                     17: 
                     18: #include "font5x8.h"
                     19: #include "font10x16.h"
                     20: 
                     21: 
1.1.1.2   root       22: static SDL_Surface *pSdlGuiScrn;            /* Pointer to the actual main SDL screen surface */
1.1       root       23: static SDL_Surface *pSmallFontGfx = NULL;   /* The small font graphics */
                     24: static SDL_Surface *pBigFontGfx = NULL;     /* The big font graphics */
1.1.1.2   root       25: static SDL_Surface *pFontGfx = NULL;        /* The actual font graphics */
1.1       root       26: static int fontwidth, fontheight;           /* Width & height of the actual font */
                     27: 
                     28: 
                     29: 
                     30: /*-----------------------------------------------------------------------*/
                     31: /*
                     32:   Load an 1 plane XBM into a 8 planes SDL_Surface.
                     33: */
1.1.1.4 ! root       34: static SDL_Surface *SDLGui_LoadXBM(int w, int h, const Uint8 *pXbmBits)
1.1       root       35: {
                     36:   SDL_Surface *bitmap;
1.1.1.4 ! root       37:   Uint8 *dstbits;
        !            38:   const Uint8 *srcbits;
1.1       root       39:   int x, y, srcpitch;
                     40:   int mask;
                     41: 
1.1.1.3   root       42:   srcbits = pXbmBits;
                     43: 
1.1       root       44:   /* Allocate the bitmap */
                     45:   bitmap = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 8, 0, 0, 0, 0);
                     46:   if (bitmap == NULL)
                     47:   {
                     48:     fprintf(stderr, "Couldn't allocate bitmap: %s", SDL_GetError());
                     49:     return(NULL);
                     50:   }
                     51: 
                     52:   srcpitch = ((w + 7) / 8);
                     53:   dstbits = (Uint8 *)bitmap->pixels;
                     54:   mask = 1;
                     55: 
                     56:   /* Copy the pixels */
                     57:   for (y = 0 ; y < h ; y++)
                     58:   {
                     59:     for (x = 0 ; x < w ; x++)
                     60:     {
                     61:       dstbits[x] = (srcbits[x / 8] & mask) ? 1 : 0;
                     62:       mask <<= 1;
                     63:       mask |= (mask >> 8);
                     64:       mask &= 0xFF;
                     65:     }
                     66:     dstbits += bitmap->pitch;
                     67:     srcbits += srcpitch;
                     68:   }
                     69: 
                     70:   return(bitmap);
                     71: }
                     72: 
                     73: 
                     74: /*-----------------------------------------------------------------------*/
                     75: /*
                     76:   Initialize the GUI.
                     77: */
                     78: int SDLGui_Init(void)
                     79: {
                     80:   SDL_Color blackWhiteColors[2] = {{255, 255, 255, 0}, {0, 0, 0, 0}};
                     81: 
                     82:   /* Initialize the font graphics: */
                     83:   pSmallFontGfx = SDLGui_LoadXBM(font5x8_width, font5x8_height, font5x8_bits);
                     84:   pBigFontGfx = SDLGui_LoadXBM(font10x16_width, font10x16_height, font10x16_bits);
                     85:   if (pSmallFontGfx == NULL || pBigFontGfx == NULL)
                     86:   {
                     87:     fprintf(stderr, "Error: Can not init font graphics!\n");
                     88:     return -1;
                     89:   }
                     90: 
                     91:   /* Set color palette of the font graphics: */
                     92:   SDL_SetColors(pSmallFontGfx, blackWhiteColors, 0, 2);
                     93:   SDL_SetColors(pBigFontGfx, blackWhiteColors, 0, 2);
                     94: 
                     95:   /* Set font color 0 as transparent: */
                     96:   SDL_SetColorKey(pSmallFontGfx, (SDL_SRCCOLORKEY|SDL_RLEACCEL), 0);
                     97:   SDL_SetColorKey(pBigFontGfx, (SDL_SRCCOLORKEY|SDL_RLEACCEL), 0);
                     98: 
                     99:   return 0;
                    100: }
                    101: 
                    102: 
                    103: /*-----------------------------------------------------------------------*/
                    104: /*
                    105:   Uninitialize the GUI.
                    106: */
                    107: int SDLGui_UnInit(void)
                    108: {
                    109:   if (pSmallFontGfx)
                    110:   {
                    111:     SDL_FreeSurface(pSmallFontGfx);
                    112:     pSmallFontGfx = NULL;
                    113:   }
                    114: 
                    115:   if (pBigFontGfx)
                    116:   {
                    117:     SDL_FreeSurface(pBigFontGfx);
                    118:     pBigFontGfx = NULL;
                    119:   }
                    120: 
                    121:   return 0;
                    122: }
                    123: 
                    124: 
                    125: /*-----------------------------------------------------------------------*/
                    126: /*
1.1.1.2   root      127:   Inform the SDL-GUI about the actual SDL_Surface screen pointer and
                    128:   prepare the font to suit the actual resolution.
1.1       root      129: */
1.1.1.2   root      130: int SDLGui_SetScreen(SDL_Surface *pScrn)
1.1       root      131: {
1.1.1.2   root      132:   pSdlGuiScrn = pScrn;
                    133: 
1.1       root      134:   /* Decide which font to use - small or big one: */
1.1.1.2   root      135:   if (pSdlGuiScrn->w >= 640 && pSdlGuiScrn->h >= 400 && pBigFontGfx != NULL)
1.1       root      136:   {
1.1.1.2   root      137:     pFontGfx = pBigFontGfx;
1.1       root      138:   }
                    139:   else
                    140:   {
1.1.1.2   root      141:     pFontGfx = pSmallFontGfx;
1.1       root      142:   }
                    143: 
1.1.1.2   root      144:   if (pFontGfx == NULL)
1.1       root      145:   {
                    146:     fprintf(stderr, "Error: A problem with the font occured!\n");
                    147:     return -1;
                    148:   }
                    149: 
                    150:   /* Get the font width and height: */
1.1.1.2   root      151:   fontwidth = pFontGfx->w/16;
                    152:   fontheight = pFontGfx->h/16;
1.1       root      153: 
                    154:   return 0;
                    155: }
                    156: 
                    157: 
                    158: /*-----------------------------------------------------------------------*/
                    159: /*
                    160:   Center a dialog so that it appears in the middle of the screen.
                    161:   Note: We only store the coordinates in the root box of the dialog,
                    162:   all other objects in the dialog are positioned relatively to this one.
                    163: */
                    164: void SDLGui_CenterDlg(SGOBJ *dlg)
                    165: {
1.1.1.2   root      166:   dlg[0].x = (pSdlGuiScrn->w/fontwidth-dlg[0].w)/2;
                    167:   dlg[0].y = (pSdlGuiScrn->h/fontheight-dlg[0].h)/2;
1.1       root      168: }
                    169: 
                    170: 
                    171: /*-----------------------------------------------------------------------*/
                    172: /*
                    173:   Draw a text string.
                    174: */
                    175: static void SDLGui_Text(int x, int y, const char *txt)
                    176: {
                    177:   int i;
                    178:   char c;
                    179:   SDL_Rect sr, dr;
                    180: 
                    181:   for(i=0; txt[i]!=0; i++)
                    182:   {
                    183:     c = txt[i];
                    184:     sr.x=fontwidth*(c%16);  sr.y=fontheight*(c/16);
                    185:     sr.w=fontwidth;         sr.h=fontheight;
                    186:     dr.x=x+i*fontwidth;     dr.y=y;
                    187:     dr.w=fontwidth;         dr.h=fontheight;
1.1.1.2   root      188:     SDL_BlitSurface(pFontGfx, &sr, pSdlGuiScrn, &dr);
1.1       root      189:   }
                    190: }
                    191: 
                    192: 
                    193: /*-----------------------------------------------------------------------*/
                    194: /*
                    195:   Draw a dialog text object.
                    196: */
1.1.1.2   root      197: static void SDLGui_DrawText(const SGOBJ *tdlg, int objnum)
1.1       root      198: {
                    199:   int x, y;
                    200:   x = (tdlg[0].x+tdlg[objnum].x)*fontwidth;
                    201:   y = (tdlg[0].y+tdlg[objnum].y)*fontheight;
                    202:   SDLGui_Text(x, y, tdlg[objnum].txt);
                    203: }
                    204: 
                    205: 
                    206: /*-----------------------------------------------------------------------*/
                    207: /*
                    208:   Draw a edit field object.
                    209: */
1.1.1.2   root      210: static void SDLGui_DrawEditField(const SGOBJ *edlg, int objnum)
1.1       root      211: {
                    212:   int x, y;
                    213:   SDL_Rect rect;
                    214: 
                    215:   x = (edlg[0].x+edlg[objnum].x)*fontwidth;
                    216:   y = (edlg[0].y+edlg[objnum].y)*fontheight;
                    217:   SDLGui_Text(x, y, edlg[objnum].txt);
                    218: 
                    219:   rect.x = x;    rect.y = y + edlg[objnum].h * fontheight;
                    220:   rect.w = edlg[objnum].w * fontwidth;    rect.h = 1;
1.1.1.2   root      221:   SDL_FillRect(pSdlGuiScrn, &rect, SDL_MapRGB(pSdlGuiScrn->format,160,160,160));
1.1       root      222: }
                    223: 
                    224: 
                    225: /*-----------------------------------------------------------------------*/
                    226: /*
                    227:   Draw a dialog box object.
                    228: */
1.1.1.2   root      229: static void SDLGui_DrawBox(const SGOBJ *bdlg, int objnum)
1.1       root      230: {
                    231:   SDL_Rect rect;
                    232:   int x, y, w, h, offset;
1.1.1.2   root      233:   Uint32 grey = SDL_MapRGB(pSdlGuiScrn->format,192,192,192);
1.1       root      234:   Uint32 upleftc, downrightc;
                    235: 
                    236:   x = bdlg[objnum].x*fontwidth;
                    237:   y = bdlg[objnum].y*fontheight;
                    238:   if(objnum>0)                    /* Since the root object is a box, too, */
                    239:   {                               /* we have to look for it now here and only */
                    240:     x += bdlg[0].x*fontwidth;     /* add its absolute coordinates if we need to */
                    241:     y += bdlg[0].y*fontheight;
                    242:   }
                    243:   w = bdlg[objnum].w*fontwidth;
                    244:   h = bdlg[objnum].h*fontheight;
                    245: 
                    246:   if( bdlg[objnum].state&SG_SELECTED )
                    247:   {
1.1.1.2   root      248:     upleftc = SDL_MapRGB(pSdlGuiScrn->format,128,128,128);
                    249:     downrightc = SDL_MapRGB(pSdlGuiScrn->format,255,255,255);
1.1       root      250:   }
                    251:   else
                    252:   {
1.1.1.2   root      253:     upleftc = SDL_MapRGB(pSdlGuiScrn->format,255,255,255);
                    254:     downrightc = SDL_MapRGB(pSdlGuiScrn->format,128,128,128);
1.1       root      255:   }
                    256: 
                    257:   /* The root box should be bigger than the screen, so we disable the offset there: */
                    258:   if (objnum != 0)
                    259:     offset = 1;
                    260:   else
                    261:     offset = 0;
                    262: 
                    263:   /* Draw background: */
                    264:   rect.x = x;  rect.y = y;
                    265:   rect.w = w;  rect.h = h;
1.1.1.2   root      266:   SDL_FillRect(pSdlGuiScrn, &rect, grey);
1.1       root      267: 
                    268:   /* Draw upper border: */
                    269:   rect.x = x;  rect.y = y - offset;
                    270:   rect.w = w;  rect.h = 1;
1.1.1.2   root      271:   SDL_FillRect(pSdlGuiScrn, &rect, upleftc);
1.1       root      272: 
                    273:   /* Draw left border: */
                    274:   rect.x = x - offset;  rect.y = y;
                    275:   rect.w = 1;  rect.h = h;
1.1.1.2   root      276:   SDL_FillRect(pSdlGuiScrn, &rect, upleftc);
1.1       root      277: 
                    278:   /* Draw bottom border: */
                    279:   rect.x = x;  rect.y = y + h - 1 + offset;
                    280:   rect.w = w;  rect.h = 1;
1.1.1.2   root      281:   SDL_FillRect(pSdlGuiScrn, &rect, downrightc);
1.1       root      282: 
                    283:   /* Draw right border: */
                    284:   rect.x = x + w - 1 + offset;  rect.y = y;
                    285:   rect.w = 1;  rect.h = h;
1.1.1.2   root      286:   SDL_FillRect(pSdlGuiScrn, &rect, downrightc);
1.1       root      287: }
                    288: 
                    289: 
                    290: /*-----------------------------------------------------------------------*/
                    291: /*
                    292:   Draw a normal button.
                    293: */
1.1.1.2   root      294: static void SDLGui_DrawButton(const SGOBJ *bdlg, int objnum)
1.1       root      295: {
                    296:   int x,y;
                    297: 
                    298:   SDLGui_DrawBox(bdlg, objnum);
                    299: 
                    300:   x = (bdlg[0].x+bdlg[objnum].x+(bdlg[objnum].w-strlen(bdlg[objnum].txt))/2)*fontwidth;
                    301:   y = (bdlg[0].y+bdlg[objnum].y+(bdlg[objnum].h-1)/2)*fontheight;
                    302: 
                    303:   if( bdlg[objnum].state&SG_SELECTED )
                    304:   {
                    305:     x+=1;
                    306:     y+=1;
                    307:   }
                    308:   SDLGui_Text(x, y, bdlg[objnum].txt);
                    309: }
                    310: 
                    311: 
                    312: /*-----------------------------------------------------------------------*/
                    313: /*
                    314:   Draw a dialog radio button object.
                    315: */
1.1.1.2   root      316: static void SDLGui_DrawRadioButton(const SGOBJ *rdlg, int objnum)
1.1       root      317: {
                    318:   char str[80];
                    319:   int x, y;
                    320: 
                    321:   x = (rdlg[0].x+rdlg[objnum].x)*fontwidth;
                    322:   y = (rdlg[0].y+rdlg[objnum].y)*fontheight;
                    323: 
                    324:   if( rdlg[objnum].state&SG_SELECTED )
                    325:     str[0]=SGRADIOBUTTON_SELECTED;
                    326:    else
                    327:     str[0]=SGRADIOBUTTON_NORMAL;
                    328:   str[1]=' ';
                    329:   strcpy(&str[2], rdlg[objnum].txt);
                    330: 
                    331:   SDLGui_Text(x, y, str);
                    332: }
                    333: 
                    334: 
                    335: /*-----------------------------------------------------------------------*/
                    336: /*
                    337:   Draw a dialog check box object.
                    338: */
1.1.1.2   root      339: static void SDLGui_DrawCheckBox(const SGOBJ *cdlg, int objnum)
1.1       root      340: {
                    341:   char str[80];
                    342:   int x, y;
                    343: 
                    344:   x = (cdlg[0].x+cdlg[objnum].x)*fontwidth;
                    345:   y = (cdlg[0].y+cdlg[objnum].y)*fontheight;
                    346: 
                    347:   if( cdlg[objnum].state&SG_SELECTED )
                    348:     str[0]=SGCHECKBOX_SELECTED;
                    349:    else
                    350:     str[0]=SGCHECKBOX_NORMAL;
                    351:   str[1]=' ';
                    352:   strcpy(&str[2], cdlg[objnum].txt);
                    353: 
                    354:   SDLGui_Text(x, y, str);
                    355: }
                    356: 
                    357: 
                    358: /*-----------------------------------------------------------------------*/
                    359: /*
                    360:   Draw a dialog popup button object.
                    361: */
1.1.1.2   root      362: static void SDLGui_DrawPopupButton(const SGOBJ *pdlg, int objnum)
1.1       root      363: {
                    364:   int x, y, w, h;
                    365:   const char *downstr = "\x02";
                    366: 
                    367:   SDLGui_DrawBox(pdlg, objnum);
                    368: 
                    369:   x = (pdlg[0].x+pdlg[objnum].x)*fontwidth;
                    370:   y = (pdlg[0].y+pdlg[objnum].y)*fontheight;
                    371:   w = pdlg[objnum].w*fontwidth;
                    372:   h = pdlg[objnum].h*fontheight;
                    373: 
                    374:   SDLGui_Text(x, y, pdlg[objnum].txt);
                    375:   SDLGui_Text(x+w-fontwidth, y, downstr);
                    376: }
                    377: 
                    378: 
                    379: /*-----------------------------------------------------------------------*/
                    380: /*
                    381:   Let the user insert text into an edit field object.
                    382:   NOTE: The dlg[objnum].txt must point to an an array that is big enough
                    383:   for dlg[objnum].w characters!
                    384: */
                    385: static void SDLGui_EditField(SGOBJ *dlg, int objnum)
                    386: {
1.1.1.2   root      387:   size_t cursorPos;                     /* Position of the cursor in the edit field */
1.1       root      388:   int blinkState = 0;                   /* Used for cursor blinking */
1.1.1.2   root      389:   int bStopEditing = FALSE;             /* TRUE if user wants to exit the edit field */
1.1       root      390:   char *txt;                            /* Shortcut for dlg[objnum].txt */
                    391:   SDL_Rect rect;
                    392:   Uint32 grey, cursorCol;
                    393:   SDL_Event event;
                    394: 
1.1.1.2   root      395:   grey = SDL_MapRGB(pSdlGuiScrn->format,192,192,192);
                    396:   cursorCol = SDL_MapRGB(pSdlGuiScrn->format,128,128,128);
1.1       root      397: 
                    398:   rect.x = (dlg[0].x + dlg[objnum].x) * fontwidth;
                    399:   rect.y = (dlg[0].y + dlg[objnum].y) * fontheight;
                    400:   rect.w = (dlg[objnum].w + 1) * fontwidth - 1;
                    401:   rect.h = dlg[objnum].h * fontheight;
                    402: 
                    403:   txt = dlg[objnum].txt;
                    404:   cursorPos = strlen(txt);
                    405: 
                    406:   do
                    407:   {
                    408:     /* Look for events */
                    409:     if(SDL_PollEvent(&event) == 0)
                    410:     {
                    411:       /* No event: Wait some time for cursor blinking */
                    412:       SDL_Delay(250);
                    413:       blinkState ^= 1;
                    414:     }
                    415:     else
                    416:     {
                    417:       int keysym;
                    418: 
                    419:       /* Handle events */
                    420:       do
                    421:       {
                    422:         switch(event.type)
                    423:         {
                    424:           case SDL_QUIT:                        /* User wants to quit */
                    425:             bQuitProgram = TRUE;
                    426:             bStopEditing = TRUE;
                    427:             break;
                    428:           case SDL_MOUSEBUTTONDOWN:             /* Mouse pressed -> stop editing */
                    429:             bStopEditing = TRUE;
                    430:             break;
                    431:           case SDL_KEYDOWN:                     /* Key pressed */
                    432:             keysym = event.key.keysym.sym;
                    433:             switch(keysym)
                    434:             {
                    435:               case SDLK_RETURN:
                    436:               case SDLK_KP_ENTER:
                    437:                 bStopEditing = TRUE;
                    438:                 break;
                    439:               case SDLK_LEFT:
                    440:                 if(cursorPos > 0)
                    441:                   cursorPos -= 1;
                    442:                 break;
                    443:               case SDLK_RIGHT:
                    444:                 if(cursorPos < strlen(txt))
                    445:                   cursorPos += 1;
                    446:                 break;
                    447:               case SDLK_BACKSPACE:
                    448:                 if(cursorPos > 0)
                    449:                 {
                    450:                   memmove(&txt[cursorPos-1], &txt[cursorPos], strlen(&txt[cursorPos])+1);
                    451:                   cursorPos -= 1;
                    452:                 }
                    453:                 break;
                    454:               case SDLK_DELETE:
                    455:                 if(cursorPos < strlen(txt))
                    456:                   memmove(&txt[cursorPos], &txt[cursorPos+1], strlen(&txt[cursorPos+1])+1);
                    457:                 break;
                    458:               default:
                    459:                 /* If it is a "good" key then insert it into the text field */
                    460:                 if(keysym >= 32 && keysym < 256)
                    461:                 {
1.1.1.2   root      462:                   if(strlen(txt) < (size_t)dlg[objnum].w)
1.1       root      463:                   {
                    464:                     memmove(&txt[cursorPos+1], &txt[cursorPos], strlen(&txt[cursorPos])+1);
                    465:                     if(event.key.keysym.mod & (KMOD_LSHIFT|KMOD_RSHIFT))
                    466:                       txt[cursorPos] = toupper(keysym);
                    467:                     else
                    468:                       txt[cursorPos] = keysym;
                    469:                     cursorPos += 1;
                    470:                   }
                    471:                 }
                    472:                 break;
                    473:             }
                    474:             break;
                    475:         }
                    476:       }
                    477:       while(SDL_PollEvent(&event));
                    478: 
                    479:       blinkState = 1;
                    480:     }
                    481: 
                    482:     /* Redraw the text field: */
1.1.1.2   root      483:     SDL_FillRect(pSdlGuiScrn, &rect, grey);  /* Draw background */
1.1       root      484:     /* Draw the cursor: */
                    485:     if(blinkState && !bStopEditing)
                    486:     {
                    487:       SDL_Rect cursorrect;
                    488:       cursorrect.x = rect.x + cursorPos * fontwidth;  cursorrect.y = rect.y;
                    489:       cursorrect.w = fontwidth;  cursorrect.h = rect.h;
1.1.1.2   root      490:       SDL_FillRect(pSdlGuiScrn, &cursorrect, cursorCol);
1.1       root      491:     }
                    492:     SDLGui_Text(rect.x, rect.y, dlg[objnum].txt);  /* Draw text */
1.1.1.2   root      493:     SDL_UpdateRects(pSdlGuiScrn, 1, &rect);
1.1       root      494:   }
                    495:   while(!bStopEditing);
                    496: }
                    497: 
                    498: 
                    499: /*-----------------------------------------------------------------------*/
                    500: /*
                    501:   Draw a whole dialog.
                    502: */
1.1.1.3   root      503: void SDLGui_DrawDialog(const SGOBJ *dlg)
1.1       root      504: {
                    505:   int i;
                    506:   for(i=0; dlg[i].type!=-1; i++ )
                    507:   {
                    508:     switch( dlg[i].type )
                    509:     {
                    510:       case SGBOX:
                    511:         SDLGui_DrawBox(dlg, i);
                    512:         break;
                    513:       case SGTEXT:
                    514:         SDLGui_DrawText(dlg, i);
                    515:         break;
                    516:       case SGEDITFIELD:
                    517:         SDLGui_DrawEditField(dlg, i);
                    518:         break;
                    519:       case SGBUTTON:
                    520:         SDLGui_DrawButton(dlg, i);
                    521:         break;
                    522:       case SGRADIOBUT:
                    523:         SDLGui_DrawRadioButton(dlg, i);
                    524:         break;
                    525:       case SGCHECKBOX:
                    526:         SDLGui_DrawCheckBox(dlg, i);
                    527:         break;
                    528:       case SGPOPUP:
                    529:         SDLGui_DrawPopupButton(dlg, i);
                    530:         break;
                    531:     }
                    532:   }
1.1.1.2   root      533:   SDL_UpdateRect(pSdlGuiScrn, 0,0,0,0);
1.1       root      534: }
                    535: 
                    536: 
                    537: /*-----------------------------------------------------------------------*/
                    538: /*
                    539:   Search an object at a certain position.
                    540: */
1.1.1.2   root      541: static int SDLGui_FindObj(const SGOBJ *dlg, int fx, int fy)
1.1       root      542: {
                    543:   int len, i;
                    544:   int ob = -1;
                    545:   int xpos, ypos;
                    546: 
                    547:   len = 0;
                    548:   while( dlg[len].type!=-1)   len++;
                    549: 
                    550:   xpos = fx/fontwidth;
                    551:   ypos = fy/fontheight;
                    552:   /* Now search for the object: */
1.1.1.2   root      553:   for (i = len; i >= 0; i--)
1.1       root      554:   {
                    555:     if(xpos>=dlg[0].x+dlg[i].x && ypos>=dlg[0].y+dlg[i].y
                    556:        && xpos<dlg[0].x+dlg[i].x+dlg[i].w && ypos<dlg[0].y+dlg[i].y+dlg[i].h)
                    557:     {
                    558:       ob = i;
                    559:       break;
                    560:     }
                    561:   }
                    562: 
                    563:   return ob;
                    564: }
                    565: 
                    566: 
                    567: /*-----------------------------------------------------------------------*/
                    568: /*
                    569:   Show and process a dialog. Returns the button number that has been
1.1.1.2   root      570:   pressed or SDLGUI_UNKNOWNEVENT if an unsupported event occured (will be
                    571:   stored in parameter pEventOut).
1.1       root      572: */
1.1.1.2   root      573: int SDLGui_DoDialog(SGOBJ *dlg, SDL_Event *pEventOut)
1.1       root      574: {
                    575:   int obj=0;
                    576:   int oldbutton=0;
                    577:   int retbutton=0;
                    578:   int i, j, b;
1.1.1.2   root      579:   SDL_Event sdlEvent;
1.1       root      580:   SDL_Rect rct;
                    581:   Uint32 grey;
                    582:   SDL_Surface *pBgSurface;
                    583:   SDL_Rect dlgrect, bgrect;
                    584:   
1.1.1.2   root      585:   grey = SDL_MapRGB(pSdlGuiScrn->format,192,192,192);
1.1       root      586: 
                    587:   dlgrect.x = dlg[0].x * fontwidth;
                    588:   dlgrect.y = dlg[0].y * fontheight;
                    589:   dlgrect.w = dlg[0].w * fontwidth;
                    590:   dlgrect.h = dlg[0].h * fontheight;
                    591: 
                    592:   bgrect.x = bgrect.y = 0;
                    593:   bgrect.w = dlgrect.w;
                    594:   bgrect.h = dlgrect.h;
                    595: 
                    596:   /* Save background */
1.1.1.2   root      597:   pBgSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, dlgrect.w, dlgrect.h, pSdlGuiScrn->format->BitsPerPixel,
                    598:                    pSdlGuiScrn->format->Rmask, pSdlGuiScrn->format->Gmask, pSdlGuiScrn->format->Bmask, pSdlGuiScrn->format->Amask);
                    599:   if (pSdlGuiScrn->format->palette != NULL)
1.1       root      600:   {
1.1.1.2   root      601:     SDL_SetColors(pBgSurface, pSdlGuiScrn->format->palette->colors, 0, pSdlGuiScrn->format->palette->ncolors-1);
1.1       root      602:   }
                    603: 
                    604:   if (pBgSurface != NULL)
                    605:   {
1.1.1.2   root      606:     SDL_BlitSurface(pSdlGuiScrn,  &dlgrect, pBgSurface, &bgrect);
1.1       root      607:   }
                    608:   else
                    609:   {
                    610:     fprintf(stderr, "SDLGUI_DoDialog: CreateRGBSurface failed: %s\n", SDL_GetError());
                    611:   }
                    612: 
                    613:   /* (Re-)draw the dialog */
                    614:   SDLGui_DrawDialog(dlg);
                    615: 
                    616:   /* Is the left mouse button still pressed? Yes -> Handle TOUCHEXIT objects here */
                    617:   SDL_PumpEvents();
                    618:   b = SDL_GetMouseState(&i, &j);
                    619:   obj = SDLGui_FindObj(dlg, i, j);
                    620:   if(obj>0 && (dlg[obj].flags&SG_TOUCHEXIT) )
                    621:   {
                    622:     oldbutton = obj;
                    623:     if( b&SDL_BUTTON(1) )
                    624:     {
                    625:       dlg[obj].state |= SG_SELECTED;
                    626:       retbutton = obj;
                    627:     }
                    628:   }
                    629: 
                    630:   /* The main loop */
1.1.1.2   root      631:   while (retbutton == 0 && !bQuitProgram)
1.1       root      632:   {
1.1.1.2   root      633:     if (SDL_WaitEvent(&sdlEvent) == 1)  /* Wait for events */
                    634:       switch (sdlEvent.type)
1.1       root      635:       {
                    636:         case SDL_QUIT:
1.1.1.2   root      637:           retbutton = SDLGUI_QUIT;
1.1       root      638:           break;
1.1.1.2   root      639: 
1.1       root      640:         case SDL_MOUSEBUTTONDOWN:
1.1.1.2   root      641:           if (sdlEvent.button.button != SDL_BUTTON_LEFT)
                    642:           {
                    643:             /* Not left mouse button -> unsupported event */
                    644:             if (pEventOut)
                    645:               retbutton = SDLGUI_UNKNOWNEVENT;
                    646:             break;
                    647:           }
                    648:           /* It was the left button: Find the object under the mouse cursor */
                    649:           obj = SDLGui_FindObj(dlg, sdlEvent.button.x, sdlEvent.button.y);
1.1       root      650:           if(obj>0)
                    651:           {
                    652:             if(dlg[obj].type==SGBUTTON)
                    653:             {
                    654:               dlg[obj].state |= SG_SELECTED;
                    655:               SDLGui_DrawButton(dlg, obj);
1.1.1.2   root      656:               SDL_UpdateRect(pSdlGuiScrn, (dlg[0].x+dlg[obj].x)*fontwidth-2, (dlg[0].y+dlg[obj].y)*fontheight-2,
1.1       root      657:                              dlg[obj].w*fontwidth+4, dlg[obj].h*fontheight+4);
                    658:               oldbutton=obj;
                    659:             }
                    660:             if( dlg[obj].flags&SG_TOUCHEXIT )
                    661:             {
                    662:               dlg[obj].state |= SG_SELECTED;
                    663:               retbutton = obj;
                    664:             }
                    665:           }
                    666:           break;
1.1.1.2   root      667: 
1.1       root      668:         case SDL_MOUSEBUTTONUP:
1.1.1.2   root      669:           if (sdlEvent.button.button != SDL_BUTTON_LEFT)
                    670:           {
                    671:             /* Not left mouse button -> unsupported event */
                    672:             if (pEventOut)
                    673:               retbutton = SDLGUI_UNKNOWNEVENT;
                    674:             break;
                    675:           }
                    676:           /* It was the left button: Find the object under the mouse cursor */
                    677:           obj = SDLGui_FindObj(dlg, sdlEvent.button.x, sdlEvent.button.y);
1.1       root      678:           if(obj>0)
                    679:           {
                    680:             switch(dlg[obj].type)
                    681:             {
                    682:               case SGBUTTON:
                    683:                 if(oldbutton==obj)
                    684:                   retbutton=obj;
                    685:                 break;
                    686:               case SGEDITFIELD:
                    687:                 SDLGui_EditField(dlg, obj);
                    688:                 break;
                    689:               case SGRADIOBUT:
                    690:                 for(i=obj-1; i>0 && dlg[i].type==SGRADIOBUT; i--)
                    691:                 {
                    692:                   dlg[i].state &= ~SG_SELECTED;  /* Deselect all radio buttons in this group */
                    693:                   rct.x = (dlg[0].x+dlg[i].x)*fontwidth;
                    694:                   rct.y = (dlg[0].y+dlg[i].y)*fontheight;
                    695:                   rct.w = fontwidth;  rct.h = fontheight;
1.1.1.2   root      696:                   SDL_FillRect(pSdlGuiScrn, &rct, grey); /* Clear old */
1.1       root      697:                   SDLGui_DrawRadioButton(dlg, i);
1.1.1.2   root      698:                   SDL_UpdateRects(pSdlGuiScrn, 1, &rct);
1.1       root      699:                 }
                    700:                 for(i=obj+1; dlg[i].type==SGRADIOBUT; i++)
                    701:                 {
                    702:                   dlg[i].state &= ~SG_SELECTED;  /* Deselect all radio buttons in this group */
                    703:                   rct.x = (dlg[0].x+dlg[i].x)*fontwidth;
                    704:                   rct.y = (dlg[0].y+dlg[i].y)*fontheight;
                    705:                   rct.w = fontwidth;  rct.h = fontheight;
1.1.1.2   root      706:                   SDL_FillRect(pSdlGuiScrn, &rct, grey); /* Clear old */
1.1       root      707:                   SDLGui_DrawRadioButton(dlg, i);
1.1.1.2   root      708:                   SDL_UpdateRects(pSdlGuiScrn, 1, &rct);
1.1       root      709:                 }
                    710:                 dlg[obj].state |= SG_SELECTED;  /* Select this radio button */
                    711:                 rct.x = (dlg[0].x+dlg[obj].x)*fontwidth;
                    712:                 rct.y = (dlg[0].y+dlg[obj].y)*fontheight;
                    713:                 rct.w = fontwidth;  rct.h = fontheight;
1.1.1.2   root      714:                 SDL_FillRect(pSdlGuiScrn, &rct, grey); /* Clear old */
1.1       root      715:                 SDLGui_DrawRadioButton(dlg, obj);
1.1.1.2   root      716:                 SDL_UpdateRects(pSdlGuiScrn, 1, &rct);
1.1       root      717:                 break;
                    718:               case SGCHECKBOX:
                    719:                 dlg[obj].state ^= SG_SELECTED;
                    720:                 rct.x = (dlg[0].x+dlg[obj].x)*fontwidth;
                    721:                 rct.y = (dlg[0].y+dlg[obj].y)*fontheight;
                    722:                 rct.w = fontwidth;  rct.h = fontheight;
1.1.1.2   root      723:                 SDL_FillRect(pSdlGuiScrn, &rct, grey); /* Clear old */
1.1       root      724:                 SDLGui_DrawCheckBox(dlg, obj);
1.1.1.2   root      725:                 SDL_UpdateRects(pSdlGuiScrn, 1, &rct);
1.1       root      726:                 break;
                    727:               case SGPOPUP:
                    728:                 dlg[obj].state |= SG_SELECTED;
                    729:                 SDLGui_DrawPopupButton(dlg, obj);
1.1.1.2   root      730:                 SDL_UpdateRect(pSdlGuiScrn, (dlg[0].x+dlg[obj].x)*fontwidth-2, (dlg[0].y+dlg[obj].y)*fontheight-2,
1.1       root      731:                            dlg[obj].w*fontwidth+4, dlg[obj].h*fontheight+4);
                    732:                 retbutton=obj;
                    733:                 break;
                    734:             }
                    735:           }
                    736:           if(oldbutton>0)
                    737:           {
                    738:             dlg[oldbutton].state &= ~SG_SELECTED;
                    739:             SDLGui_DrawButton(dlg, oldbutton);
1.1.1.2   root      740:             SDL_UpdateRect(pSdlGuiScrn, (dlg[0].x+dlg[oldbutton].x)*fontwidth-2, (dlg[0].y+dlg[oldbutton].y)*fontheight-2,
1.1       root      741:                            dlg[oldbutton].w*fontwidth+4, dlg[oldbutton].h*fontheight+4);
                    742:             oldbutton = 0;
                    743:           }
1.1.1.2   root      744:           if (obj >= 0 && (dlg[obj].flags&SG_EXIT))
1.1       root      745:           {
                    746:             retbutton = obj;
                    747:           }
                    748:           break;
1.1.1.2   root      749: 
                    750:         case SDL_MOUSEMOTION:
                    751:           break;
                    752: 
                    753:         default:
                    754:           if (pEventOut)
                    755:             retbutton = SDLGUI_UNKNOWNEVENT;
                    756:           break;
1.1       root      757:       }
                    758:   }
                    759: 
                    760:   /* Restore background */
                    761:   if (pBgSurface)
                    762:   {
1.1.1.2   root      763:     SDL_BlitSurface(pBgSurface, &bgrect, pSdlGuiScrn,  &dlgrect);
1.1       root      764:     SDL_FreeSurface(pBgSurface);
                    765:   }
                    766: 
1.1.1.2   root      767:   /* Copy event data of unsupported events if caller wants to have it */
                    768:   if (retbutton == SDLGUI_UNKNOWNEVENT && pEventOut)
                    769:     memcpy(pEventOut, &sdlEvent, sizeof(SDL_Event));
                    770: 
                    771:   if (retbutton == SDLGUI_QUIT)
                    772:     bQuitProgram = TRUE;
1.1       root      773: 
                    774:   return retbutton;
                    775: }
                    776: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.