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

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

unix.superglobalmegacorp.com

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