revert between 56095 -> 55830 in arch
[AROS.git] / workbench / libs / reqtools / filereqextra.c
blobdc89d7ebf016ea449b854b93ea1329002dcb1c1a
1 /*
2 Copyright © 1995-2018, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: English
7 */
9 /**************************************************************
10 * *
11 * File/Font/Screenmode requester *
12 * *
13 * (c) Nico François 1991-1994 *
14 **************************************************************/
16 #include "filereq.h"
18 #define D(x)
20 /****************************************************************************************/
22 extern struct LocaleBase *LocaleBase;
24 /****************************************************************************************/
26 static void REGARGS MarkHidden (GlobData *);
27 static int REGARGS SkipEntry (GlobData *, struct ReqEntry *);
29 /****************************************************************************************/
31 /********************
32 * Requester Display *
33 ********************/
35 /****************************************************************************************/
37 void REGARGS AdjustScroller (GlobData *glob)
39 myGT_SetGadgetAttrs (glob->scrollergad, glob->reqwin, NULL, GTSC_Total, glob->buff->currentnum,
40 GTSC_Top, glob->buff->gotopos,
41 TAG_END);
44 /****************************************************************************************/
46 void REGARGS ClearFilesRect (GlobData *glob)
48 SetAPen (glob->reqrp, glob->pens[BACKGROUNDPEN]);
49 mySetWriteMask (glob->reqrp, glob->entrymask);
50 RectFill (glob->reqrp, glob->boxleft, glob->boxtop - 1, glob->boxright,
51 glob->boxtop + glob->boxheight);
52 mySetWriteMask (glob->reqrp, glob->rpmask);
55 /****************************************************************************************/
57 void REGARGS ScrollerMoved (GlobData *glob, int code)
59 glob->buff->gotopos = code;
60 if (!glob->buff->sorted)
62 glob->buff->pos = glob->buff->gotopos;
63 UpdateDisplayList (glob);
64 PrintFiles (glob);
65 AdjustScroller (glob);
66 glob->buff->sorted = TRUE;
70 /****************************************************************************************/
72 static void REGARGS MarkHidden (GlobData *glob)
74 struct ReqEntry *entry;
75 int skipflags;
77 if (glob->nodir) return;
79 for (entry = (struct ReqEntry *)glob->firstentry->re_Next;
80 entry;
81 entry = (struct ReqEntry *)entry->re_Next)
83 entry->re_Flags &= ~(ENTRYF_HIDDEN|ENTRYF_GHOSTED);
84 if ((skipflags = SkipEntry (glob, entry))) entry->re_Flags |= skipflags;
88 /****************************************************************************************/
90 void REGARGS RethinkReqDisplay (GlobData *glob)
92 int num;
94 if (glob->nodir) return;
96 MarkHidden (glob);
97 num = (glob->buff->currentnum = CountAllDeselect (glob, FALSE))
98 - glob->numentries;
99 if (num < 0) glob->buff->gotopos = glob->buff->pos = 0;
100 else if (glob->buff->pos > num) glob->buff->gotopos = glob->buff->pos = num;
102 AdjustScroller (glob);
103 UpdateDisplayList (glob);
104 PrintFiles (glob);
107 /****************************************************************************************/
109 void REGARGS ClearDisplayList (GlobData *glob)
111 memset (glob->displaylist, 0, 50*4);
114 /****************************************************************************************/
116 void REGARGS UpdateDisplayList (GlobData *glob)
118 struct ReqEntry *entry;
119 int i;
121 i = 0;
123 if (glob->buff->currentnum &&
124 (entry = (struct ReqEntry *)glob->firstentry->re_Next))
126 while (i < glob->buff->pos)
128 if (!(entry->re_Flags & ENTRYF_HIDDEN))
130 i++;
133 entry = (struct ReqEntry *)entry->re_Next;
137 for (i = 0; entry && (i < glob->numentries);
138 entry = (struct ReqEntry *)entry->re_Next)
140 if (!(entry->re_Flags & ENTRYF_HIDDEN))
142 glob->displaylist[i++] = entry;
147 while (i < glob->numentries)
149 glob->displaylist[i++] = NULL;
153 /****************************************************************************************/
155 static UWORD GhostPattern[] = { 0x4444, 0x1111 };
157 /****************************************************************************************/
159 /* Apply a ghosting pattern to a given rectangle in a rastport */
160 static void REGARGS Ghost (struct RastPort *rp, UWORD pen, UWORD x, UWORD y, UWORD w, UWORD h)
162 SetAPen (rp, pen);
163 SetBPen (rp, pen);
164 SetDrMd (rp, JAM1);
165 SetAfPt (rp, GhostPattern, 1);
166 RectFill (rp, x, y, x + w - 1, y + h - 1);
167 SetAfPt (rp, NULL, 0);
170 /****************************************************************************************/
172 void REGARGS PrintEntry (GlobData *glob, int i)
174 struct TextExtent extent;
175 struct ReqEntry *entry;
176 struct RastPort *reqrp = glob->reqrp;
177 char sizestr[16], tempstr[108], *volname = NULL, *str;
178 int apen = 0, bpen = 0, top, len = 0, sizelen = 0, sizelenpix = 0, type, rectpen, left, entrytop;
179 LONG size;
181 mySetWriteMask (glob->reqrp, glob->entrymask);
182 rectpen = BACKGROUNDPEN;
184 if ((entry = glob->displaylist[i]))
186 strcpy (tempstr, entry->re_Name);
187 apen = TEXTPEN; bpen = BACKGROUNDPEN;
188 sizestr[0] = 0;
189 size = entry->re_Size;
190 type = entry->re_Type;
191 if (type == glob->directory_id)
193 strcpy (sizestr, GetStr (glob->catalog, MSG_DRAWER));
194 apen = HIGHLIGHTTEXTPEN;
196 else if (type == FONT || (type == glob->file_id))
198 BOOL useLocFmt = LocaleBase ? TRUE : FALSE;
199 #ifdef __AROS__
200 /* FIXME: AROS LocaleLibrary does not yet patch RawDoFmt. So "%lD" (uppercase D) does not work yet here! */
201 useLocFmt = FALSE;
202 #endif
203 DofmtArgs (sizestr, useLocFmt ? " %lD" : " %ld", size);
205 if (type == FONT)
207 StrCat (tempstr, sizestr);
208 sizestr[0] = 0;
211 else if (type == ASSIGN)
213 strcpy (sizestr, GetStr (glob->catalog, MSG_ASSIGN));
214 apen = HIGHLIGHTTEXTPEN;
216 else if (type == VOLUME)
218 if (size >= 0) DofmtArgs (sizestr, GetStr (glob->catalog, MSG_FULL), size);
221 if (type == VOLUME && entry->re_VolLen)
223 len = entry->re_VolLen;
224 volname = entry->re_Name + len + 1;
226 else
227 len = strlen (tempstr);
229 sizelen = strlen (sizestr);
230 /* Cache the pixel size for each entry so
231 we only have to calculate this once. */
232 if (entry->re_SizeLenPix)
233 sizelenpix = entry->re_SizeLenPix;
234 else
236 if (sizestr[0])
237 sizelenpix = StrWidth_noloc (&glob->itxt, sizestr);
238 else
239 sizelenpix = 0;
241 if (sizelenpix < 256) entry->re_SizeLenPix = sizelenpix;
244 if (entry->re_Flags & ENTRYF_SELECTED)
246 bpen = FILLPEN;
247 if (type == glob->directory_id || type == ASSIGN)
249 apen = BACKGROUNDPEN;
250 bpen = HIGHLIGHTTEXTPEN;
252 else /* VOLUME, FILE, FONT */
253 apen = FILLTEXTPEN;
255 rectpen = bpen;
258 } /* if ((entry = glob->displaylist[i])) */
259 else
261 if (glob->lastdisplaylistnum == -1) glob->lastdisplaylistnum = i;
264 top = glob->boxtop + i * glob->entryheight;
265 SetDrMd (glob->reqrp, JAM2);
266 SetAPen (reqrp, glob->pens[rectpen]);
267 entrytop = top;
268 RectFill (reqrp, glob->boxleft, entrytop, glob->boxright, entrytop + glob->entryheight - 1);
270 if (entry)
272 SetAPen (reqrp, glob->pens[apen]);
273 SetBPen (reqrp, glob->pens[bpen]);
274 top += glob->fontbase + 1;
275 str = tempstr;
276 left = glob->boxleft + 2;
277 Move (reqrp, left, top);
279 if (volname)
281 Text (reqrp, volname, strlen (volname));
282 left += glob->maxvolwidth;
283 Move (reqrp, left, top);
286 /* Cache entry length, so we only need to calculate this once */
287 if (!entry->re_EntryLen)
289 len = TextFit (reqrp, str, len, &extent, NULL, 1,
290 glob->boxright - left - sizelenpix - 5, glob->entryheight);
291 entry->re_EntryLen = len;
293 else len = entry->re_EntryLen;
295 Text (reqrp, str, len);
297 if (sizelenpix)
299 Move (reqrp, glob->boxright - sizelenpix - 1, top);
300 Text (reqrp, sizestr, sizelen);
303 if (entry->re_Flags & ENTRYF_GHOSTED)
305 Ghost (reqrp, glob->pens[BACKGROUNDPEN],
306 glob->boxleft, entrytop,
307 glob->boxright - glob->boxleft + 1, glob->entryheight);
310 } /* if (entry) */
312 mySetWriteMask (glob->reqrp, glob->rpmask);
315 /****************************************************************************************/
317 void REGARGS PrintFiles (GlobData *glob)
319 int i;
321 glob->lastdisplaylistnum = -1;
322 for (i = 0; i < glob->numentries; i++)
324 PrintEntry (glob, i);
328 /****************************************************************************************/
330 /********************
331 * Requester entries *
332 ********************/
334 /****************************************************************************************/
336 void REGARGS ClearAndInitReqBuffer (GlobData *glob)
338 glob->buff->gotopos = glob->buff->pos = glob->buff->currentnum = glob->buff->numfiles = 0;
339 glob->firstentry = (struct ReqEntry *)AllocVecPooled(glob->buff->pool, sizeof (struct ReqEntry));
340 glob->buff->firstname = glob->firstentry;
343 /****************************************************************************************/
345 static UBYTE *REGARGS SkipDevName (UBYTE *entryname)
347 while (*entryname != ' ') entryname++;
348 while (*entryname == ' ') entryname++;
350 return (entryname);
353 /****************************************************************************************/
355 struct ReqEntry *REGARGS FindEntry (struct BufferData *buff, char *name, int size,
356 int ctype, int *pos, ULONG flags)
358 struct ReqEntry *curr, *lastname;
359 int lastcmp, cmp, i = 0, cmptype;
360 UBYTE *entryname;
362 lastname = buff->firstname;
363 curr = (struct ReqEntry *)lastname->re_Next;
364 if ((ctype <= MAX_FILE_DIRECTORY) && buff->dirsmixed)
366 cmptype = 1;
368 else
370 while (curr && curr->re_Type < ctype)
372 lastname = curr;
373 if (!(lastname->re_Flags & ENTRYF_HIDDEN)) i++;
374 curr = (struct ReqEntry *)curr->re_Next;
376 cmptype = ctype;
379 lastcmp = 1;
380 while (curr)
382 if (ctype >= 0 && curr->re_Type > cmptype) break;
383 entryname = curr->re_Name;
385 if (curr->re_Type == VOLUME && !(flags & FIND_VOLUMENAME))
387 cmp = Strnicmp (name, entryname, strlen(name));
389 else
391 if (curr->re_Type == VOLUME && (flags & FIND_VOLUMENAME))
392 entryname = SkipDevName (entryname);
393 cmp = Stricmp (name, entryname);
396 if ((cmp < 0) || (!cmp && (size < curr->re_Size))) break;
398 lastcmp = cmp;
399 lastname = curr;
401 if (!(lastname->re_Flags & ENTRYF_HIDDEN)) i++;
403 curr = (struct ReqEntry *)curr->re_Next;
406 if (pos)
408 if (lastname && (!(flags & FIND_EXACT) || !lastcmp))
410 *pos = i - 1;
411 return (lastname);
413 else
415 *pos = 0;
416 return (NULL);
420 return (lastname);
423 /****************************************************************************************/
425 struct ReqEntry *REGARGS AddEntry (GlobData *glob, struct BufferData *buff,
426 char *name, int size, int ctype)
428 struct ReqEntry *lastname, *newentry;
429 int pos, len = strlen( name ) + 1, currnum, skipflags;
430 STRPTR str, findname = name;
432 if( ctype == VOLUME )
434 findname = SkipDevName( findname );
437 lastname = FindEntry( buff, findname, ( ( ctype == FONT ) ? size : MAXINT) ,
438 ctype, &pos, FIND_VOLUMENAME );
440 str = lastname->re_Name;
442 if( str && !Stricmp( name, str ) )
444 if( ctype <= MAX_FILE_DIRECTORY )
446 lastname->re_Size = size;
447 return( lastname );
450 len = 0;
453 if( !( newentry = ( struct ReqEntry * ) AllocVecPooled(buff->pool, sizeof( struct ReqEntry ) + len ) ) )
455 return( NULL );
458 if( len )
460 str = ( STRPTR ) newentry + sizeof( struct ReqEntry );
461 strcpy( str, name );
464 newentry->re_Name = str;
465 newentry->re_Size = size;
466 newentry->re_Type = ctype;
467 newentry->re_Next = lastname->re_Next;
468 lastname->re_Next = ( struct Node * ) newentry;
470 buff->numfiles++;
471 buff->sorted = FALSE;
473 if( glob )
475 skipflags = SkipEntry( glob, newentry );
476 newentry->re_Flags |= skipflags;
478 if( skipflags != ENTRYF_HIDDEN )
480 /* If file requester keep activated itempos up to date */
481 if( ctype <= MAX_FILE_DIRECTORY )
483 if( pos < glob->selectedpos )
485 glob->selectedpos++;
489 currnum = buff->currentnum;
490 buff->currentnum++;
492 if( ctype <= MAX_FILE_DIRECTORY )
493 { /* display now ? */
494 if (currnum < glob->numentries)
496 glob->displaylist[currnum] = newentry;
498 if( !glob->quiet )
500 PrintEntry( glob, currnum );
503 else if( !glob->quiet )
505 AdjustScroller( glob );
511 return( newentry );
514 /****************************************************************************************/
516 int REGARGS EndsInDotInfo (char *str, int len)
518 if (len >= 5 && !Stricmp (&str[len-5], DOTINFOSTR)) return (TRUE);
519 return (FALSE);
522 /****************************************************************************************/
524 static int REGARGS SkipEntry (GlobData *glob, struct ReqEntry *entry)
526 char *str = entry->re_Name;
527 int len = strlen (str);
529 if (glob->reqtype == RT_FILEREQ)
531 if (entry->re_Type == glob->file_id)
533 if (!glob->wilddotinfo)
535 if (EndsInDotInfo (str, len))
537 if (glob->freq->hideinfo) return (ENTRYF_HIDDEN);
539 if (glob->matchpat[0])
541 int ret;
543 str[len-5] = '\0';
544 ret = !MatchPatternNoCase (glob->matchpat, str);
545 str[len-5] = '.';
547 return (ret ? ENTRYF_HIDDEN : 0);
552 if (glob->flags & FREQF_NOFILES) return (ENTRYF_GHOSTED);
554 if (glob->matchpat[0])
555 if (!MatchPatternNoCase (glob->matchpat, str))
556 return (ENTRYF_HIDDEN);
559 else if (glob->reqtype == RT_FONTREQ)
561 if (entry->re_Size < glob->minsize || entry->re_Size > glob->maxsize ||
562 ((glob->flags & FREQF_FIXEDWIDTH) && (entry->re_Flags & FPF_PROPORTIONAL)) ||
563 (!(glob->flags & FREQF_COLORFONTS) && (entry->re_Style & FSF_COLORFONT)))
564 return (ENTRYF_HIDDEN);
566 else
571 return (0);
574 /****************************************************************************************/
576 int REGARGS CountAllDeselect (GlobData *glob, int dirsonly)
578 struct ReqEntry *entry;
579 int count = 0;
581 for (entry = (struct ReqEntry *)glob->firstentry->re_Next;
582 entry;
583 entry = (struct ReqEntry *)entry->re_Next)
585 if (!(entry->re_Flags & ENTRYF_HIDDEN)) count++;
586 if (!dirsonly || entry->re_Type != glob->file_id)
588 if (entry->re_Flags & ENTRYF_SELECTED)
590 glob->numselected--;
591 entry->re_Flags &= ~ENTRYF_SELECTED;
596 glob->selectedpos = -1;
598 return (count);
601 /****************************************************************************************/
603 void REGARGS SelectAll (GlobData *glob, char *pattern)
605 struct ReqEntry *entry;
606 char *selpat;
607 LONG pattern_len;
609 pattern_len = strlen(pattern) * 2 + 2;
610 selpat = AllocVec(pattern_len, MEMF_PUBLIC);
611 if (selpat)
613 ParsePatternNoCase (pattern, selpat, pattern_len);
615 for (entry = (struct ReqEntry *)glob->firstentry->re_Next;
616 entry;
617 entry = (struct ReqEntry *)entry->re_Next)
619 if (!(entry->re_Flags & (ENTRYF_HIDDEN|ENTRYF_GHOSTED)))
621 if ((entry->re_Type == glob->file_id) ||
622 (entry->re_Type == glob->directory_id && (glob->flags & FREQF_SELECTDIRS)))
624 if (MatchPatternNoCase (selpat, entry->re_Name))
626 if (!(entry->re_Flags & ENTRYF_SELECTED)) glob->numselected++;
627 entry->re_Flags |= ENTRYF_SELECTED;
632 FreeVec(selpat);
635 UpdateNumSelGad (glob);
636 PrintFiles (glob);
637 my_SetStringGadget (glob->reqwin, glob->filegad, NULL);
640 /****************************************************************************************/
642 /*****************
643 * File requester *
644 *****************/
646 /****************************************************************************************/
648 void REGARGS UnLockReqLock (GlobData *glob)
650 glob->ledon = FALSE;
651 RenderLED (glob);
652 if (glob->lock) UnLock (glob->lock);
653 glob->lock = BNULL;
656 /****************************************************************************************/
658 BOOL REGARGS FindVolume (GlobData *glob, UBYTE *str, struct ReqEntry *curr)
660 struct ReqEntry *entry;
661 UBYTE *s;
663 for (entry = (struct ReqEntry *)glob->firstentry->re_Next;
664 entry;
665 entry = (struct ReqEntry *)entry->re_Next)
667 if (entry != curr && entry->re_Type == VOLUME)
669 s = entry->re_Name;
670 while (*s != ' ') s++;
671 while (*s == ' ') s++;
672 if (!Stricmp (s, str)) return (TRUE);
676 return (FALSE);
679 /****************************************************************************************/
681 static BOOL
682 IsDosVolume(struct DosList *dlist)
684 BOOL isdev = FALSE;
685 D_S( struct InfoData,id );
687 if( !dlist->dol_Task || DoPkt1( dlist->dol_Task, ACTION_DISK_INFO, (SIPTR)MKBADDR( id ) ) )
689 isdev = TRUE;
692 return (isdev);
695 /****************************************************************************************/
697 static BOOL
698 IsDosDevice( struct DosList *dlist )
700 struct FileSysStartupMsg *fssm;
701 struct DosEnvec *de;
702 BOOL isdev = FALSE;
704 /* If it`s a device, do the hard check for a filesystem */
706 if (dlist->dol_Type == DLT_DEVICE)
708 fssm = ( struct FileSysStartupMsg * )BADDR( dlist->dol_misc.dol_handler.dol_Startup );
710 if( fssm )
712 if( TypeOfMem( fssm ) && TypeOfMem( BADDR( fssm->fssm_Device ) )
713 && TypeOfMem( BADDR( fssm->fssm_Environ ) ) )
715 if( *( ( STRPTR ) BADDR( fssm->fssm_Device ) ) != 255 )
717 de = ( struct DosEnvec * ) BADDR( fssm->fssm_Environ );
719 if( de && TypeOfMem( de ) )
721 if( de->de_Surfaces && de->de_BlocksPerTrack )
723 isdev = TRUE;
729 #ifdef TASK_DEVICE
730 else
732 isdev = ( dlist->dol_Task != NULL );
734 #endif
737 return( isdev );
740 /****************************************************************************************/
742 struct DeviceEntry
744 struct DeviceEntry *next;
745 struct MsgPort *task;
746 BOOL resolved;
747 UBYTE name[ 42 ];
750 /****************************************************************************************/
752 #define SIZE_NONE ( ( ULONG ) -1 )
753 #define SIZE_CALCULATE ( ( ULONG ) -2 )
755 /****************************************************************************************/
757 static void
758 AddDisk(
759 GlobData *glob,
760 struct DeviceEntry *deventry,
761 UBYTE *devname,
762 ULONG size,
763 ULONG volreqflags )
765 struct rtVolumeEntry volentry;
766 struct ReqEntry *entry;
767 UBYTE buffer[80];
768 int i, addentry;
770 D_S( struct InfoData, infodata );
772 addentry = TRUE;
774 if( volreqflags && glob->filterhook )
776 volentry.Type = DLT_DEVICE;
777 volentry.Name = devname;
778 addentry = CallHookPkt( glob->filterhook, glob->freq, &volentry );
781 if( addentry )
783 if( size == SIZE_CALCULATE )
785 size = SIZE_NONE;
787 if( deventry->task &&
788 DoPkt1( deventry->task, ACTION_DISK_INFO, (SIPTR)MKBADDR( infodata ) ) )
790 size = ( infodata->id_NumBlocksUsed * 100 +
791 infodata->id_NumBlocks / 2 ) /
792 infodata->id_NumBlocks;
796 i = StrWidth_noloc( &glob->itxt, deventry->name ) + StrWidth_noloc( &glob->itxt, "W" );
798 if( i > glob->maxvolwidth )
800 glob->maxvolwidth = i;
803 DofmtArgs( buffer, "%s %s", devname, deventry->name );
805 if( ( entry = AddEntry( glob, glob->buff, buffer, size, VOLUME ) ) )
807 entry->re_VolLen = strlen( devname );
812 /****************************************************************************************/
814 static struct DeviceEntry *
815 AllocDevEntry( GlobData *glob, struct DosList *dlist, STRPTR name )
817 struct DeviceEntry *deventry;
819 if( ( deventry = ( struct DeviceEntry * ) AllocVecPooled(
820 glob->buff->pool, sizeof( struct DeviceEntry ) ) ) )
822 strcpy( deventry->name, name );
823 deventry->task = dlist->dol_Task;
824 deventry->resolved = FALSE;
827 return( deventry );
830 /****************************************************************************************/
832 static void
833 GetVolName( BSTR bstr, STRPTR cstr )
835 #ifdef __AROS__
836 /* In AROS, BPTR:s are handled differently on different systems
837 (to be binary compatible on Amiga) */
839 if (bstr != BNULL)
841 LONG length = AROS_BSTR_strlen(bstr);
842 LONG i; /* Loop variable */
844 for (i = 0; i < length; i++)
846 cstr[i] = AROS_BSTR_getchar(bstr, i);
849 cstr[i++] = ':';
850 cstr[i] = 0;
852 D(bug("Found volume %s\n", cstr));
854 #else
855 STRPTR str;
857 *cstr = 0;
859 if( ( str = BADDR( bstr ) ) )
861 LONG i;
863 for( i = *str++; i--; )
865 *cstr++ = *str++;
868 *cstr++ = ':';
869 *cstr = 0;
871 #endif
875 /****************************************************************************************/
877 void REGARGS
878 AddDiskNames( GlobData *glob, ULONG volreqflags )
880 struct ReqEntry *entry, *temp;
881 struct DosList *dlist;
882 struct DeviceEntry *deventry, *lastdeventry = NULL;
883 struct rtVolumeEntry volentry;
884 UBYTE /* *bstr, *cstr, */ name[ 42 ], devname[ 36 ];
885 /* WORD i; */
887 *glob->winaddr = ( APTR ) -1;
888 glob->maxvolwidth = 0;
889 dlist = LockDosList( LDF_VOLUMES | LDF_ASSIGNS | LDF_READ );
891 /* Add PROGDIR: assign is possible, just like reqtools_patch.lha
892 from Aminet (by Mikolaj Calusinski) does. */
894 if (!(volreqflags & VREQF_NOASSIGNS))
896 if (((struct Process *)FindTask(NULL))->pr_HomeDir)
898 AddEntry(glob, glob->buff, "PROGDIR:", -1, ASSIGN);
902 while( ( dlist = NextDosEntry( dlist, LDF_VOLUMES | LDF_ASSIGNS | LDF_READ ) ) )
904 GetVolName(dlist->dol_Name, name);
905 if (dlist->dol_Type == DLT_VOLUME)
907 if (IsDosVolume(dlist) && !(volreqflags & VREQF_NODISKS))
909 if ((deventry = AllocDevEntry(glob, dlist, name)))
911 deventry->next = lastdeventry;
912 lastdeventry = deventry;
916 else if (dlist->dol_Type == DLT_DIRECTORY ||
917 dlist->dol_Type == DLT_NONBINDING)
919 if (!(volreqflags & VREQF_NOASSIGNS))
921 AddEntry(glob, glob->buff, name, -1, ASSIGN);
926 /* Append device names to volumes */
927 dlist = LockDosList( LDF_DEVICES | LDF_READ );
929 while( ( dlist = NextDosEntry( dlist, LDF_DEVICES | LDF_READ ) ) )
931 BOOL devmatch;
933 deventry = lastdeventry;
934 devmatch = FALSE;
936 while( deventry )
938 devmatch |= ( deventry->task == dlist->dol_Task );
939 if( !deventry->resolved && deventry->task && ( deventry->task == dlist->dol_Task ) )
941 GetVolName( dlist->dol_Name, devname );
942 AddDisk( glob, deventry, devname, SIZE_CALCULATE, volreqflags );
943 deventry->resolved = TRUE;
946 deventry = deventry->next;
949 if( !devmatch && ( volreqflags & VREQF_ALLDISKS ) &&
950 !( volreqflags & VREQF_NODISKS ) && IsDosDevice( dlist ) )
952 /* Device seems to be a DOS disk device, and it didn't belong
953 * to a volume, and we should really show all devices in a
954 * volume requester.
956 GetVolName( dlist->dol_Name, devname );
958 if( ( deventry = AllocDevEntry( glob, dlist, "-" ) ) )
960 deventry->next = lastdeventry;
961 lastdeventry = deventry;
962 AddDisk( glob, deventry, devname, SIZE_NONE, volreqflags );
963 deventry->resolved = TRUE;
968 UnLockDosList( LDF_DEVICES | LDF_READ );
969 UnLockDosList( LDF_VOLUMES | LDF_ASSIGNS | LDF_READ );
971 /* Free temp volume list (and add remaining names if ALLDISKS is on) */
972 while( ( deventry = lastdeventry ) )
974 if( !deventry->resolved /* && ( !volreqflags || ( volreqflags & VREQF_ALLDISKS ) ) */ )
976 AddDisk( glob, deventry, "-", SIZE_CALCULATE, volreqflags );
979 lastdeventry = deventry->next;
980 FreeVecPooled( glob->buff->pool, deventry );
983 /* If volume requester filter assigns */
984 if( volreqflags && glob->filterhook )
986 entry = glob->buff->firstname;
988 while( ( temp = entry ) )
990 entry = ( struct ReqEntry * ) entry->re_Next;
992 if( !entry )
994 break;
997 if( entry->re_Type == ASSIGN )
999 volentry.Type = DLT_DIRECTORY;
1000 volentry.Name = entry->re_Name;
1002 if( !CallHookPkt( glob->filterhook, glob->freq, &volentry ) )
1004 temp->re_Next = entry->re_Next;
1005 FreeVecPooled( glob->buff->pool, entry );
1006 entry = temp;
1007 glob->buff->currentnum--;
1013 *glob->winaddr = glob->reqwin;
1016 /****************************************************************************************/
1018 BOOL REGARGS FindCurrentPos (GlobData *glob, char *name, int size, int ctype)
1020 BOOL success;
1022 MarkHidden (glob);
1023 success = FindEntry (glob->buff, name, size, ctype, ( int * ) &glob->buff->pos, FIND_EXACT) ? TRUE : FALSE;
1024 glob->buff->gotopos = glob->buff->pos;
1026 return (success);
1029 /****************************************************************************************/
1031 void REGARGS NewDir (GlobData *glob)
1033 UnLockReqLock (glob);
1034 SetWindowTitles (glob->reqwin, glob->title, (char *)~0);
1035 FreeReqBuffer (glob->req);
1036 ClearDisplayList (glob);
1037 glob->newdir = TRUE;
1038 glob->clicked = ~0;
1040 if (glob->freq)
1042 SetFileDirMode (glob->buff, glob->flags);
1043 glob->file_id = glob->buff->file_id;
1044 glob->directory_id = glob->buff->directory_id;
1048 /****************************************************************************************/
1050 void REGARGS ShowDisks(GlobData *glob)
1053 if (!glob->disks)
1055 UnLockReqLock (glob);
1056 FreeReqBuffer (glob->req);
1057 ClearAndInitReqBuffer (glob);
1058 glob->exnext = FALSE;
1059 glob->disks = TRUE;
1060 AddDiskNames (glob, glob->volumerequest);
1061 AdjustScroller (glob);
1062 UpdateDisplayList (glob);
1063 PrintFiles (glob);
1064 glob->buff->sorted = TRUE;
1065 glob->selectedpos = -1;
1069 /****************************************************************************************/
1071 void REGARGS UpdateNumSelGad (GlobData *glob)
1073 int top;
1074 char str[6];
1076 if (glob->numselectedgad)
1078 DofmtArgs (str, "%4ld", glob->numselected);
1080 SetAPen (glob->reqrp, glob->pens[TEXTPEN]);
1081 SetBPen (glob->reqrp, glob->pens[BACKGROUNDPEN]);
1082 SetDrMd (glob->reqrp, JAM2);
1084 top = glob->numselectedgad->TopEdge + 3;
1086 Move (glob->reqrp, glob->numselectedgad->LeftEdge + glob->numselectedoff + 8,
1087 top + glob->reqfont->tf_Baseline);
1088 Text (glob->reqrp, str, 4);
1090 SetDrMd (glob->reqrp, JAM2);
1091 SetAPen (glob->reqrp, glob->pens[BACKGROUNDPEN]);
1093 RectFill (glob->reqrp, glob->reqrp->cp_x,
1094 top,
1095 glob->numselectedgad->LeftEdge + glob->numselectedgad->Width - 3,
1096 top + glob->fontheight - 1);
1100 /****************************************************************************************/
1102 /*****************
1103 * Font requester *
1104 *****************/
1106 /****************************************************************************************/
1108 static struct Region *MyInstallRegion (struct Window *win, struct Region *reg, int refresh)
1110 struct Region *oldregion;
1112 LockLayerInfo(&win->WScreen->LayerInfo);
1114 if (refresh) GT_EndRefresh (win, FALSE);
1116 oldregion = InstallClipRegion (win->WLayer, reg);
1117 if (refresh) GT_BeginRefresh (win);
1119 UnlockLayerInfo(&win->WScreen->LayerInfo);
1121 return (oldregion);
1124 /****************************************************************************************/
1126 void REGARGS ShowFontSample (GlobData *glob, int refresh, int dowait)
1128 struct DiskfontBase *DiskfontBase = glob->diskfontbase;
1129 struct TextFont *font;
1130 struct Rectangle rect;
1131 struct Region *oldregion, *region;
1132 char *message = "0123 aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ";
1133 UWORD *cmap = NULL;
1134 ULONG style = glob->fontstyle, count = glob->colcount;
1135 APTR winlock = NULL;
1137 if (dowait) winlock = rtLockWindow (glob->reqwin);
1139 if (glob->flags & FREQF_SCALE)
1140 glob->fontreq->Attr.ta_Flags &= ~FPF_DESIGNED;
1142 if (!(font = OpenDiskFont (&glob->fontreq->Attr)))
1144 font = glob->reqfont;
1145 message = GetStr (glob->catalog, MSG_COULDNT_OPEN_FONT);
1146 style = 0;
1149 rect.MinX = glob->fontdisplayleft;
1150 rect.MaxX = glob->fontdisplayright;
1151 rect.MinY = glob->fontdisplaytop;
1152 rect.MaxY = glob->fontdisplaytop + glob->sampleheight - 1;
1154 if ( ( region = NewRegion() ) )
1156 OrRectRegion (region, &rect);
1158 oldregion = MyInstallRegion (glob->reqwin, region, refresh);
1160 SetFont (glob->reqrp, font);
1161 SetSoftStyle (glob->reqrp, style, ~0);
1162 SetAPen (glob->reqrp, glob->pens[TEXTPEN]);
1163 SetBPen (glob->reqrp, glob->pens[BACKGROUNDPEN]);
1165 if (font->tf_Style & FSF_COLORFONT)
1167 struct ColorFontColors *cfc;
1169 cfc = ((struct ColorTextFont *)font)->ctf_ColorFontColors;
1170 if (cfc)
1172 count = cfc->cfc_Count;
1173 cmap = cfc->cfc_ColorTable;
1177 if (glob->flags & FREQF_CHANGEPALETTE)
1179 if (cmap) LoadRGB4 (glob->vp, cmap, count);
1180 else LoadCMap (glob->vp, glob->colormap);
1183 if (!refresh) SetRast (glob->reqrp, glob->pens[BACKGROUNDPEN]);
1185 Move (glob->reqrp, glob->fontdisplayleft,
1186 glob->fontdisplaytop + (glob->sampleheight - font->tf_YSize) / 2
1187 + font->tf_Baseline);
1188 Text (glob->reqrp, message, strlen(message));
1190 MyInstallRegion (glob->reqwin, oldregion, refresh);
1191 DisposeRegion (region);
1193 SetFont (glob->reqrp, glob->reqfont);
1194 SetSoftStyle (glob->reqrp, 0, ~0);
1197 /*endshowsample:*/
1198 CloseFont (font);
1199 if (dowait) rtUnlockWindow (glob->reqwin, winlock);
1202 /****************************************************************************************/
1204 /***********************
1205 * ScreenMode requester *
1206 ***********************/
1208 /****************************************************************************************/
1210 ULONG ASM myGetDisplayInfoData (
1211 OPT_REGPARAM(a1, UBYTE *, buf),
1212 OPT_REGPARAM(d0, unsigned long, size),
1213 OPT_REGPARAM(d1, unsigned long, tagID),
1214 OPT_REGPARAM(d2, unsigned long, displayID))
1216 return (GetDisplayInfoData (FindDisplayInfo (displayID),
1217 buf, size, tagID, displayID));
1220 /****************************************************************************************/
1222 int REGARGS GetModeData (GlobData *glob, ULONG id, int *mon)
1224 struct MonitorInfo monitorinfo;
1225 ULONG propflags;
1226 int modewidth, stdmode = TRUE;
1227 char *str, *monstr;
1229 if ((myGetDisplayInfoData ((UBYTE *)&glob->diminfo,
1230 sizeof (struct DimensionInfo), DTAG_DIMS, id) <= 0) ||
1231 (myGetDisplayInfoData ((UBYTE *)&glob->dispinfo,
1232 sizeof (struct DisplayInfo), DTAG_DISP, id) <= 0))
1234 return (FALSE);
1237 modewidth = glob->diminfo.Nominal.MaxX - glob->diminfo.Nominal.MinX + 1;
1238 propflags = glob->dispinfo.PropertyFlags;
1240 if ((glob->flags & SCREQF_GUIMODES) && !(propflags & DIPF_IS_WB))
1241 return (FALSE);
1243 *mon = ((id & MONITOR_ID_MASK) >> 16) - 1;
1245 if (myGetDisplayInfoData ((UBYTE *)&glob->nameinfo,
1246 sizeof (struct NameInfo), DTAG_NAME, id) <= 0)
1248 str = glob->nameinfo.Name;
1249 if ((myGetDisplayInfoData ((UBYTE *)&monitorinfo, sizeof (struct MonitorInfo), DTAG_MNTR, id) > 0)
1250 && monitorinfo.Mspc)
1252 monstr = monitorinfo.Mspc->ms_Node.xln_Name;
1253 while (*monstr > '.') *str++ = ToUpper (*monstr++);
1254 *str++ = ':';
1257 DofmtArgs (str, "%ld x %ld", modewidth,
1258 glob->diminfo.Nominal.MaxY - glob->diminfo.Nominal.MinY + 1);
1260 if (propflags & DIPF_IS_HAM)
1262 StrCat (str, GetStr (glob->catalog, MSG_DASH_HAM));
1263 stdmode = FALSE;
1266 if (propflags & DIPF_IS_EXTRAHALFBRITE)
1268 StrCat (str, GetStr (glob->catalog, MSG_DASH_EHB));
1269 stdmode = FALSE;
1272 if (propflags & DIPF_IS_LACE)
1273 StrCat (str, GetStr (glob->catalog, MSG_DASH_INTERLACED));
1277 /* check property flags using mask */
1278 if ((propflags & glob->propertymask) != (glob->propertyflags & glob->propertymask))
1279 return (FALSE);
1281 /* check if depth larger than minimum depth */
1282 if (glob->diminfo.MaxDepth < glob->mindepth) return (FALSE);
1284 /* GUI modes ? */
1285 if (glob->flags & SCREQF_GUIMODES)
1287 return (stdmode && (modewidth >= 640));
1290 /* include non-standard modes ? */
1291 if (!(glob->flags & SCREQF_NONSTDMODES)) return (stdmode);
1293 return (TRUE);
1296 /****************************************************************************************/
1298 void REGARGS SetTextGad (GlobData *glob, struct Gadget *gad, char *text)
1300 if (!gad) return;
1302 myGT_SetGadgetAttrs (gad, glob->reqwin, NULL, GTTX_Text, (IPTR) text,
1303 TAG_END);
1306 /****************************************************************************************/
1308 void REGARGS SetSizeGads (GlobData *glob)
1310 if (glob->usedefwidth) glob->width = glob->defwidth;
1311 if (glob->usedefheight) glob->height = glob->defheight;
1312 if (glob->width > glob->maxwidth) glob->width = glob->maxwidth;
1313 if (glob->width < glob->minwidth) glob->width = glob->minwidth;
1315 my_SetIntegerGadget (glob->reqwin, glob->widthgad, glob->width);
1317 if (glob->height > glob->maxheight) glob->height = glob->maxheight;
1318 if (glob->height < glob->minheight) glob->height = glob->minheight;
1320 my_SetIntegerGadget (glob->reqwin, glob->heightgad, glob->height);
1323 /****************************************************************************************/
1325 LONG REGARGS IntGadgetBounds (GlobData *glob, struct Gadget *gad,
1326 LONG min, LONG max)
1328 LONG val;
1330 val = ((struct StringInfo *)gad->SpecialInfo)->LongInt;
1332 if (val > max)
1334 val = max;
1335 my_SetIntegerGadget (glob->reqwin, gad, val);
1338 if (val < min)
1340 val = min;
1341 my_SetIntegerGadget (glob->reqwin, gad, val);
1344 return (val);
1347 /****************************************************************************************/
1349 int overscantrans[] = { 0, 3, 4, 1 };
1351 /****************************************************************************************/
1353 void REGARGS GetModeDimensions (GlobData *glob)
1355 struct Rectangle *rect;
1357 if (glob->modeid != INVALID_ID)
1359 rect = &(&glob->diminfo.Nominal)[overscantrans[glob->overscantype]];
1360 glob->defwidth = rect->MaxX - rect->MinX + 1;
1361 glob->defheight = rect->MaxY - rect->MinY + 1;
1363 else glob->defwidth = glob->defheight = 0;
1366 /****************************************************************************************/
1368 void BuildColStr (char *colstr, LONG colors, ULONG id)
1370 colors = 1 << colors;
1372 if (id & HAM)
1373 colors = (colors == 128 ? 4096 : 16777216L);
1375 if (id & EXTRA_HALFBRITE )
1376 colors = 64;
1378 if (colors <= 9999)
1380 DofmtArgs (colstr, "%ld", colors);
1381 return;
1384 colors /= 1024;
1385 if (colors <= 999)
1387 DofmtArgs (colstr, "%ldK", colors);
1388 return;
1391 colors /= 1024;
1393 DofmtArgs (colstr, "%ldM", colors);
1396 /****************************************************************************************/
1398 void REGARGS UpdateDepthDisplay (GlobData *glob, int depth, ULONG id)
1400 BuildColStr (glob->currcolstr, depth, id);
1402 myGT_SetGadgetAttrs (glob->currcolgad, glob->reqwin, NULL, GTTX_Text, (IPTR) glob->currcolstr,
1403 TAG_END);
1406 /****************************************************************************************/
1408 void REGARGS UpdateDepthGad (GlobData *glob)
1410 UpdateDepthDisplay (glob, glob->depth, glob->modeid);
1412 myGT_SetGadgetAttrs (glob->depthgad, glob->reqwin, NULL, GTSL_Min, glob->currmindepth,
1413 GTSL_Max, glob->currmaxdepth,
1414 GTSL_Level, glob->depth,
1415 GA_Disabled, (glob->currmindepth == glob->currmaxdepth),
1416 TAG_END);
1419 /****************************************************************************************/
1421 void REGARGS DisplayModeAttrs (GlobData *glob)
1423 if (glob->modeid != INVALID_ID)
1425 int maxdepth = glob->diminfo.MaxDepth, mindepth = 1;
1427 if( maxdepth < 0 || maxdepth > 24 )
1429 maxdepth = 24;
1432 if (glob->depth > maxdepth || !(glob->flags & SCREQF_DEPTHGAD))
1433 glob->depth = maxdepth;
1435 /* if (glob->modeid & HAM) mindepth = maxdepth = glob->depth = 12; */
1436 /* if (glob->modeid & EXTRA_HALFBRITE) mindepth = maxdepth = glob->depth = 6; */
1438 if (glob->depthgad)
1440 if (glob->modeid & EXTRA_HALFBRITE)
1442 mindepth = maxdepth;
1445 if (glob->modeid & HAM)
1447 mindepth = 7;
1449 if (maxdepth == 6)
1450 ++maxdepth;
1453 glob->currmaxdepth = maxdepth; glob->currmindepth = mindepth;
1455 if (glob->currmaxdepth > glob->maxdepth) glob->currmaxdepth = glob->maxdepth;
1456 if (glob->currmindepth < glob->mindepth) glob->currmindepth = glob->mindepth;
1457 if (glob->depth > glob->currmaxdepth) glob->depth = glob->currmaxdepth;
1458 if (glob->depth < glob->currmindepth) glob->depth = glob->currmindepth;
1460 UpdateDepthGad (glob);
1461 BuildColStr (glob->maxcolstr, glob->currmaxdepth, glob->modeid);
1462 myGT_SetGadgetAttrs (glob->maxcolgad, glob->reqwin, NULL,
1463 GTTX_Text, (IPTR) glob->maxcolstr, TAG_END);
1465 SetSizeGads (glob);
1467 } /* if (glob->modeid != INVALID_ID) */
1470 /****************************************************************************************/