Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / libs / reqtools / filereqextra.c
blob029938dd33e2d288ca4f84feb0e6fde0223225f2
1 /*
2 Copyright © 1995-2011, 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 #ifdef __AROS__
199 /* FIXME: AROS LocaleLibrary does not yet patch RawDoFmt. So "%lD" (uppercase D) does not work yet here! */
200 Dofmt (sizestr, " %ld", &size);
201 #else
202 Dofmt (sizestr, LocaleBase ? " %lD" : " %ld", &size);
203 #endif
204 if (type == FONT)
206 StrCat (tempstr, sizestr);
207 sizestr[0] = 0;
210 else if (type == ASSIGN)
212 strcpy (sizestr, GetStr (glob->catalog, MSG_ASSIGN));
213 apen = HIGHLIGHTTEXTPEN;
215 else if (type == VOLUME)
217 if (size >= 0) Dofmt (sizestr, GetStr (glob->catalog, MSG_FULL), &size);
220 if (type == VOLUME && entry->re_VolLen)
222 len = entry->re_VolLen;
223 volname = entry->re_Name + len + 1;
225 else
226 len = strlen (tempstr);
228 sizelen = strlen (sizestr);
229 /* Cache the pixel size for each entry so
230 we only have to calculate this once. */
231 if (entry->re_SizeLenPix)
232 sizelenpix = entry->re_SizeLenPix;
233 else
235 if (sizestr[0])
236 sizelenpix = StrWidth_noloc (&glob->itxt, sizestr);
237 else
238 sizelenpix = 0;
240 if (sizelenpix < 256) entry->re_SizeLenPix = sizelenpix;
243 if (entry->re_Flags & ENTRYF_SELECTED)
245 bpen = FILLPEN;
246 if (type == glob->directory_id || type == ASSIGN)
248 apen = BACKGROUNDPEN;
249 bpen = HIGHLIGHTTEXTPEN;
251 else /* VOLUME, FILE, FONT */
252 apen = FILLTEXTPEN;
254 rectpen = bpen;
257 } /* if ((entry = glob->displaylist[i])) */
258 else
260 if (glob->lastdisplaylistnum == -1) glob->lastdisplaylistnum = i;
263 top = glob->boxtop + i * glob->entryheight;
264 SetDrMd (glob->reqrp, JAM2);
265 SetAPen (reqrp, glob->pens[rectpen]);
266 entrytop = top;
267 RectFill (reqrp, glob->boxleft, entrytop, glob->boxright, entrytop + glob->entryheight - 1);
269 if (entry)
271 SetAPen (reqrp, glob->pens[apen]);
272 SetBPen (reqrp, glob->pens[bpen]);
273 top += glob->fontbase + 1;
274 str = tempstr;
275 left = glob->boxleft + 2;
276 Move (reqrp, left, top);
278 if (volname)
280 Text (reqrp, volname, strlen (volname));
281 left += glob->maxvolwidth;
282 Move (reqrp, left, top);
285 /* Cache entry length, so we only need to calculate this once */
286 if (!entry->re_EntryLen)
288 len = TextFit (reqrp, str, len, &extent, NULL, 1,
289 glob->boxright - left - sizelenpix - 5, glob->entryheight);
290 entry->re_EntryLen = len;
292 else len = entry->re_EntryLen;
294 Text (reqrp, str, len);
296 if (sizelenpix)
298 Move (reqrp, glob->boxright - sizelenpix - 1, top);
299 Text (reqrp, sizestr, sizelen);
302 if (entry->re_Flags & ENTRYF_GHOSTED)
304 Ghost (reqrp, glob->pens[BACKGROUNDPEN],
305 glob->boxleft, entrytop,
306 glob->boxright - glob->boxleft + 1, glob->entryheight);
309 } /* if (entry) */
311 mySetWriteMask (glob->reqrp, glob->rpmask);
314 /****************************************************************************************/
316 void REGARGS PrintFiles (GlobData *glob)
318 int i;
320 glob->lastdisplaylistnum = -1;
321 for (i = 0; i < glob->numentries; i++)
323 PrintEntry (glob, i);
327 /****************************************************************************************/
329 /********************
330 * Requester entries *
331 ********************/
333 /****************************************************************************************/
335 void REGARGS ClearAndInitReqBuffer (GlobData *glob)
337 glob->buff->gotopos = glob->buff->pos = glob->buff->currentnum = glob->buff->numfiles = 0;
338 glob->firstentry = (struct ReqEntry *)AllocVecPooled(glob->buff->pool, sizeof (struct ReqEntry));
339 glob->buff->firstname = glob->firstentry;
342 /****************************************************************************************/
344 static UBYTE *REGARGS SkipDevName (UBYTE *entryname)
346 while (*entryname != ' ') entryname++;
347 while (*entryname == ' ') entryname++;
349 return (entryname);
352 /****************************************************************************************/
354 struct ReqEntry *REGARGS FindEntry (struct BufferData *buff, char *name, int size,
355 int ctype, int *pos, ULONG flags)
357 struct ReqEntry *curr, *lastname;
358 int lastcmp, cmp, i = 0, cmptype;
359 UBYTE *entryname;
361 lastname = buff->firstname;
362 curr = (struct ReqEntry *)lastname->re_Next;
363 if ((ctype <= MAX_FILE_DIRECTORY) && buff->dirsmixed)
365 cmptype = 1;
367 else
369 while (curr && curr->re_Type < ctype)
371 lastname = curr;
372 if (!(lastname->re_Flags & ENTRYF_HIDDEN)) i++;
373 curr = (struct ReqEntry *)curr->re_Next;
375 cmptype = ctype;
378 lastcmp = 1;
379 while (curr)
381 if (ctype >= 0 && curr->re_Type > cmptype) break;
382 entryname = curr->re_Name;
384 if (curr->re_Type == VOLUME && !(flags & FIND_VOLUMENAME))
386 cmp = Strnicmp (name, entryname, strlen(name));
388 else
390 if (curr->re_Type == VOLUME && (flags & FIND_VOLUMENAME))
391 entryname = SkipDevName (entryname);
392 cmp = Stricmp (name, entryname);
395 if ((cmp < 0) || (!cmp && (size < curr->re_Size))) break;
397 lastcmp = cmp;
398 lastname = curr;
400 if (!(lastname->re_Flags & ENTRYF_HIDDEN)) i++;
402 curr = (struct ReqEntry *)curr->re_Next;
405 if (pos)
407 if (lastname && (!(flags & FIND_EXACT) || !lastcmp))
409 *pos = i - 1;
410 return (lastname);
412 else
414 *pos = 0;
415 return (NULL);
419 return (lastname);
422 /****************************************************************************************/
424 struct ReqEntry *REGARGS AddEntry (GlobData *glob, struct BufferData *buff,
425 char *name, int size, int ctype)
427 struct ReqEntry *lastname, *newentry;
428 int pos, len = strlen( name ) + 1, currnum, skipflags;
429 STRPTR str, findname = name;
431 if( ctype == VOLUME )
433 findname = SkipDevName( findname );
436 lastname = FindEntry( buff, findname, ( ( ctype == FONT ) ? size : MAXINT) ,
437 ctype, &pos, FIND_VOLUMENAME );
439 str = lastname->re_Name;
441 if( str && !Stricmp( name, str ) )
443 if( ctype <= MAX_FILE_DIRECTORY )
445 lastname->re_Size = size;
446 return( lastname );
449 len = 0;
452 if( !( newentry = ( struct ReqEntry * ) AllocVecPooled(buff->pool, sizeof( struct ReqEntry ) + len ) ) )
454 return( NULL );
457 if( len )
459 str = ( STRPTR ) newentry + sizeof( struct ReqEntry );
460 strcpy( str, name );
463 newentry->re_Name = str;
464 newentry->re_Size = size;
465 newentry->re_Type = ctype;
466 newentry->re_Next = lastname->re_Next;
467 lastname->re_Next = ( struct Node * ) newentry;
469 buff->numfiles++;
470 buff->sorted = FALSE;
472 if( glob )
474 skipflags = SkipEntry( glob, newentry );
475 newentry->re_Flags |= skipflags;
477 if( skipflags != ENTRYF_HIDDEN )
479 /* If file requester keep activated itempos up to date */
480 if( ctype <= MAX_FILE_DIRECTORY )
482 if( pos < glob->selectedpos )
484 glob->selectedpos++;
488 currnum = buff->currentnum;
489 buff->currentnum++;
491 if( ctype <= MAX_FILE_DIRECTORY )
492 { /* display now ? */
493 if (currnum < glob->numentries)
495 glob->displaylist[currnum] = newentry;
497 if( !glob->quiet )
499 PrintEntry( glob, currnum );
502 else if( !glob->quiet )
504 AdjustScroller( glob );
510 return( newentry );
513 /****************************************************************************************/
515 int REGARGS EndsInDotInfo (char *str, int len)
517 if (len >= 5 && !Stricmp (&str[len-5], DOTINFOSTR)) return (TRUE);
518 return (FALSE);
521 /****************************************************************************************/
523 static int REGARGS SkipEntry (GlobData *glob, struct ReqEntry *entry)
525 char *str = entry->re_Name;
526 int len = strlen (str);
528 if (glob->reqtype == RT_FILEREQ)
530 if (entry->re_Type == glob->file_id)
532 if (!glob->wilddotinfo)
534 if (EndsInDotInfo (str, len))
536 if (glob->freq->hideinfo) return (ENTRYF_HIDDEN);
538 if (glob->matchpat[0])
540 int ret;
542 str[len-5] = '\0';
543 ret = !MatchPatternNoCase (glob->matchpat, str);
544 str[len-5] = '.';
546 return (ret ? ENTRYF_HIDDEN : 0);
551 if (glob->flags & FREQF_NOFILES) return (ENTRYF_GHOSTED);
553 if (glob->matchpat[0])
554 if (!MatchPatternNoCase (glob->matchpat, str))
555 return (ENTRYF_HIDDEN);
558 else if (glob->reqtype == RT_FONTREQ)
560 if (entry->re_Size < glob->minsize || entry->re_Size > glob->maxsize ||
561 ((glob->flags & FREQF_FIXEDWIDTH) && (entry->re_Flags & FPF_PROPORTIONAL)) ||
562 (!(glob->flags & FREQF_COLORFONTS) && (entry->re_Style & FSF_COLORFONT)))
563 return (ENTRYF_HIDDEN);
565 else
570 return (0);
573 /****************************************************************************************/
575 int REGARGS CountAllDeselect (GlobData *glob, int dirsonly)
577 struct ReqEntry *entry;
578 int count = 0;
580 for (entry = (struct ReqEntry *)glob->firstentry->re_Next;
581 entry;
582 entry = (struct ReqEntry *)entry->re_Next)
584 if (!(entry->re_Flags & ENTRYF_HIDDEN)) count++;
585 if (!dirsonly || entry->re_Type != glob->file_id)
587 if (entry->re_Flags & ENTRYF_SELECTED)
589 glob->numselected--;
590 entry->re_Flags &= ~ENTRYF_SELECTED;
595 glob->selectedpos = -1;
597 return (count);
600 /****************************************************************************************/
602 void REGARGS SelectAll (GlobData *glob, char *pattern)
604 struct ReqEntry *entry;
605 char *selpat;
606 LONG pattern_len;
608 pattern_len = strlen(pattern) * 2 + 2;
609 selpat = AllocVec(pattern_len, MEMF_PUBLIC);
610 if (selpat)
612 ParsePatternNoCase (pattern, selpat, pattern_len);
614 for (entry = (struct ReqEntry *)glob->firstentry->re_Next;
615 entry;
616 entry = (struct ReqEntry *)entry->re_Next)
618 if (!(entry->re_Flags & (ENTRYF_HIDDEN|ENTRYF_GHOSTED)))
620 if ((entry->re_Type == glob->file_id) ||
621 (entry->re_Type == glob->directory_id && (glob->flags & FREQF_SELECTDIRS)))
623 if (MatchPatternNoCase (selpat, entry->re_Name))
625 if (!(entry->re_Flags & ENTRYF_SELECTED)) glob->numselected++;
626 entry->re_Flags |= ENTRYF_SELECTED;
631 FreeVec(selpat);
634 UpdateNumSelGad (glob);
635 PrintFiles (glob);
636 my_SetStringGadget (glob->reqwin, glob->filegad, NULL);
639 /****************************************************************************************/
641 /*****************
642 * File requester *
643 *****************/
645 /****************************************************************************************/
647 void REGARGS UnLockReqLock (GlobData *glob)
649 glob->ledon = FALSE;
650 RenderLED (glob);
651 if (glob->lock) UnLock (glob->lock);
652 glob->lock = BNULL;
655 /****************************************************************************************/
657 BOOL REGARGS FindVolume (GlobData *glob, UBYTE *str, struct ReqEntry *curr)
659 struct ReqEntry *entry;
660 UBYTE *s;
662 for (entry = (struct ReqEntry *)glob->firstentry->re_Next;
663 entry;
664 entry = (struct ReqEntry *)entry->re_Next)
666 if (entry != curr && entry->re_Type == VOLUME)
668 s = entry->re_Name;
669 while (*s != ' ') s++;
670 while (*s == ' ') s++;
671 if (!Stricmp (s, str)) return (TRUE);
675 return (FALSE);
678 /****************************************************************************************/
680 static BOOL
681 IsDosVolume(struct DosList *dlist)
683 BOOL isdev = FALSE;
684 D_S( struct InfoData,id );
686 if( !dlist->dol_Task || DoPkt1( dlist->dol_Task, ACTION_DISK_INFO, (SIPTR)MKBADDR( id ) ) )
688 isdev = TRUE;
691 return (isdev);
694 /****************************************************************************************/
696 static BOOL
697 IsDosDevice( struct DosList *dlist )
699 struct FileSysStartupMsg *fssm;
700 struct DosEnvec *de;
701 BOOL isdev = FALSE;
703 /* If it`s a device, do the hard check for a filesystem */
705 if (dlist->dol_Type == DLT_DEVICE)
707 fssm = ( struct FileSysStartupMsg * )BADDR( dlist->dol_misc.dol_handler.dol_Startup );
709 if( fssm )
711 if( TypeOfMem( fssm ) && TypeOfMem( BADDR( fssm->fssm_Device ) )
712 && TypeOfMem( BADDR( fssm->fssm_Environ ) ) )
714 if( *( ( STRPTR ) BADDR( fssm->fssm_Device ) ) != 255 )
716 de = ( struct DosEnvec * ) BADDR( fssm->fssm_Environ );
718 if( de && TypeOfMem( de ) )
720 if( de->de_Surfaces && de->de_BlocksPerTrack )
722 isdev = TRUE;
728 #ifdef TASK_DEVICE
729 else
731 isdev = ( dlist->dol_Task != NULL );
733 #endif
736 return( isdev );
739 /****************************************************************************************/
741 struct DeviceEntry
743 struct DeviceEntry *next;
744 struct MsgPort *task;
745 BOOL resolved;
746 UBYTE name[ 42 ];
749 /****************************************************************************************/
751 #define SIZE_NONE ( ( ULONG ) -1 )
752 #define SIZE_CALCULATE ( ( ULONG ) -2 )
754 /****************************************************************************************/
756 static void
757 AddDisk(
758 GlobData *glob,
759 struct DeviceEntry *deventry,
760 UBYTE *devname,
761 ULONG size,
762 ULONG volreqflags )
764 struct rtVolumeEntry volentry;
765 struct ReqEntry *entry;
766 UBYTE buffer[80];
767 int i, addentry;
769 D_S( struct InfoData, infodata );
771 addentry = TRUE;
773 if( volreqflags && glob->filterhook )
775 volentry.Type = DLT_DEVICE;
776 volentry.Name = devname;
777 addentry = CallHookPkt( glob->filterhook, glob->freq, &volentry );
780 if( addentry )
782 if( size == SIZE_CALCULATE )
784 size = SIZE_NONE;
786 if( deventry->task &&
787 DoPkt1( deventry->task, ACTION_DISK_INFO, (SIPTR)MKBADDR( infodata ) ) )
789 size = ( infodata->id_NumBlocksUsed * 100 +
790 infodata->id_NumBlocks / 2 ) /
791 infodata->id_NumBlocks;
795 i = StrWidth_noloc( &glob->itxt, deventry->name ) + StrWidth_noloc( &glob->itxt, "W" );
797 if( i > glob->maxvolwidth )
799 glob->maxvolwidth = i;
802 DofmtArgs( buffer, "%s %s", devname, deventry->name );
804 if( ( entry = AddEntry( glob, glob->buff, buffer, size, VOLUME ) ) )
806 entry->re_VolLen = strlen( devname );
811 /****************************************************************************************/
813 static struct DeviceEntry *
814 AllocDevEntry( GlobData *glob, struct DosList *dlist, STRPTR name )
816 struct DeviceEntry *deventry;
818 if( ( deventry = ( struct DeviceEntry * ) AllocVecPooled(
819 glob->buff->pool, sizeof( struct DeviceEntry ) ) ) )
821 strcpy( deventry->name, name );
822 deventry->task = dlist->dol_Task;
823 deventry->resolved = FALSE;
826 return( deventry );
829 /****************************************************************************************/
831 static void
832 GetVolName( BSTR bstr, STRPTR cstr )
834 #ifdef __AROS__
835 /* In AROS, BPTR:s are handled differently on different systems
836 (to be binary compatible on Amiga) */
838 if (bstr != BNULL)
840 LONG length = AROS_BSTR_strlen(bstr);
841 LONG i; /* Loop variable */
843 for (i = 0; i < length; i++)
845 cstr[i] = AROS_BSTR_getchar(bstr, i);
848 cstr[i++] = ':';
849 cstr[i] = 0;
851 D(bug("Found volume %s\n", cstr));
853 #else
854 STRPTR str;
856 *cstr = 0;
858 if( ( str = BADDR( bstr ) ) )
860 LONG i;
862 for( i = *str++; i--; )
864 *cstr++ = *str++;
867 *cstr++ = ':';
868 *cstr = 0;
870 #endif
874 /****************************************************************************************/
876 void REGARGS
877 AddDiskNames( GlobData *glob, ULONG volreqflags )
879 struct ReqEntry *entry, *temp;
880 struct DosList *dlist;
881 struct DeviceEntry *deventry, *lastdeventry = NULL;
882 struct rtVolumeEntry volentry;
883 UBYTE /* *bstr, *cstr, */ name[ 42 ], devname[ 36 ];
884 /* WORD i; */
886 *glob->winaddr = ( APTR ) -1;
887 glob->maxvolwidth = 0;
888 dlist = LockDosList( LDF_VOLUMES | LDF_ASSIGNS | LDF_READ );
890 /* Add PROGDIR: assign is possible, just like reqtools_patch.lha
891 from Aminet (by Mikolaj Calusinski) does. */
893 if (!(volreqflags & VREQF_NOASSIGNS))
895 if (((struct Process *)FindTask(NULL))->pr_HomeDir)
897 AddEntry(glob, glob->buff, "PROGDIR:", -1, ASSIGN);
901 while( ( dlist = NextDosEntry( dlist, LDF_VOLUMES | LDF_ASSIGNS | LDF_READ ) ) )
903 GetVolName(dlist->dol_Name, name);
904 if (dlist->dol_Type == DLT_VOLUME)
906 if (IsDosVolume(dlist) && !(volreqflags & VREQF_NODISKS))
908 if ((deventry = AllocDevEntry(glob, dlist, name)))
910 deventry->next = lastdeventry;
911 lastdeventry = deventry;
915 else if (dlist->dol_Type == DLT_DIRECTORY ||
916 dlist->dol_Type == DLT_NONBINDING)
918 if (!(volreqflags & VREQF_NOASSIGNS))
920 AddEntry(glob, glob->buff, name, -1, ASSIGN);
925 /* Append device names to volumes */
926 dlist = LockDosList( LDF_DEVICES | LDF_READ );
928 while( ( dlist = NextDosEntry( dlist, LDF_DEVICES | LDF_READ ) ) )
930 BOOL devmatch;
932 deventry = lastdeventry;
933 devmatch = FALSE;
935 while( deventry )
937 devmatch |= ( deventry->task == dlist->dol_Task );
938 if( !deventry->resolved && deventry->task && ( deventry->task == dlist->dol_Task ) )
940 GetVolName( dlist->dol_Name, devname );
941 AddDisk( glob, deventry, devname, SIZE_CALCULATE, volreqflags );
942 deventry->resolved = TRUE;
945 deventry = deventry->next;
948 if( !devmatch && ( volreqflags & VREQF_ALLDISKS ) &&
949 !( volreqflags & VREQF_NODISKS ) && IsDosDevice( dlist ) )
951 /* Device seems to be a DOS disk device, and it didn't belong
952 * to a volume, and we should really show all devices in a
953 * volume requester.
955 GetVolName( dlist->dol_Name, devname );
957 if( ( deventry = AllocDevEntry( glob, dlist, "-" ) ) )
959 deventry->next = lastdeventry;
960 lastdeventry = deventry;
961 AddDisk( glob, deventry, devname, SIZE_NONE, volreqflags );
962 deventry->resolved = TRUE;
967 UnLockDosList( LDF_DEVICES | LDF_READ );
968 UnLockDosList( LDF_VOLUMES | LDF_ASSIGNS | LDF_READ );
970 /* Free temp volume list (and add remaining names if ALLDISKS is on) */
971 while( ( deventry = lastdeventry ) )
973 if( !deventry->resolved /* && ( !volreqflags || ( volreqflags & VREQF_ALLDISKS ) ) */ )
975 AddDisk( glob, deventry, "-", SIZE_CALCULATE, volreqflags );
978 lastdeventry = deventry->next;
979 FreeVecPooled( glob->buff->pool, deventry );
982 /* If volume requester filter assigns */
983 if( volreqflags && glob->filterhook )
985 entry = glob->buff->firstname;
987 while( ( temp = entry ) )
989 entry = ( struct ReqEntry * ) entry->re_Next;
991 if( !entry )
993 break;
996 if( entry->re_Type == ASSIGN )
998 volentry.Type = DLT_DIRECTORY;
999 volentry.Name = entry->re_Name;
1001 if( !CallHookPkt( glob->filterhook, glob->freq, &volentry ) )
1003 temp->re_Next = entry->re_Next;
1004 FreeVecPooled( glob->buff->pool, entry );
1005 entry = temp;
1006 glob->buff->currentnum--;
1012 *glob->winaddr = glob->reqwin;
1015 /****************************************************************************************/
1017 BOOL REGARGS FindCurrentPos (GlobData *glob, char *name, int size, int ctype)
1019 BOOL success;
1021 MarkHidden (glob);
1022 success = FindEntry (glob->buff, name, size, ctype, ( int * ) &glob->buff->pos, FIND_EXACT) ? TRUE : FALSE;
1023 glob->buff->gotopos = glob->buff->pos;
1025 return (success);
1028 /****************************************************************************************/
1030 void REGARGS NewDir (GlobData *glob)
1032 UnLockReqLock (glob);
1033 SetWindowTitles (glob->reqwin, glob->title, (char *)~0);
1034 FreeReqBuffer (glob->req);
1035 ClearDisplayList (glob);
1036 glob->newdir = TRUE;
1037 glob->clicked = ~0;
1039 if (glob->freq)
1041 SetFileDirMode (glob->buff, glob->flags);
1042 glob->file_id = glob->buff->file_id;
1043 glob->directory_id = glob->buff->directory_id;
1047 /****************************************************************************************/
1049 void REGARGS ShowDisks(GlobData *glob)
1052 if (!glob->disks)
1054 UnLockReqLock (glob);
1055 FreeReqBuffer (glob->req);
1056 ClearAndInitReqBuffer (glob);
1057 glob->exnext = FALSE;
1058 glob->disks = TRUE;
1059 AddDiskNames (glob, glob->volumerequest);
1060 AdjustScroller (glob);
1061 UpdateDisplayList (glob);
1062 PrintFiles (glob);
1063 glob->buff->sorted = TRUE;
1064 glob->selectedpos = -1;
1068 /****************************************************************************************/
1070 void REGARGS UpdateNumSelGad (GlobData *glob)
1072 int top;
1073 char str[6];
1075 if (glob->numselectedgad)
1077 Dofmt (str, "%4ld", &glob->numselected);
1079 SetAPen (glob->reqrp, glob->pens[TEXTPEN]);
1080 SetBPen (glob->reqrp, glob->pens[BACKGROUNDPEN]);
1081 SetDrMd (glob->reqrp, JAM2);
1083 top = glob->numselectedgad->TopEdge + 3;
1085 Move (glob->reqrp, glob->numselectedgad->LeftEdge + glob->numselectedoff + 8,
1086 top + glob->reqfont->tf_Baseline);
1087 Text (glob->reqrp, str, 4);
1089 SetDrMd (glob->reqrp, JAM2);
1090 SetAPen (glob->reqrp, glob->pens[BACKGROUNDPEN]);
1092 RectFill (glob->reqrp, glob->reqrp->cp_x,
1093 top,
1094 glob->numselectedgad->LeftEdge + glob->numselectedgad->Width - 3,
1095 top + glob->fontheight - 1);
1099 /****************************************************************************************/
1101 /*****************
1102 * Font requester *
1103 *****************/
1105 /****************************************************************************************/
1107 static struct Region *MyInstallRegion (struct Window *win, struct Region *reg, int refresh)
1109 struct Region *oldregion;
1111 LockLayerInfo(&win->WScreen->LayerInfo);
1113 if (refresh) GT_EndRefresh (win, FALSE);
1115 oldregion = InstallClipRegion (win->WLayer, reg);
1116 if (refresh) GT_BeginRefresh (win);
1118 UnlockLayerInfo(&win->WScreen->LayerInfo);
1120 return (oldregion);
1123 /****************************************************************************************/
1125 void REGARGS ShowFontSample (GlobData *glob, int refresh, int dowait)
1127 struct DiskfontBase *DiskfontBase = glob->diskfontbase;
1128 struct TextFont *font;
1129 struct Rectangle rect;
1130 struct Region *oldregion, *region;
1131 char *message = "0123 aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ";
1132 UWORD *cmap = NULL;
1133 ULONG style = glob->fontstyle, count = glob->colcount;
1134 APTR winlock = NULL;
1136 if (dowait) winlock = rtLockWindow (glob->reqwin);
1138 if (glob->flags & FREQF_SCALE)
1139 glob->fontreq->Attr.ta_Flags &= ~FPF_DESIGNED;
1141 if (!(font = OpenDiskFont (&glob->fontreq->Attr)))
1143 font = glob->reqfont;
1144 message = GetStr (glob->catalog, MSG_COULDNT_OPEN_FONT);
1145 style = 0;
1148 rect.MinX = glob->fontdisplayleft;
1149 rect.MaxX = glob->fontdisplayright;
1150 rect.MinY = glob->fontdisplaytop;
1151 rect.MaxY = glob->fontdisplaytop + glob->sampleheight - 1;
1153 if ( ( region = NewRegion() ) )
1155 OrRectRegion (region, &rect);
1157 oldregion = MyInstallRegion (glob->reqwin, region, refresh);
1159 SetFont (glob->reqrp, font);
1160 SetSoftStyle (glob->reqrp, style, ~0);
1161 SetAPen (glob->reqrp, glob->pens[TEXTPEN]);
1162 SetBPen (glob->reqrp, glob->pens[BACKGROUNDPEN]);
1164 if (font->tf_Style & FSF_COLORFONT)
1166 struct ColorFontColors *cfc;
1168 cfc = ((struct ColorTextFont *)font)->ctf_ColorFontColors;
1169 if (cfc)
1171 count = cfc->cfc_Count;
1172 cmap = cfc->cfc_ColorTable;
1176 if (glob->flags & FREQF_CHANGEPALETTE)
1178 if (cmap) LoadRGB4 (glob->vp, cmap, count);
1179 else LoadCMap (glob->vp, glob->colormap);
1182 if (!refresh) SetRast (glob->reqrp, glob->pens[BACKGROUNDPEN]);
1184 Move (glob->reqrp, glob->fontdisplayleft,
1185 glob->fontdisplaytop + (glob->sampleheight - font->tf_YSize) / 2
1186 + font->tf_Baseline);
1187 Text (glob->reqrp, message, strlen(message));
1189 MyInstallRegion (glob->reqwin, oldregion, refresh);
1190 DisposeRegion (region);
1192 SetFont (glob->reqrp, glob->reqfont);
1193 SetSoftStyle (glob->reqrp, 0, ~0);
1196 /*endshowsample:*/
1197 CloseFont (font);
1198 if (dowait) rtUnlockWindow (glob->reqwin, winlock);
1201 /****************************************************************************************/
1203 /***********************
1204 * ScreenMode requester *
1205 ***********************/
1207 /****************************************************************************************/
1209 ULONG ASM myGetDisplayInfoData (
1210 OPT_REGPARAM(a1, UBYTE *, buf),
1211 OPT_REGPARAM(d0, unsigned long, size),
1212 OPT_REGPARAM(d1, unsigned long, tagID),
1213 OPT_REGPARAM(d2, unsigned long, displayID))
1215 return (GetDisplayInfoData (FindDisplayInfo (displayID),
1216 buf, size, tagID, displayID));
1219 /****************************************************************************************/
1221 int REGARGS GetModeData (GlobData *glob, ULONG id, int *mon)
1223 struct MonitorInfo monitorinfo;
1224 ULONG propflags;
1225 int modewidth, stdmode = TRUE;
1226 char *str, *monstr;
1228 if ((myGetDisplayInfoData ((UBYTE *)&glob->diminfo,
1229 sizeof (struct DimensionInfo), DTAG_DIMS, id) <= 0) ||
1230 (myGetDisplayInfoData ((UBYTE *)&glob->dispinfo,
1231 sizeof (struct DisplayInfo), DTAG_DISP, id) <= 0))
1233 return (FALSE);
1236 modewidth = glob->diminfo.Nominal.MaxX - glob->diminfo.Nominal.MinX + 1;
1237 propflags = glob->dispinfo.PropertyFlags;
1239 if ((glob->flags & SCREQF_GUIMODES) && !(propflags & DIPF_IS_WB))
1240 return (FALSE);
1242 *mon = ((id & MONITOR_ID_MASK) >> 16) - 1;
1244 if (myGetDisplayInfoData ((UBYTE *)&glob->nameinfo,
1245 sizeof (struct NameInfo), DTAG_NAME, id) <= 0)
1247 str = glob->nameinfo.Name;
1248 if ((myGetDisplayInfoData ((UBYTE *)&monitorinfo, sizeof (struct MonitorInfo), DTAG_MNTR, id) > 0)
1249 && monitorinfo.Mspc)
1251 monstr = monitorinfo.Mspc->ms_Node.xln_Name;
1252 while (*monstr > '.') *str++ = ToUpper (*monstr++);
1253 *str++ = ':';
1256 DofmtArgs (str, "%ld x %ld", modewidth,
1257 glob->diminfo.Nominal.MaxY - glob->diminfo.Nominal.MinY + 1);
1259 if (propflags & DIPF_IS_HAM)
1261 StrCat (str, GetStr (glob->catalog, MSG_DASH_HAM));
1262 stdmode = FALSE;
1265 if (propflags & DIPF_IS_EXTRAHALFBRITE)
1267 StrCat (str, GetStr (glob->catalog, MSG_DASH_EHB));
1268 stdmode = FALSE;
1271 if (propflags & DIPF_IS_LACE)
1272 StrCat (str, GetStr (glob->catalog, MSG_DASH_INTERLACED));
1276 /* check property flags using mask */
1277 if ((propflags & glob->propertymask) != (glob->propertyflags & glob->propertymask))
1278 return (FALSE);
1280 /* check if depth larger than minimum depth */
1281 if (glob->diminfo.MaxDepth < glob->mindepth) return (FALSE);
1283 /* GUI modes ? */
1284 if (glob->flags & SCREQF_GUIMODES)
1286 return (stdmode && (modewidth >= 640));
1289 /* include non-standard modes ? */
1290 if (!(glob->flags & SCREQF_NONSTDMODES)) return (stdmode);
1292 return (TRUE);
1295 /****************************************************************************************/
1297 void REGARGS SetTextGad (GlobData *glob, struct Gadget *gad, char *text)
1299 if (!gad) return;
1301 myGT_SetGadgetAttrs (gad, glob->reqwin, NULL, GTTX_Text, (IPTR) text,
1302 TAG_END);
1305 /****************************************************************************************/
1307 void REGARGS SetSizeGads (GlobData *glob)
1309 if (glob->usedefwidth) glob->width = glob->defwidth;
1310 if (glob->usedefheight) glob->height = glob->defheight;
1311 if (glob->width > glob->maxwidth) glob->width = glob->maxwidth;
1312 if (glob->width < glob->minwidth) glob->width = glob->minwidth;
1314 my_SetIntegerGadget (glob->reqwin, glob->widthgad, glob->width);
1316 if (glob->height > glob->maxheight) glob->height = glob->maxheight;
1317 if (glob->height < glob->minheight) glob->height = glob->minheight;
1319 my_SetIntegerGadget (glob->reqwin, glob->heightgad, glob->height);
1322 /****************************************************************************************/
1324 LONG REGARGS IntGadgetBounds (GlobData *glob, struct Gadget *gad,
1325 LONG min, LONG max)
1327 LONG val;
1329 val = ((struct StringInfo *)gad->SpecialInfo)->LongInt;
1331 if (val > max)
1333 val = max;
1334 my_SetIntegerGadget (glob->reqwin, gad, val);
1337 if (val < min)
1339 val = min;
1340 my_SetIntegerGadget (glob->reqwin, gad, val);
1343 return (val);
1346 /****************************************************************************************/
1348 int overscantrans[] = { 0, 3, 4, 1 };
1350 /****************************************************************************************/
1352 void REGARGS GetModeDimensions (GlobData *glob)
1354 struct Rectangle *rect;
1356 if (glob->modeid != INVALID_ID)
1358 rect = &(&glob->diminfo.Nominal)[overscantrans[glob->overscantype]];
1359 glob->defwidth = rect->MaxX - rect->MinX + 1;
1360 glob->defheight = rect->MaxY - rect->MinY + 1;
1362 else glob->defwidth = glob->defheight = 0;
1365 /****************************************************************************************/
1367 void BuildColStr (char *colstr, LONG colors, ULONG id)
1369 colors = 1 << colors;
1371 if (id & HAM)
1372 colors = (colors == 128 ? 4096 : 16777216L);
1374 if (id & EXTRA_HALFBRITE )
1375 colors = 64;
1377 if (colors <= 9999)
1379 DofmtArgs (colstr, "%ld", colors);
1380 return;
1383 colors /= 1024;
1384 if (colors <= 999)
1386 DofmtArgs (colstr, "%ldK", colors);
1387 return;
1390 colors /= 1024;
1392 DofmtArgs (colstr, "%ldM", colors);
1395 /****************************************************************************************/
1397 void REGARGS UpdateDepthDisplay (GlobData *glob, int depth, ULONG id)
1399 BuildColStr (glob->currcolstr, depth, id);
1401 myGT_SetGadgetAttrs (glob->currcolgad, glob->reqwin, NULL, GTTX_Text, (IPTR) glob->currcolstr,
1402 TAG_END);
1405 /****************************************************************************************/
1407 void REGARGS UpdateDepthGad (GlobData *glob)
1409 UpdateDepthDisplay (glob, glob->depth, glob->modeid);
1411 myGT_SetGadgetAttrs (glob->depthgad, glob->reqwin, NULL, GTSL_Min, glob->currmindepth,
1412 GTSL_Max, glob->currmaxdepth,
1413 GTSL_Level, glob->depth,
1414 GA_Disabled, (glob->currmindepth == glob->currmaxdepth),
1415 TAG_END);
1418 /****************************************************************************************/
1420 void REGARGS DisplayModeAttrs (GlobData *glob)
1422 if (glob->modeid != INVALID_ID)
1424 int maxdepth = glob->diminfo.MaxDepth, mindepth = 1;
1426 if( maxdepth < 0 || maxdepth > 24 )
1428 maxdepth = 24;
1431 if (glob->depth > maxdepth || !(glob->flags & SCREQF_DEPTHGAD))
1432 glob->depth = maxdepth;
1434 /* if (glob->modeid & HAM) mindepth = maxdepth = glob->depth = 12; */
1435 /* if (glob->modeid & EXTRA_HALFBRITE) mindepth = maxdepth = glob->depth = 6; */
1437 if (glob->depthgad)
1439 if (glob->modeid & EXTRA_HALFBRITE)
1441 mindepth = maxdepth;
1444 if (glob->modeid & HAM)
1446 mindepth = 7;
1448 if (maxdepth == 6)
1449 ++maxdepth;
1452 glob->currmaxdepth = maxdepth; glob->currmindepth = mindepth;
1454 if (glob->currmaxdepth > glob->maxdepth) glob->currmaxdepth = glob->maxdepth;
1455 if (glob->currmindepth < glob->mindepth) glob->currmindepth = glob->mindepth;
1456 if (glob->depth > glob->currmaxdepth) glob->depth = glob->currmaxdepth;
1457 if (glob->depth < glob->currmindepth) glob->depth = glob->currmindepth;
1459 UpdateDepthGad (glob);
1460 BuildColStr (glob->maxcolstr, glob->currmaxdepth, glob->modeid);
1461 myGT_SetGadgetAttrs (glob->maxcolgad, glob->reqwin, NULL,
1462 GTTX_Text, (IPTR) glob->maxcolstr, TAG_END);
1464 SetSizeGads (glob);
1466 } /* if (glob->modeid != INVALID_ID) */
1469 /****************************************************************************************/