Annotation of hatari/src/sdlgui.c, revision 1.1.1.3

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

unix.superglobalmegacorp.com

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