Annotation of frontvm/hardware/sdlgui.c, revision 1.1.1.1

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: */
                      9: 
                     10: #include <SDL.h>
                     11: #include <sys/stat.h>
                     12: #include <unistd.h>
                     13: #include <dirent.h>
                     14: 
                     15: #include "main.h"
                     16: #include "memAlloc.h"
                     17: #include "screen.h"
                     18: #include "sdlgui.h"
                     19: #include "file.h"
                     20: 
                     21: #define SGRADIOBUTTON_NORMAL    12
                     22: #define SGRADIOBUTTON_SELECTED  13
                     23: #define SGCHECKBOX_NORMAL    14
                     24: #define SGCHECKBOX_SELECTED  15
                     25: #define SGARROWUP    1
                     26: #define SGARROWDOWN  2
                     27: #define SGFOLDER     5
                     28: 
                     29: 
                     30: 
                     31: static SDL_Surface *stdfontgfx = NULL;  /* The 'standard' font graphics */
                     32: static SDL_Surface *fontgfx = NULL;     /* The actual font graphics */
                     33: static int fontwidth, fontheight;       /* Height and width of the actual font */
                     34: 
                     35: 
                     36: 
                     37: /*-----------------------------------------------------------------------*/
                     38: /*
                     39:   Initialize the GUI.
                     40: */
                     41: int SDLGui_Init()
                     42: {
                     43:   const char *fontname = "font8.bmp";
                     44: 
                     45:   /* Load the font graphics: */
                     46:   stdfontgfx = SDL_LoadBMP(fontname);
                     47:   if( stdfontgfx==NULL )
                     48:   {
                     49:     fprintf(stderr, "Error: Can't load image %s: %s\n", fontname, SDL_GetError() );
                     50:     return -1;
                     51:   }
                     52: 
                     53:   return 0;
                     54: }
                     55: 
                     56: 
                     57: /*-----------------------------------------------------------------------*/
                     58: /*
                     59:   Uninitialize the GUI.
                     60: */
                     61: int SDLGui_UnInit()
                     62: {
                     63:   if(stdfontgfx)
                     64:   {
                     65:     SDL_FreeSurface(stdfontgfx);
                     66:     stdfontgfx = NULL;
                     67:   }
                     68:   if(fontgfx)
                     69:   {
                     70:     SDL_FreeSurface(fontgfx);
                     71:     fontgfx = NULL;
                     72:   }
                     73: 
                     74:   return 0;
                     75: }
                     76: 
                     77: 
                     78: /*-----------------------------------------------------------------------*/
                     79: /*
                     80:   Prepare the font to suit the actual resolution.
                     81: */
                     82: int SDLGui_PrepareFont()
                     83: {
                     84: /* FIXME: Freeing the old font gfx does sometimes crash with a SEGFAULT
                     85:   if(fontgfx)
                     86:   {
                     87:     SDL_FreeSurface(fontgfx);
                     88:     fontgfx = NULL;
                     89:   }
                     90: */
                     91: 
                     92:   if( stdfontgfx==NULL )
                     93:   {
                     94:     fprintf(stderr, "Error: The font has not been loaded!\n");
                     95:     return -1;
                     96:   }
                     97: 
                     98:   /* Convert the font graphics to the actual screen format */
                     99:   fontgfx = SDL_DisplayFormat(stdfontgfx);
                    100:   if( fontgfx==NULL )
                    101:   {
                    102:     fprintf(stderr, "Could not convert font:\n %s\n", SDL_GetError() );
                    103:     return -1;
                    104:   }
                    105:   /* Set transparent pixel */
                    106:   SDL_SetColorKey(fontgfx, (SDL_SRCCOLORKEY|SDL_RLEACCEL), SDL_MapRGB(fontgfx->format,255,255,255));
                    107:   /* Get the font width and height: */
                    108:   fontwidth = fontgfx->w/16;
                    109:   fontheight = fontgfx->h/16;
                    110: 
                    111:   return 0;
                    112: }
                    113: 
                    114: 
                    115: /*-----------------------------------------------------------------------*/
                    116: /*
                    117:   Center a dialog so that it appears in the middle of the screen.
                    118:   Note: We only store the coordinates in the root box of the dialog,
                    119:   all other objects in the dialog are positioned relatively to this one.
                    120: */
                    121: void SDLGui_CenterDlg(SGOBJ *dlg)
                    122: {
                    123:   dlg[0].x = (sdlscrn->w/fontwidth-dlg[0].w)/2;
                    124:   dlg[0].y = (sdlscrn->h/fontheight-dlg[0].h)/2;
                    125: }
                    126: 
                    127: 
                    128: /*-----------------------------------------------------------------------*/
                    129: /*
                    130:   Draw a text string.
                    131: */
                    132: void SDLGui_Text(int x, int y, const char *txt)
                    133: {
                    134:   int i;
                    135:   char c;
                    136:   SDL_Rect sr, dr;
                    137: 
                    138:   for(i=0; txt[i]!=0; i++)
                    139:   {
                    140:     c = txt[i];
                    141:     sr.x=fontwidth*(c%16);  sr.y=fontheight*(c/16);
                    142:     sr.w=fontwidth;         sr.h=fontheight;
                    143:     dr.x=x+i*fontwidth;     dr.y=y;
                    144:     dr.w=fontwidth;         dr.h=fontheight;
                    145:     SDL_BlitSurface(fontgfx, &sr, sdlscrn, &dr);
                    146:   }
                    147: }
                    148: 
                    149: 
                    150: /*-----------------------------------------------------------------------*/
                    151: /*
                    152:   Draw a dialog text object.
                    153: */
                    154: void SDLGui_DrawText(SGOBJ *tdlg, int objnum)
                    155: {
                    156:   int x, y;
                    157:   x = (tdlg[0].x+tdlg[objnum].x)*fontwidth;
                    158:   y = (tdlg[0].y+tdlg[objnum].y)*fontheight;
                    159:   SDLGui_Text(x, y, tdlg[objnum].txt);
                    160: }
                    161: 
                    162: 
                    163: /*-----------------------------------------------------------------------*/
                    164: /*
                    165:   Draw a dialog box object.
                    166: */
                    167: void SDLGui_DrawBox(SGOBJ *bdlg, int objnum)
                    168: {
                    169:   SDL_Rect rect;
                    170:   int x, y, w, h;
                    171:   Uint32 grey = SDL_MapRGB(sdlscrn->format,192,192,192);
                    172:   Uint32 upleftc, downrightc;
                    173: 
                    174:   x = bdlg[objnum].x*fontwidth;
                    175:   y = bdlg[objnum].y*fontheight;
                    176:   if(objnum>0)                    /* Since the root object is a box, too, */
                    177:   {                               /* we have to look for it now here and only */
                    178:     x += bdlg[0].x*fontwidth;     /* add its absolute coordinates if we need to */
                    179:     y += bdlg[0].y*fontheight;
                    180:   }
                    181:   w = bdlg[objnum].w*fontwidth;
                    182:   h = bdlg[objnum].h*fontheight;
                    183: 
                    184:   if( bdlg[objnum].state&SG_SELECTED )
                    185:   {
                    186:     upleftc = SDL_MapRGB(sdlscrn->format,128,128,128);
                    187:     downrightc = SDL_MapRGB(sdlscrn->format,255,255,255);
                    188:   }
                    189:   else
                    190:   {
                    191:     upleftc = SDL_MapRGB(sdlscrn->format,255,255,255);
                    192:     downrightc = SDL_MapRGB(sdlscrn->format,128,128,128);
                    193:   }
                    194: 
                    195:   rect.x = x;  rect.y = y;
                    196:   rect.w = w;  rect.h = h;
                    197:   SDL_FillRect(sdlscrn, &rect, grey);
                    198: 
                    199:   rect.x = x;  rect.y = y-1;
                    200:   rect.w = w;  rect.h = 1;
                    201:   SDL_FillRect(sdlscrn, &rect, upleftc);
                    202: 
                    203:   rect.x = x-1;  rect.y = y;
                    204:   rect.w = 1;  rect.h = h;
                    205:   SDL_FillRect(sdlscrn, &rect, upleftc);
                    206: 
                    207:   rect.x = x;  rect.y = y+h;
                    208:   rect.w = w;  rect.h = 1;
                    209:   SDL_FillRect(sdlscrn, &rect, downrightc);
                    210: 
                    211:   rect.x = x+w;  rect.y = y;
                    212:   rect.w = 1;  rect.h = h;
                    213:   SDL_FillRect(sdlscrn, &rect, downrightc);
                    214: }
                    215: 
                    216: 
                    217: /*-----------------------------------------------------------------------*/
                    218: /*
                    219:   Draw a normal button.
                    220: */
                    221: void SDLGui_DrawButton(SGOBJ *bdlg, int objnum)
                    222: {
                    223:   int x,y;
                    224: 
                    225:   SDLGui_DrawBox(bdlg, objnum);
                    226: 
                    227:   x = (bdlg[0].x+bdlg[objnum].x+(bdlg[objnum].w-strlen(bdlg[objnum].txt))/2)*fontwidth;
                    228:   y = (bdlg[0].y+bdlg[objnum].y+(bdlg[objnum].h-1)/2)*fontheight;
                    229: 
                    230:   if( bdlg[objnum].state&SG_SELECTED )
                    231:   {
                    232:     x+=1;
                    233:     y+=1;
                    234:   }
                    235:   SDLGui_Text(x, y, bdlg[objnum].txt);
                    236: }
                    237: 
                    238: 
                    239: /*-----------------------------------------------------------------------*/
                    240: /*
                    241:   Draw a dialog radio button object.
                    242: */
                    243: void SDLGui_DrawRadioButton(SGOBJ *rdlg, int objnum)
                    244: {
                    245:   char str[80];
                    246:   int x, y;
                    247: 
                    248:   x = (rdlg[0].x+rdlg[objnum].x)*fontwidth;
                    249:   y = (rdlg[0].y+rdlg[objnum].y)*fontheight;
                    250: 
                    251:   if( rdlg[objnum].state&SG_SELECTED )
                    252:     str[0]=SGRADIOBUTTON_SELECTED;
                    253:    else
                    254:     str[0]=SGRADIOBUTTON_NORMAL;
                    255:   str[1]=' ';
                    256:   strcpy(&str[2], rdlg[objnum].txt);
                    257: 
                    258:   SDLGui_Text(x, y, str);
                    259: }
                    260: 
                    261: 
                    262: /*-----------------------------------------------------------------------*/
                    263: /*
                    264:   Draw a dialog check box object.
                    265: */
                    266: void SDLGui_DrawCheckBox(SGOBJ *cdlg, int objnum)
                    267: {
                    268:   char str[80];
                    269:   int x, y;
                    270: 
                    271:   x = (cdlg[0].x+cdlg[objnum].x)*fontwidth;
                    272:   y = (cdlg[0].y+cdlg[objnum].y)*fontheight;
                    273: 
                    274:   if( cdlg[objnum].state&SG_SELECTED )
                    275:     str[0]=SGCHECKBOX_SELECTED;
                    276:    else
                    277:     str[0]=SGCHECKBOX_NORMAL;
                    278:   str[1]=' ';
                    279:   strcpy(&str[2], cdlg[objnum].txt);
                    280: 
                    281:   SDLGui_Text(x, y, str);
                    282: }
                    283: 
                    284: 
                    285: /*-----------------------------------------------------------------------*/
                    286: /*
                    287:   Draw a dialog popup button object.
                    288: */
                    289: void SDLGui_DrawPopupButton(SGOBJ *pdlg, int objnum)
                    290: {
                    291:   int x, y, w, h;
                    292:   const char *downstr = "\x02";
                    293: 
                    294:   SDLGui_DrawBox(pdlg, objnum);
                    295: 
                    296:   x = (pdlg[0].x+pdlg[objnum].x)*fontwidth;
                    297:   y = (pdlg[0].y+pdlg[objnum].y)*fontheight;
                    298:   w = pdlg[objnum].w*fontwidth;
                    299:   h = pdlg[objnum].h*fontheight;
                    300: 
                    301:   SDLGui_Text(x, y, pdlg[objnum].txt);
                    302:   SDLGui_Text(x+w-fontwidth, y, downstr);
                    303: }
                    304: 
                    305: 
                    306: /*-----------------------------------------------------------------------*/
                    307: /*
                    308:   Draw a whole dialog.
                    309: */
                    310: void SDLGui_DrawDialog(SGOBJ *dlg)
                    311: {
                    312:   int i;
                    313:   for(i=0; dlg[i].type!=-1; i++ )
                    314:   {
                    315:     switch( dlg[i].type )
                    316:     {
                    317:       case SGBOX:
                    318:         SDLGui_DrawBox(dlg, i);
                    319:         break;
                    320:       case SGTEXT:
                    321:         SDLGui_DrawText(dlg, i);
                    322:         break;
                    323:       case SGBUTTON:
                    324:         SDLGui_DrawButton(dlg, i);
                    325:         break;
                    326:       case SGRADIOBUT:
                    327:         SDLGui_DrawRadioButton(dlg, i);
                    328:         break;
                    329:       case SGCHECKBOX:
                    330:         SDLGui_DrawCheckBox(dlg, i);
                    331:         break;
                    332:       case SGPOPUP:
                    333:         SDLGui_DrawPopupButton(dlg, i);
                    334:         break;
                    335:     }
                    336:   }
                    337:   SDL_UpdateRect(sdlscrn, 0,0,0,0);
                    338: }
                    339: 
                    340: 
                    341: /*-----------------------------------------------------------------------*/
                    342: /*
                    343:   Search an object at a certain position.
                    344: */
                    345: int SDLGui_FindObj(SGOBJ *dlg, int fx, int fy)
                    346: {
                    347:   int len, i;
                    348:   int ob = -1;
                    349:   int xpos, ypos;
                    350: 
                    351:   len = 0;
                    352:   while( dlg[len].type!=-1)   len++;
                    353: 
                    354:   xpos = fx/fontwidth;
                    355:   ypos = fy/fontheight;
                    356:   /* Now search for the object: */
                    357:   for(i=len; i>0; i--)
                    358:   {
                    359:     if(xpos>=dlg[0].x+dlg[i].x && ypos>=dlg[0].y+dlg[i].y
                    360:        && xpos<dlg[0].x+dlg[i].x+dlg[i].w && ypos<dlg[0].y+dlg[i].y+dlg[i].h)
                    361:     {
                    362:       ob = i;
                    363:       break;
                    364:     }
                    365:   }
                    366: 
                    367:   return ob;
                    368: }
                    369: 
                    370: 
                    371: /*-----------------------------------------------------------------------*/
                    372: /*
                    373:   Show and process a dialog. Returns the button number that has been
                    374:   pressed or -1 if something went wrong.
                    375: */
                    376: int SDLGui_DoDialog(SGOBJ *dlg)
                    377: {
                    378:   int obj=0;
                    379:   int oldbutton=0;
                    380:   int retbutton=0;
                    381:   int i, j, b;
                    382:   SDL_Event evnt;
                    383:   SDL_Rect rct;
                    384:   Uint32 grey;
                    385: 
                    386:   grey = SDL_MapRGB(sdlscrn->format,192,192,192);
                    387: 
                    388:   SDLGui_DrawDialog(dlg);
                    389: 
                    390:   /* Is the left mouse button still pressed? Yes -> Handle TOUCHEXIT objects here */
                    391:   SDL_PumpEvents();
                    392:   b = SDL_GetMouseState(&i, &j);
                    393:   obj = SDLGui_FindObj(dlg, i, j);
                    394:   if(obj>0 && (dlg[obj].flags&SG_TOUCHEXIT) )
                    395:   {
                    396:     oldbutton = obj;
                    397:     if( b&SDL_BUTTON(1) )
                    398:     {
                    399:       dlg[obj].state |= SG_SELECTED;
                    400:       return obj;
                    401:     }
                    402:   }
                    403: 
                    404:   /* The main loop */
                    405:   do
                    406:   {
                    407:     if( SDL_WaitEvent(&evnt)==1 )  /* Wait for events */
                    408:       switch(evnt.type)
                    409:       {
                    410:         case SDL_KEYDOWN:
                    411:           break;
                    412:         case SDL_QUIT:
                    413:           bQuitProgram = TRUE;
                    414:           break;
                    415:         case SDL_MOUSEBUTTONDOWN:
                    416:           obj = SDLGui_FindObj(dlg, evnt.button.x, evnt.button.y);
                    417:           if(obj>0)
                    418:           {
                    419:             if(dlg[obj].type==SGBUTTON)
                    420:             {
                    421:               dlg[obj].state |= SG_SELECTED;
                    422:               SDLGui_DrawButton(dlg, obj);
                    423:               SDL_UpdateRect(sdlscrn, (dlg[0].x+dlg[obj].x)*fontwidth-2, (dlg[0].y+dlg[obj].y)*fontheight-2,
                    424:                              dlg[obj].w*fontwidth+4, dlg[obj].h*fontheight+4);
                    425:               oldbutton=obj;
                    426:             }
                    427:             if( dlg[obj].flags&SG_TOUCHEXIT )
                    428:             {
                    429:               dlg[obj].state |= SG_SELECTED;
                    430:               retbutton = obj;
                    431:             }
                    432:           }
                    433:           break;
                    434:         case SDL_MOUSEBUTTONUP:
                    435:           obj = SDLGui_FindObj(dlg, evnt.button.x, evnt.button.y);
                    436:           if(obj>0)
                    437:           {
                    438:             switch(dlg[obj].type)
                    439:             {
                    440:               case SGBUTTON:
                    441:                 if(oldbutton==obj)
                    442:                   retbutton=obj;
                    443:                 break;
                    444:               case SGRADIOBUT:
                    445:                 for(i=obj-1; i>0 && dlg[i].type==SGRADIOBUT; i--)
                    446:                 {
                    447:                   dlg[i].state &= ~SG_SELECTED;  /* Deselect all radio buttons in this group */
                    448:                   rct.x = (dlg[0].x+dlg[i].x)*fontwidth;
                    449:                   rct.y = (dlg[0].y+dlg[i].y)*fontheight;
                    450:                   rct.w = fontwidth;  rct.h = fontheight;
                    451:                   SDL_FillRect(sdlscrn, &rct, grey); /* Clear old */
                    452:                   SDLGui_DrawRadioButton(dlg, i);
                    453:                   SDL_UpdateRects(sdlscrn, 1, &rct);
                    454:                 }
                    455:                 for(i=obj+1; dlg[i].type==SGRADIOBUT; i++)
                    456:                 {
                    457:                   dlg[i].state &= ~SG_SELECTED;  /* Deselect all radio buttons in this group */
                    458:                   rct.x = (dlg[0].x+dlg[i].x)*fontwidth;
                    459:                   rct.y = (dlg[0].y+dlg[i].y)*fontheight;
                    460:                   rct.w = fontwidth;  rct.h = fontheight;
                    461:                   SDL_FillRect(sdlscrn, &rct, grey); /* Clear old */
                    462:                   SDLGui_DrawRadioButton(dlg, i);
                    463:                   SDL_UpdateRects(sdlscrn, 1, &rct);
                    464:                 }
                    465:                 dlg[obj].state |= SG_SELECTED;  /* Select this radio button */
                    466:                 rct.x = (dlg[0].x+dlg[obj].x)*fontwidth;
                    467:                 rct.y = (dlg[0].y+dlg[obj].y)*fontheight;
                    468:                 rct.w = fontwidth;  rct.h = fontheight;
                    469:                 SDL_FillRect(sdlscrn, &rct, grey); /* Clear old */
                    470:                 SDLGui_DrawRadioButton(dlg, obj);
                    471:                 SDL_UpdateRects(sdlscrn, 1, &rct);
                    472:                 break;
                    473:               case SGCHECKBOX:
                    474:                 dlg[obj].state ^= SG_SELECTED;
                    475:                 rct.x = (dlg[0].x+dlg[obj].x)*fontwidth;
                    476:                 rct.y = (dlg[0].y+dlg[obj].y)*fontheight;
                    477:                 rct.w = fontwidth;  rct.h = fontheight;
                    478:                 SDL_FillRect(sdlscrn, &rct, grey); /* Clear old */
                    479:                 SDLGui_DrawCheckBox(dlg, obj);
                    480:                 SDL_UpdateRects(sdlscrn, 1, &rct);
                    481:                 break;
                    482:               case SGPOPUP:
                    483:                 dlg[obj].state |= SG_SELECTED;
                    484:                 SDLGui_DrawPopupButton(dlg, obj);
                    485:                 SDL_UpdateRect(sdlscrn, (dlg[0].x+dlg[obj].x)*fontwidth-2, (dlg[0].y+dlg[obj].y)*fontheight-2,
                    486:                            dlg[obj].w*fontwidth+4, dlg[obj].h*fontheight+4);
                    487:                 retbutton=obj;
                    488:                 break;
                    489:             }
                    490:           }
                    491:           if(oldbutton>0)
                    492:           {
                    493:             dlg[oldbutton].state &= ~SG_SELECTED;
                    494:             SDLGui_DrawButton(dlg, oldbutton);
                    495:             SDL_UpdateRect(sdlscrn, (dlg[0].x+dlg[oldbutton].x)*fontwidth-2, (dlg[0].y+dlg[oldbutton].y)*fontheight-2,
                    496:                            dlg[oldbutton].w*fontwidth+4, dlg[oldbutton].h*fontheight+4);
                    497:             oldbutton = 0;
                    498:           }
                    499:           if( dlg[obj].flags&SG_EXIT )
                    500:           {
                    501:             retbutton = obj;
                    502:           }
                    503:           break;
                    504:       }
                    505:   }
                    506:   while(retbutton==0 && !bQuitProgram);
                    507: 
                    508:   if(bQuitProgram)
                    509:     retbutton=-1;
                    510: 
                    511:   return retbutton;
                    512: }
                    513: 
                    514: 
                    515: /*-----------------------------------------------------------------------*/
                    516: /*
                    517:   Show and process a file select dialog.
                    518:   Returns TRUE if the use selected "okay", FALSE if "cancel".
                    519:   input: zip_path = pointer to buffer to contain file path within a selected
                    520:   zip file, or NULL if browsing zip files is disallowed.
                    521: */
                    522: #define SGFSDLG_UPDIR     6
                    523: #define SGFSDLG_ROOTDIR   7
                    524: #define SGFSDLG_ENTRY1    10
                    525: #define SGFSDLG_ENTRY16   25
                    526: #define SGFSDLG_UP        26
                    527: #define SGFSDLG_DOWN      27
                    528: #define SGFSDLG_OKAY      28
                    529: #define SGFSDLG_CANCEL    29
                    530: int SDLGui_FileSelect(char *path_and_name, char *zip_path)
                    531: {
                    532:   int i,n;
                    533:   int entries = 0;                             /* How many files are in the actual directory? */
                    534:   int ypos = 0;
                    535:   char dlgfilenames[16][36];
                    536:   struct dirent **files = NULL;
                    537:   char path[MAX_FILENAME_LENGTH], fname[128];  /* The actual file and path names */
                    538:   char dlgpath[39], dlgfname[33];              /* File and path name in the dialog */
                    539:   BOOL reloaddir = TRUE;                       /* Do we have to reload the directory file list? */
                    540:   BOOL refreshentries = TRUE;                  /* Do we have to update the file names in the dialog? */
                    541:   int retbut;
                    542:   int oldcursorstate;
                    543:   int selection = -1;                          /* The actual selection, -1 if none selected */
                    544:   char zipfilename[MAX_FILENAME_LENGTH];       /* Filename in zip file */
                    545:   char zipdir[MAX_FILENAME_LENGTH];
                    546:   BOOL browsingzip = FALSE;                    /* Are we browsing an archive? */
                    547: 
                    548:   SGOBJ fsdlg[] =
                    549:   {
                    550:     { SGBOX, 0, 0, 0,0, 40,25, NULL },
                    551:     { SGTEXT, 0, 0, 13,1, 13,1, "Choose a file" },
                    552:     { SGTEXT, 0, 0, 1,2, 7,1, "Folder:" },
                    553:     { SGTEXT, 0, 0, 1,3, 38,1, dlgpath },
                    554:     { SGTEXT, 0, 0, 1,4, 6,1, "File:" },
                    555:     { SGTEXT, 0, 0, 7,4, 31,1, dlgfname },
                    556:     { SGBUTTON, 0, 0, 31,1, 4,1, ".." },
                    557:     { SGBUTTON, 0, 0, 36,1, 3,1, "/" },
                    558:     { SGBOX, 0, 0, 1,6, 38,16, NULL },
                    559:     { SGBOX, 0, 0, 38,7, 1,14, NULL },
                    560:     { SGTEXT, SG_EXIT, 0, 2,6, 35,1, dlgfilenames[0] },
                    561:     { SGTEXT, SG_EXIT, 0, 2,7, 35,1, dlgfilenames[1] },
                    562:     { SGTEXT, SG_EXIT, 0, 2,8, 35,1, dlgfilenames[2] },
                    563:     { SGTEXT, SG_EXIT, 0, 2,9, 35,1, dlgfilenames[3] },
                    564:     { SGTEXT, SG_EXIT, 0, 2,10, 35,1, dlgfilenames[4] },
                    565:     { SGTEXT, SG_EXIT, 0, 2,11, 35,1, dlgfilenames[5] },
                    566:     { SGTEXT, SG_EXIT, 0, 2,12, 35,1, dlgfilenames[6] },
                    567:     { SGTEXT, SG_EXIT, 0, 2,13, 35,1, dlgfilenames[7] },
                    568:     { SGTEXT, SG_EXIT, 0, 2,14, 35,1, dlgfilenames[8] },
                    569:     { SGTEXT, SG_EXIT, 0, 2,15, 35,1, dlgfilenames[9] },
                    570:     { SGTEXT, SG_EXIT, 0, 2,16, 35,1, dlgfilenames[10] },
                    571:     { SGTEXT, SG_EXIT, 0, 2,17, 35,1, dlgfilenames[11] },
                    572:     { SGTEXT, SG_EXIT, 0, 2,18, 35,1, dlgfilenames[12] },
                    573:     { SGTEXT, SG_EXIT, 0, 2,19, 35,1, dlgfilenames[13] },
                    574:     { SGTEXT, SG_EXIT, 0, 2,20, 35,1, dlgfilenames[14] },
                    575:     { SGTEXT, SG_EXIT, 0, 2,21, 35,1, dlgfilenames[15] },
                    576:     { SGBUTTON, SG_TOUCHEXIT, 0, 38,6, 1,1, "\x01" },          /* Arrow up */
                    577:     { SGBUTTON, SG_TOUCHEXIT, 0, 38,21, 1,1, "\x02" },         /* Arrow down */
                    578:     { SGBUTTON, 0, 0, 10,23, 8,1, "Okay" },
                    579:     { SGBUTTON, 0, 0, 24,23, 8,1, "Cancel" },
                    580:     { -1, 0, 0, 0,0, 0,0, NULL }
                    581:   };
                    582: 
                    583:   zipfilename[0] = 0;
                    584:   SDLGui_CenterDlg(fsdlg);
                    585: 
                    586:   /* Prepare the path and filename variables */
                    587:   File_splitpath(path_and_name, path, fname, NULL);
                    588:   File_ShrinkName(dlgpath, path, 38);
                    589:   File_ShrinkName(dlgfname, fname, 32);
                    590: 
                    591:   /* Save old mouse cursor state and enable cursor anyway */
                    592:   oldcursorstate = SDL_ShowCursor(SDL_QUERY);
                    593:   if( oldcursorstate==SDL_DISABLE )
                    594:     SDL_ShowCursor(SDL_ENABLE);
                    595: 
                    596:   do
                    597:     {
                    598:       if( reloaddir )
                    599:        {
                    600:          if( strlen(path)>=MAX_FILENAME_LENGTH )
                    601:            {
                    602:              fprintf(stderr, "SDLGui_FileSelect: Path name too long!\n");
                    603:              return FALSE;
                    604:            }
                    605: 
                    606:          /* Free old allocated memory: */
                    607:          if( files!=NULL )
                    608:            {
                    609:              for(i=0; i<entries; i++)
                    610:                {
                    611:                  free(files[i]);
                    612:                }
                    613:              free(files);
                    614:              files = NULL;
                    615:            }
                    616: 
                    617:          if( browsingzip )
                    618:            {
                    619:            }
                    620:          else
                    621:            {
                    622:              /* Load directory entries: */
                    623:              entries = scandir(path, &files, 0, alphasort);
                    624:            }
                    625: 
                    626:          if(entries<0)
                    627:            {
                    628:              fprintf(stderr, "SDLGui_FileSelect: Path not found.\n");
                    629:              return FALSE;
                    630:            }
                    631: 
                    632:          reloaddir = FALSE;
                    633:          refreshentries = TRUE;
                    634:        }/* reloaddir */
                    635: 
                    636: 
                    637:       if( refreshentries )
                    638:        {
                    639:          /* Copy entries to dialog: */
                    640:          for(i=0; i<16; i++)
                    641:            {
                    642:              if( i+ypos<entries )
                    643:                {
                    644:                  char tempstr[MAX_FILENAME_LENGTH];
                    645:                  struct stat filestat;
                    646:                  /* Prepare entries: */
                    647:                  strcpy(tempstr, "  ");
                    648:                  strcat(tempstr, files[i+ypos]->d_name);
                    649:                  File_ShrinkName(dlgfilenames[i], tempstr, 35);
                    650:                  /* Mark folders: */
                    651:                  strcpy(tempstr, path);
                    652:                  strcat(tempstr, files[i+ypos]->d_name);
                    653: 
                    654:                  if( browsingzip )
                    655:                    {
                    656:                      if( tempstr[strlen(tempstr)-1] == '/'  )
                    657:                        dlgfilenames[i][0] = SGFOLDER;    /* Mark folders */
                    658:                    }
                    659:                  else
                    660:                    {
                    661:                      if( stat(tempstr, &filestat)==0 && S_ISDIR(filestat.st_mode) )
                    662:                        dlgfilenames[i][0] = SGFOLDER;    /* Mark folders */
                    663:                      if( File_FileNameIsZIP(tempstr) && browsingzip == FALSE)
                    664:                        dlgfilenames[i][0] = SGFOLDER;    /* Mark .ZIP archives as folders */
                    665:                    }
                    666:                }
                    667:              else
                    668:                dlgfilenames[i][0] = 0;  /* Clear entry */
                    669:            }
                    670:          refreshentries = FALSE;
                    671:        }/* refreshentries */
                    672: 
                    673:       /* Show dialog: */
                    674:       retbut = SDLGui_DoDialog(fsdlg);
                    675: 
                    676:       /* Has the user clicked on a file or folder? */
                    677:       if( retbut>=SGFSDLG_ENTRY1 && retbut<=SGFSDLG_ENTRY16 && retbut-SGFSDLG_ENTRY1+ypos<entries)
                    678:        {
                    679:          char tempstr[MAX_FILENAME_LENGTH];
                    680:          struct stat filestat;
                    681: 
                    682:          if( browsingzip == TRUE )
                    683:            {
                    684:              strcpy(tempstr, zipdir);
                    685:              strcat(tempstr, files[retbut-SGFSDLG_ENTRY1+ypos]->d_name);
                    686:              if(tempstr[strlen(tempstr)-1] == '/')
                    687:                {
                    688:                  /* handle the ../ directory */
                    689:                  if(strcmp(files[retbut-SGFSDLG_ENTRY1+ypos]->d_name, "../") == 0)
                    690:                    {
                    691:                      /* close the zip file */
                    692:                      if( strcmp(tempstr, "../") == 0 )
                    693:                        {
                    694:                        }
                    695:                      else
                    696:                        {
                    697:                          i=strlen(tempstr)-1; n=0;
                    698:                          while(i > 0 && n < 3) if( tempstr[i--] == '/' )n++;
                    699:                          if(tempstr[i+1] == '/') tempstr[i+2] = '\0';
                    700:                          else tempstr[0] = '\0';
                    701: 
                    702:                          strcpy(zipdir, tempstr);
                    703:                          File_ShrinkName(dlgpath, zipdir, 38);
                    704:                        }
                    705:                    }
                    706:                  else /* not the "../" directory */
                    707:                    {
                    708:                      strcpy(zipdir, tempstr);
                    709:                      File_ShrinkName(dlgpath, zipdir, 38);
                    710:                    }
                    711:                  reloaddir = TRUE;
                    712:                  /* Copy the path name to the dialog */
                    713:                  selection = -1;                /* Remove old selection */
                    714:                  zipfilename[0] = '\0';
                    715:                  dlgfname[0] = 0;
                    716:                  ypos = 0;
                    717: 
                    718:                } else {
                    719:                  /* Select a file in the zip */
                    720:                  selection = retbut-SGFSDLG_ENTRY1+ypos;
                    721:                  strcpy(zipfilename, files[selection]->d_name);
                    722:                  File_ShrinkName(dlgfname, zipfilename, 32);
                    723:                }
                    724: 
                    725:            } /* if browsingzip */
                    726:          else
                    727:            {
                    728:              strcpy(tempstr, path);
                    729:              strcat(tempstr, files[retbut-SGFSDLG_ENTRY1+ypos]->d_name);
                    730:              if( stat(tempstr, &filestat)==0 && S_ISDIR(filestat.st_mode) )
                    731:                {
                    732:                  /* Set the new directory */
                    733:                  strcpy(path, tempstr);
                    734:                  if( strlen(path)>=3 )
                    735:                    {
                    736:                      if(path[strlen(path)-2]=='/' && path[strlen(path)-1]=='.')
                    737:                        path[strlen(path)-2] = 0;  /* Strip a single dot at the end of the path name */
                    738:                      if(path[strlen(path)-3]=='/' && path[strlen(path)-2]=='.' && path[strlen(path)-1]=='.')
                    739:                        {
                    740:                          /* Handle the ".." folder */
                    741:                          char *ptr;
                    742:                          if( strlen(path)==3 )
                    743:                            path[1] = 0;
                    744:                          else
                    745:                            {
                    746:                              path[strlen(path)-3] = 0;
                    747:                              ptr = strrchr(path, '/');
                    748:                              if(ptr)  *(ptr+1) = 0;
                    749:                            }
                    750:                        }
                    751:                    }
                    752:                  File_AddSlashToEndFileName(path);
                    753:                  reloaddir = TRUE;
                    754:                  /* Copy the path name to the dialog */
                    755:                  File_ShrinkName(dlgpath, path, 38);
                    756:                  selection = -1;                /* Remove old selection */
                    757:                  dlgfname[0] = 0;
                    758:                  ypos = 0;
                    759:                }
                    760:          else if ( File_FileNameIsZIP(tempstr) && zip_path != NULL )
                    761:            {
                    762: 
                    763:            } else {
                    764:              /* Select a file */
                    765:              selection = retbut-SGFSDLG_ENTRY1+ypos;
                    766:              strcpy(fname, files[selection]->d_name);
                    767:              File_ShrinkName(dlgfname, fname, 32);
                    768:            }
                    769: 
                    770:            } /* not browsingzip */
                    771: 
                    772:        }
                    773:       else    /* Has the user clicked on another button? */
                    774:        {
                    775:          switch(retbut)
                    776:            {
                    777:            case SGFSDLG_UPDIR:                 /* Change path to parent directory */
                    778: 
                    779:              if( browsingzip )
                    780:              {
                    781:              /* close the zip file */
                    782:              if( strcmp(zipdir, "") == 0 )
                    783:                {
                    784:                  reloaddir = refreshentries = TRUE;
                    785:                  /* Copy the path name to the dialog */
                    786:                  File_ShrinkName(dlgpath, path, 38);
                    787:                  browsingzip = FALSE;
                    788:                  reloaddir = TRUE;
                    789:                  selection = -1;                 /* Remove old selection */
                    790:                  fname[0] = 0;
                    791:                  dlgfname[0] = 0;
                    792:                  ypos = 0;
                    793:                }
                    794:              else
                    795:                {
                    796:                  i=strlen(zipdir)-1; n=0;
                    797:                  while(i > 0 && n < 2) if( zipdir[i--] == '/' )n++;
                    798:                  if(zipdir[i+1] == '/') zipdir[i+2] = '\0';
                    799:                  else zipdir[0] = '\0';
                    800: 
                    801:                  File_ShrinkName(dlgpath, zipdir, 38);
                    802:                  reloaddir = TRUE;
                    803:                  selection = -1;                 /* Remove old selection */
                    804:                  zipfilename[0] = '\0';
                    805:                  dlgfname[0] = 0;
                    806:                  ypos = 0;
                    807:                }
                    808:              }  /* not a zip file: */
                    809:              else if( strlen(path)>2 )
                    810:                {
                    811:                  char *ptr;
                    812:                  File_CleanFileName(path);
                    813:                  ptr = strrchr(path, '/');
                    814:                  if(ptr)  *(ptr+1) = 0;
                    815:                  File_AddSlashToEndFileName(path);
                    816:                  reloaddir = TRUE;
                    817:                  File_ShrinkName(dlgpath, path, 38);  /* Copy the path name to the dialog */
                    818:                  selection = -1;                 /* Remove old selection */
                    819:                  fname[0] = 0;
                    820:                  dlgfname[0] = 0;
                    821:                  ypos = 0;
                    822:                }
                    823:              break;
                    824:            case SGFSDLG_ROOTDIR:               /* Change to root directory */
                    825: 
                    826:              strcpy(path, "/");
                    827:              reloaddir = TRUE;
                    828:              strcpy(dlgpath, path);
                    829:              selection = -1;                   /* Remove old selection */
                    830:              fname[0] = 0;
                    831:              dlgfname[0] = 0;
                    832:              ypos = 0;
                    833:              break;
                    834:            case SGFSDLG_UP:                    /* Scroll up */
                    835:              if( ypos>0 )
                    836:                {
                    837:                  --ypos;
                    838:                  refreshentries = TRUE;
                    839:                }
                    840:              SDL_Delay(20);
                    841:              break;
                    842:            case SGFSDLG_DOWN:                  /* Scroll down */
                    843:              if( ypos+17<=entries )
                    844:                {
                    845:                  ++ypos;
                    846:                  refreshentries = TRUE;
                    847:                }
                    848:              SDL_Delay(20);
                    849:              break;
                    850:            } /* switch */
                    851:        } /* other button code */
                    852: 
                    853: 
                    854:     } /* do */
                    855: 
                    856: 
                    857:   while(retbut!=SGFSDLG_OKAY && retbut!=SGFSDLG_CANCEL && !bQuitProgram);
                    858: 
                    859:   if( oldcursorstate==SDL_DISABLE )
                    860:     SDL_ShowCursor(SDL_DISABLE);
                    861: 
                    862:   File_makepath(path_and_name, path, fname, NULL);
                    863: 
                    864:   /* Free old allocated memory: */
                    865:   if( files!=NULL )
                    866:   {
                    867:     for(i=0; i<entries; i++)
                    868:     {
                    869:       free(files[i]);
                    870:     }
                    871:     free(files);
                    872:     files = NULL;
                    873:   }
                    874: 
                    875:   return( retbut==SGFSDLG_OKAY );
                    876: }
                    877: 
                    878: 

unix.superglobalmegacorp.com

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