Updated PCI IDs to latest snapshot.
[tangerine.git] / workbench / libs / reqtools / filereqextra.c
blobe20ea4e14772fa5abeee9560758ca01098dca895
1 /*
2 Copyright © 1995-2007, 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"
19 #ifdef __AROS__
21 #define DEBUG 0
22 #include <aros/debug.h>
24 #else
26 #define D(x)
28 #endif
31 /****************************************************************************************/
33 extern struct LocaleBase *LocaleBase;
35 /****************************************************************************************/
37 static void REGARGS MarkHidden (GlobData *);
38 static int REGARGS SkipEntry (GlobData *, struct ReqEntry *);
40 /****************************************************************************************/
42 /********************
43 * Requester Display *
44 ********************/
46 /****************************************************************************************/
48 void REGARGS AdjustScroller (GlobData *glob)
50 myGT_SetGadgetAttrs (glob->scrollergad, glob->reqwin, NULL, GTSC_Total, glob->buff->currentnum,
51 GTSC_Top, glob->buff->gotopos,
52 TAG_END);
55 /****************************************************************************************/
57 void REGARGS ClearFilesRect (GlobData *glob)
59 SetAPen (glob->reqrp, glob->pens[BACKGROUNDPEN]);
60 mySetWriteMask (glob->reqrp, glob->entrymask);
61 RectFill (glob->reqrp, glob->boxleft, glob->boxtop - 1, glob->boxright,
62 glob->boxtop + glob->boxheight);
63 mySetWriteMask (glob->reqrp, glob->rpmask);
66 /****************************************************************************************/
68 void REGARGS ScrollerMoved (GlobData *glob, int code)
70 glob->buff->gotopos = code;
71 if (!glob->buff->sorted)
73 glob->buff->pos = glob->buff->gotopos;
74 UpdateDisplayList (glob);
75 PrintFiles (glob);
76 AdjustScroller (glob);
77 glob->buff->sorted = TRUE;
81 /****************************************************************************************/
83 static void REGARGS MarkHidden (GlobData *glob)
85 struct ReqEntry *entry;
86 int skipflags;
88 if (glob->nodir) return;
90 for (entry = (struct ReqEntry *)glob->firstentry->re_Next;
91 entry;
92 entry = (struct ReqEntry *)entry->re_Next)
94 entry->re_Flags &= ~(ENTRYF_HIDDEN|ENTRYF_GHOSTED);
95 if ((skipflags = SkipEntry (glob, entry))) entry->re_Flags |= skipflags;
99 /****************************************************************************************/
101 void REGARGS RethinkReqDisplay (GlobData *glob)
103 int num;
105 if (glob->nodir) return;
107 MarkHidden (glob);
108 num = (glob->buff->currentnum = CountAllDeselect (glob, FALSE))
109 - glob->numentries;
110 if (num < 0) glob->buff->gotopos = glob->buff->pos = 0;
111 else if (glob->buff->pos > num) glob->buff->gotopos = glob->buff->pos = num;
113 AdjustScroller (glob);
114 UpdateDisplayList (glob);
115 PrintFiles (glob);
118 /****************************************************************************************/
120 void REGARGS ClearDisplayList (GlobData *glob)
122 memset (glob->displaylist, 0, 50*4);
125 /****************************************************************************************/
127 void REGARGS UpdateDisplayList (GlobData *glob)
129 struct ReqEntry *entry;
130 int i;
132 i = 0;
134 if (glob->buff->currentnum &&
135 (entry = (struct ReqEntry *)glob->firstentry->re_Next))
137 while (i < glob->buff->pos)
139 if (!(entry->re_Flags & ENTRYF_HIDDEN))
141 i++;
144 entry = (struct ReqEntry *)entry->re_Next;
148 for (i = 0; entry && (i < glob->numentries);
149 entry = (struct ReqEntry *)entry->re_Next)
151 if (!(entry->re_Flags & ENTRYF_HIDDEN))
153 glob->displaylist[i++] = entry;
158 while (i < glob->numentries)
160 glob->displaylist[i++] = NULL;
164 /****************************************************************************************/
166 static UWORD GhostPattern[] = { 0x4444, 0x1111 };
168 /****************************************************************************************/
170 /* Apply a ghosting pattern to a given rectangle in a rastport */
171 static void REGARGS Ghost (struct RastPort *rp, UWORD pen, UWORD x, UWORD y, UWORD w, UWORD h)
173 SetAPen (rp, pen);
174 SetBPen (rp, pen);
175 SetDrMd (rp, JAM1);
176 SetAfPt (rp, GhostPattern, 1);
177 RectFill (rp, x, y, x + w - 1, y + h - 1);
178 SetAfPt (rp, NULL, 0);
181 /****************************************************************************************/
183 void REGARGS PrintEntry (GlobData *glob, int i)
185 struct TextExtent extent;
186 struct ReqEntry *entry;
187 struct RastPort *reqrp = glob->reqrp;
188 char sizestr[16], tempstr[108], *volname = NULL, *str;
189 int apen = 0, bpen = 0, top, len = 0, sizelen = 0, sizelenpix = 0, type, rectpen, left, entrytop;
190 LONG size;
192 mySetWriteMask (glob->reqrp, glob->entrymask);
193 rectpen = BACKGROUNDPEN;
195 if ((entry = glob->displaylist[i]))
197 strcpy (tempstr, entry->re_Name);
198 apen = TEXTPEN; bpen = BACKGROUNDPEN;
199 sizestr[0] = 0;
200 size = entry->re_Size;
201 type = entry->re_Type;
202 if (type == glob->directory_id)
204 strcpy (sizestr, GetStr (glob->catalog, MSG_DRAWER));
205 apen = HIGHLIGHTTEXTPEN;
207 else if (type == FONT || (type == glob->file_id))
209 #ifdef __AROS__
210 #warning AROS LocaleLibrary does not yet patch RawDoFmt. So "%lD" (uppercase D) does not work yet here!
211 Dofmt (sizestr, " %ld", &size);
212 #else
213 Dofmt (sizestr, LocaleBase ? " %lD" : " %ld", &size);
214 #endif
215 if (type == FONT)
217 StrCat (tempstr, sizestr);
218 sizestr[0] = 0;
221 else if (type == ASSIGN)
223 strcpy (sizestr, GetStr (glob->catalog, MSG_ASSIGN));
224 apen = HIGHLIGHTTEXTPEN;
226 else if (type == VOLUME)
228 if (size >= 0) Dofmt (sizestr, GetStr (glob->catalog, MSG_FULL), &size);
231 if (type == VOLUME && entry->re_VolLen)
233 len = entry->re_VolLen;
234 volname = entry->re_Name + len + 1;
236 else
237 len = strlen (tempstr);
239 sizelen = strlen (sizestr);
240 /* Cache the pixel size for each entry so
241 we only have to calculate this once. */
242 if (entry->re_SizeLenPix)
243 sizelenpix = entry->re_SizeLenPix;
244 else
246 if (sizestr[0])
247 sizelenpix = StrWidth_noloc (&glob->itxt, sizestr);
248 else
249 sizelenpix = 0;
251 if (sizelenpix < 256) entry->re_SizeLenPix = sizelenpix;
254 if (entry->re_Flags & ENTRYF_SELECTED)
256 bpen = FILLPEN;
257 if (type == glob->directory_id || type == ASSIGN)
259 apen = BACKGROUNDPEN;
260 bpen = HIGHLIGHTTEXTPEN;
262 else /* VOLUME, FILE, FONT */
263 apen = FILLTEXTPEN;
265 rectpen = bpen;
268 } /* if ((entry = glob->displaylist[i])) */
269 else
271 if (glob->lastdisplaylistnum == -1) glob->lastdisplaylistnum = i;
274 top = glob->boxtop + i * glob->entryheight;
275 SetDrMd (glob->reqrp, JAM2);
276 SetAPen (reqrp, glob->pens[rectpen]);
277 entrytop = top;
278 RectFill (reqrp, glob->boxleft, entrytop, glob->boxright, entrytop + glob->entryheight - 1);
280 if (entry)
282 SetAPen (reqrp, glob->pens[apen]);
283 SetBPen (reqrp, glob->pens[bpen]);
284 top += glob->fontbase + 1;
285 str = tempstr;
286 left = glob->boxleft + 2;
287 Move (reqrp, left, top);
289 if (volname)
291 Text (reqrp, volname, strlen (volname));
292 left += glob->maxvolwidth;
293 Move (reqrp, left, top);
296 /* Cache entry length, so we only need to calculate this once */
297 if (!entry->re_EntryLen)
299 len = TextFit (reqrp, str, len, &extent, NULL, 1,
300 glob->boxright - left - sizelenpix - 5, glob->entryheight);
301 entry->re_EntryLen = len;
303 else len = entry->re_EntryLen;
305 Text (reqrp, str, len);
307 if (sizelenpix)
309 Move (reqrp, glob->boxright - sizelenpix - 1, top);
310 Text (reqrp, sizestr, sizelen);
313 if (entry->re_Flags & ENTRYF_GHOSTED)
315 Ghost (reqrp, glob->pens[BACKGROUNDPEN],
316 glob->boxleft, entrytop,
317 glob->boxright - glob->boxleft + 1, glob->entryheight);
320 } /* if (entry) */
322 mySetWriteMask (glob->reqrp, glob->rpmask);
325 /****************************************************************************************/
327 void REGARGS PrintFiles (GlobData *glob)
329 int i;
331 glob->lastdisplaylistnum = -1;
332 for (i = 0; i < glob->numentries; i++)
334 PrintEntry (glob, i);
338 /****************************************************************************************/
340 /********************
341 * Requester entries *
342 ********************/
344 /****************************************************************************************/
346 void REGARGS ClearAndInitReqBuffer (GlobData *glob)
348 glob->buff->gotopos = glob->buff->pos = glob->buff->currentnum = glob->buff->numfiles = 0;
349 glob->firstentry = (struct ReqEntry *)AllocVecPooled(glob->buff->pool, sizeof (struct ReqEntry));
350 glob->buff->firstname = glob->firstentry;
353 /****************************************************************************************/
355 static UBYTE *REGARGS SkipDevName (UBYTE *entryname)
357 while (*entryname != ' ') entryname++;
358 while (*entryname == ' ') entryname++;
360 return (entryname);
363 /****************************************************************************************/
365 struct ReqEntry *REGARGS FindEntry (struct BufferData *buff, char *name, int size,
366 int ctype, int *pos, ULONG flags)
368 struct ReqEntry *curr, *lastname;
369 int lastcmp, cmp, i = 0, cmptype;
370 UBYTE *entryname;
372 lastname = buff->firstname;
373 curr = (struct ReqEntry *)lastname->re_Next;
374 if ((ctype <= MAX_FILE_DIRECTORY) && buff->dirsmixed)
376 cmptype = 1;
378 else
380 while (curr && curr->re_Type < ctype)
382 lastname = curr;
383 if (!(lastname->re_Flags & ENTRYF_HIDDEN)) i++;
384 curr = (struct ReqEntry *)curr->re_Next;
386 cmptype = ctype;
389 lastcmp = 1;
390 while (curr)
392 if (ctype >= 0 && curr->re_Type > cmptype) break;
393 entryname = curr->re_Name;
395 if (curr->re_Type == VOLUME && !(flags & FIND_VOLUMENAME))
397 cmp = Strnicmp (name, entryname, strlen(name));
399 else
401 if (curr->re_Type == VOLUME && (flags & FIND_VOLUMENAME))
402 entryname = SkipDevName (entryname);
403 cmp = Stricmp (name, entryname);
406 if ((cmp < 0) || (!cmp && (size < curr->re_Size))) break;
408 lastcmp = cmp;
409 lastname = curr;
411 if (!(lastname->re_Flags & ENTRYF_HIDDEN)) i++;
413 curr = (struct ReqEntry *)curr->re_Next;
416 if (pos)
418 if (lastname && (!(flags & FIND_EXACT) || !lastcmp))
420 *pos = i - 1;
421 return (lastname);
423 else
425 *pos = 0;
426 return (NULL);
430 return (lastname);
433 /****************************************************************************************/
435 struct ReqEntry *REGARGS AddEntry (GlobData *glob, struct BufferData *buff,
436 char *name, int size, int ctype)
438 struct ReqEntry *lastname, *newentry;
439 int pos, len = strlen( name ) + 1, currnum, skipflags;
440 STRPTR str, findname = name;
442 if( ctype == VOLUME )
444 findname = SkipDevName( findname );
447 lastname = FindEntry( buff, findname, ( ( ctype == FONT ) ? size : MAXINT) ,
448 ctype, &pos, FIND_VOLUMENAME );
450 str = lastname->re_Name;
452 if( str && !Stricmp( name, str ) )
454 if( ctype <= MAX_FILE_DIRECTORY )
456 lastname->re_Size = size;
457 return( lastname );
460 len = 0;
463 if( !( newentry = ( struct ReqEntry * ) AllocVecPooled(buff->pool, sizeof( struct ReqEntry ) + len ) ) )
465 return( NULL );
468 if( len )
470 str = ( STRPTR ) newentry + sizeof( struct ReqEntry );
471 strcpy( str, name );
474 newentry->re_Name = str;
475 newentry->re_Size = size;
476 newentry->re_Type = ctype;
477 newentry->re_Next = lastname->re_Next;
478 lastname->re_Next = ( struct Node * ) newentry;
480 buff->numfiles++;
481 buff->sorted = FALSE;
483 if( glob )
485 skipflags = SkipEntry( glob, newentry );
486 newentry->re_Flags |= skipflags;
488 if( skipflags != ENTRYF_HIDDEN )
490 /* If file requester keep activated itempos up to date */
491 if( ctype <= MAX_FILE_DIRECTORY )
493 if( pos < glob->selectedpos )
495 glob->selectedpos++;
499 currnum = buff->currentnum;
500 buff->currentnum++;
502 if( ctype <= MAX_FILE_DIRECTORY )
503 { /* display now ? */
504 if (currnum < glob->numentries)
506 glob->displaylist[currnum] = newentry;
508 if( !glob->quiet )
510 PrintEntry( glob, currnum );
513 else if( !glob->quiet )
515 AdjustScroller( glob );
521 return( newentry );
524 /****************************************************************************************/
526 int REGARGS EndsInDotInfo (char *str, int len)
528 if (len >= 5 && !Stricmp (&str[len-5], DOTINFOSTR)) return (TRUE);
529 return (FALSE);
532 /****************************************************************************************/
534 static int REGARGS SkipEntry (GlobData *glob, struct ReqEntry *entry)
536 char *str = entry->re_Name;
537 int len = strlen (str);
539 if (glob->reqtype == RT_FILEREQ)
541 if (entry->re_Type == glob->file_id)
543 if (!glob->wilddotinfo)
545 if (EndsInDotInfo (str, len))
547 if (glob->freq->hideinfo) return (ENTRYF_HIDDEN);
549 if (glob->matchpat[0])
551 int ret;
553 str[len-5] = '\0';
554 ret = !MatchPatternNoCase (glob->matchpat, str);
555 str[len-5] = '.';
557 return (ret ? ENTRYF_HIDDEN : 0);
562 if (glob->flags & FREQF_NOFILES) return (ENTRYF_GHOSTED);
564 if (glob->matchpat[0])
565 if (!MatchPatternNoCase (glob->matchpat, str))
566 return (ENTRYF_HIDDEN);
569 else if (glob->reqtype == RT_FONTREQ)
571 if (entry->re_Size < glob->minsize || entry->re_Size > glob->maxsize ||
572 ((glob->flags & FREQF_FIXEDWIDTH) && (entry->re_Flags & FPF_PROPORTIONAL)) ||
573 (!(glob->flags & FREQF_COLORFONTS) && (entry->re_Style & FSF_COLORFONT)))
574 return (ENTRYF_HIDDEN);
576 else
581 return (0);
584 /****************************************************************************************/
586 int REGARGS CountAllDeselect (GlobData *glob, int dirsonly)
588 struct ReqEntry *entry;
589 int count = 0;
591 for (entry = (struct ReqEntry *)glob->firstentry->re_Next;
592 entry;
593 entry = (struct ReqEntry *)entry->re_Next)
595 if (!(entry->re_Flags & ENTRYF_HIDDEN)) count++;
596 if (!dirsonly || entry->re_Type != glob->file_id)
598 if (entry->re_Flags & ENTRYF_SELECTED)
600 glob->numselected--;
601 entry->re_Flags &= ~ENTRYF_SELECTED;
606 glob->selectedpos = -1;
608 return (count);
611 /****************************************************************************************/
613 void REGARGS SelectAll (GlobData *glob, char *pattern)
615 struct ReqEntry *entry;
616 char *selpat;
617 LONG pattern_len;
619 pattern_len = strlen(pattern) * 2 + 2;
620 selpat = AllocVec(pattern_len, MEMF_PUBLIC);
621 if (selpat)
623 ParsePatternNoCase (pattern, selpat, pattern_len);
625 for (entry = (struct ReqEntry *)glob->firstentry->re_Next;
626 entry;
627 entry = (struct ReqEntry *)entry->re_Next)
629 if (!(entry->re_Flags & (ENTRYF_HIDDEN|ENTRYF_GHOSTED)))
631 if ((entry->re_Type == glob->file_id) ||
632 (entry->re_Type == glob->directory_id && (glob->flags & FREQF_SELECTDIRS)))
634 if (MatchPatternNoCase (selpat, entry->re_Name))
636 if (!(entry->re_Flags & ENTRYF_SELECTED)) glob->numselected++;
637 entry->re_Flags |= ENTRYF_SELECTED;
642 FreeVec(selpat);
645 UpdateNumSelGad (glob);
646 PrintFiles (glob);
647 my_SetStringGadget (glob->reqwin, glob->filegad, NULL);
650 /****************************************************************************************/
652 /*****************
653 * File requester *
654 *****************/
656 /****************************************************************************************/
658 void REGARGS UnLockReqLock (GlobData *glob)
660 glob->ledon = FALSE;
661 RenderLED (glob);
662 if (glob->lock) UnLock (glob->lock);
663 glob->lock = NULL;
666 /****************************************************************************************/
668 BOOL REGARGS FindVolume (GlobData *glob, UBYTE *str, struct ReqEntry *curr)
670 struct ReqEntry *entry;
671 UBYTE *s;
673 for (entry = (struct ReqEntry *)glob->firstentry->re_Next;
674 entry;
675 entry = (struct ReqEntry *)entry->re_Next)
677 if (entry != curr && entry->re_Type == VOLUME)
679 s = entry->re_Name;
680 while (*s != ' ') s++;
681 while (*s == ' ') s++;
682 if (!Stricmp (s, str)) return (TRUE);
686 return (FALSE);
689 /****************************************************************************************/
691 static BOOL
692 IsDosVolume(struct DosList *dlist)
694 #ifdef __AROS__
695 struct InfoData id;
696 BPTR lock;
697 STRPTR volName = AllocVec(strlen(dlist->dol_Ext.dol_AROS.dol_DevName) + 2,
698 MEMF_ANY);
700 /* Create a colon ended volume name, lock it and call Info() */
702 if (volName == NULL)
704 return FALSE;
707 strcpy(volName, dlist->dol_Ext.dol_AROS.dol_DevName);
708 strcat(volName, ":");
710 lock = Lock(volName, SHARED_LOCK);
712 if (lock != NULL)
714 BOOL result = Info(lock, &id);
716 UnLock(lock);
717 FreeVec(volName);
719 return result;
721 else
723 FreeVec(volName);
725 return FALSE;
728 #else
730 BOOL isdev = FALSE;
731 D_S( struct InfoData,id );
733 if( !dlist->dol_Task || DoPkt1( dlist->dol_Task, ACTION_DISK_INFO, MKBADDR( id ) ) )
735 isdev = TRUE;
738 return (isdev);
739 #endif
743 /****************************************************************************************/
745 static BOOL
746 IsDosDevice( struct DosList *dlist )
748 struct FileSysStartupMsg *fssm;
749 struct DosEnvec *de;
750 BOOL isdev = FALSE;
752 /* If it`s a device, do the hard check for a filesystem */
754 if (dlist->dol_Type == DLT_DEVICE)
756 fssm = ( struct FileSysStartupMsg * )BADDR( dlist->dol_misc.dol_handler.dol_Startup );
758 if( fssm )
760 if( TypeOfMem( fssm ) && TypeOfMem( BADDR( fssm->fssm_Device ) )
761 && TypeOfMem( BADDR( fssm->fssm_Environ ) ) )
763 if( *( ( STRPTR ) BADDR( fssm->fssm_Device ) ) != 255 )
765 de = ( struct DosEnvec * ) BADDR( fssm->fssm_Environ );
767 if( de && TypeOfMem( de ) )
769 if( de->de_Surfaces && de->de_BlocksPerTrack )
771 isdev = TRUE;
777 #ifdef TASK_DEVICE
778 else
780 isdev = ( dlist->dol_Task != NULL );
782 #endif
785 return( isdev );
788 /****************************************************************************************/
790 struct DeviceEntry
792 struct DeviceEntry *next;
793 struct MsgPort *task;
794 BOOL resolved;
795 UBYTE name[ 42 ];
798 /****************************************************************************************/
800 #define SIZE_NONE ( ( ULONG ) -1 )
801 #define SIZE_CALCULATE ( ( ULONG ) -2 )
803 /****************************************************************************************/
805 static void
806 AddDisk(
807 GlobData *glob,
808 struct DeviceEntry *deventry,
809 UBYTE *devname,
810 ULONG size,
811 ULONG volreqflags )
813 struct rtVolumeEntry volentry;
814 struct ReqEntry *entry;
815 UBYTE buffer[80];
816 int i, addentry;
818 D_S( struct InfoData, infodata );
820 addentry = TRUE;
822 if( volreqflags && glob->filterhook )
824 volentry.Type = DLT_DEVICE;
825 volentry.Name = devname;
826 addentry = CallHookPkt( glob->filterhook, glob->freq, &volentry );
829 if( addentry )
831 if( size == SIZE_CALCULATE )
833 size = SIZE_NONE;
835 #ifdef __AROS__
837 BPTR lock = Lock((CONST_STRPTR) &deventry->name, SHARED_LOCK);
839 if (lock != NULL)
841 if (Info(lock, infodata))
843 size = ( infodata->id_NumBlocksUsed * 100 +
844 infodata->id_NumBlocks / 2 ) /
845 infodata->id_NumBlocks;
847 UnLock(lock);
850 #else
851 if( deventry->task &&
852 DoPkt1( deventry->task, ACTION_DISK_INFO, MKBADDR( infodata ) ) )
854 size = ( infodata->id_NumBlocksUsed * 100 +
855 infodata->id_NumBlocks / 2 ) /
856 infodata->id_NumBlocks;
858 #endif
861 i = StrWidth_noloc( &glob->itxt, deventry->name ) + StrWidth_noloc( &glob->itxt, "W" );
863 if( i > glob->maxvolwidth )
865 glob->maxvolwidth = i;
868 DofmtArgs( buffer, "%s %s", devname, deventry->name );
870 if( ( entry = AddEntry( glob, glob->buff, buffer, size, VOLUME ) ) )
872 entry->re_VolLen = strlen( devname );
877 /****************************************************************************************/
879 static struct DeviceEntry *
880 AllocDevEntry( GlobData *glob, struct DosList *dlist, STRPTR name )
882 struct DeviceEntry *deventry;
884 if( ( deventry = ( struct DeviceEntry * ) AllocVecPooled(
885 glob->buff->pool, sizeof( struct DeviceEntry ) ) ) )
887 strcpy( deventry->name, name );
888 #ifdef __AROS__
889 #warning FIXME: dlist->dol_Task does not exist in AROS. For now assuming 0 here.
890 deventry->task = NULL;
891 #else
892 deventry->task = dlist->dol_Task;
893 #endif
894 deventry->resolved = FALSE;
897 return( deventry );
900 /****************************************************************************************/
902 static void
903 GetVolName( BSTR bstr, STRPTR cstr )
905 #ifdef __AROS__
906 /* In AROS, BPTR:s are handled differently on different systems
907 (to be binary compatible on Amiga) */
909 if (bstr != NULL)
911 LONG length = AROS_BSTR_strlen(bstr);
912 LONG i; /* Loop variable */
914 for (i = 0; i < length; i++)
916 cstr[i] = AROS_BSTR_getchar(bstr, i);
919 cstr[i++] = ':';
920 cstr[i] = 0;
922 D(bug("Found volume %s\n", cstr));
924 #else
925 STRPTR str;
927 *cstr = 0;
929 if( ( str = BADDR( bstr ) ) )
931 LONG i;
933 for( i = *str++; i--; )
935 *cstr++ = *str++;
938 *cstr++ = ':';
939 *cstr = 0;
941 #endif
945 /****************************************************************************************/
947 void REGARGS
948 AddDiskNames( GlobData *glob, ULONG volreqflags )
950 struct ReqEntry *entry, *temp;
951 struct DosList *dlist;
952 struct DeviceEntry *deventry, *lastdeventry = NULL;
953 struct rtVolumeEntry volentry;
954 UBYTE /* *bstr, *cstr, */ name[ 42 ], devname[ 36 ];
955 /* WORD i; */
957 *glob->winaddr = ( APTR ) -1;
958 glob->maxvolwidth = 0;
959 dlist = LockDosList( LDF_VOLUMES | LDF_ASSIGNS | LDF_READ );
961 /* Add PROGDIR: assign is possible, just like reqtools_patch.lha
962 from Aminet (by Mikolaj Calusinski) does. */
964 if (!(volreqflags & VREQF_NOASSIGNS))
966 if (((struct Process *)FindTask(NULL))->pr_HomeDir)
968 AddEntry(glob, glob->buff, "PROGDIR:", -1, ASSIGN);
972 while( ( dlist = NextDosEntry( dlist, LDF_VOLUMES | LDF_ASSIGNS | LDF_READ ) ) )
974 GetVolName(dlist->dol_Name, name);
975 if (dlist->dol_Type == DLT_VOLUME)
977 if (IsDosVolume(dlist) && !(volreqflags & VREQF_NODISKS))
979 if ((deventry = AllocDevEntry(glob, dlist, name)))
981 deventry->next = lastdeventry;
982 lastdeventry = deventry;
986 else if (dlist->dol_Type == DLT_DIRECTORY ||
987 dlist->dol_Type == DLT_NONBINDING)
989 if (!(volreqflags & VREQF_NOASSIGNS))
991 AddEntry(glob, glob->buff, name, -1, ASSIGN);
996 /* Append device names to volumes */
997 dlist = LockDosList( LDF_DEVICES | LDF_READ );
999 while( ( dlist = NextDosEntry( dlist, LDF_DEVICES | LDF_READ ) ) )
1001 BOOL devmatch;
1003 deventry = lastdeventry;
1004 devmatch = FALSE;
1006 while( deventry )
1008 #ifdef __AROS__
1009 #warning FIXME: AROS has no dol_Task!
1010 #else
1011 devmatch |= ( deventry->task == dlist->dol_Task );
1012 #endif
1013 #ifdef __AROS__
1014 #warning FIXME: AROS again has no dol_Task!
1015 if( !deventry->resolved && deventry->task && devmatch )
1016 #else
1017 if( !deventry->resolved && deventry->task && ( deventry->task == dlist->dol_Task ) )
1018 #endif
1020 GetVolName( dlist->dol_Name, devname );
1021 AddDisk( glob, deventry, devname, SIZE_CALCULATE, volreqflags );
1022 deventry->resolved = TRUE;
1025 deventry = deventry->next;
1028 if( !devmatch && ( volreqflags & VREQF_ALLDISKS ) &&
1029 !( volreqflags & VREQF_NODISKS ) && IsDosDevice( dlist ) )
1031 /* Device seems to be a DOS disk device, and it didn't belong
1032 * to a volume, and we should really show all devices in a
1033 * volume requester.
1035 GetVolName( dlist->dol_Name, devname );
1037 if( ( deventry = AllocDevEntry( glob, dlist, "-" ) ) )
1039 deventry->next = lastdeventry;
1040 lastdeventry = deventry;
1041 AddDisk( glob, deventry, devname, SIZE_NONE, volreqflags );
1042 deventry->resolved = TRUE;
1047 UnLockDosList( LDF_DEVICES | LDF_READ );
1048 UnLockDosList( LDF_VOLUMES | LDF_ASSIGNS | LDF_READ );
1050 /* Free temp volume list (and add remaining names if ALLDISKS is on) */
1051 while( ( deventry = lastdeventry ) )
1053 if( !deventry->resolved /* && ( !volreqflags || ( volreqflags & VREQF_ALLDISKS ) ) */ )
1055 AddDisk( glob, deventry, "-", SIZE_CALCULATE, volreqflags );
1058 lastdeventry = deventry->next;
1059 FreeVecPooled( glob->buff->pool, deventry );
1062 /* If volume requester filter assigns */
1063 if( volreqflags && glob->filterhook )
1065 entry = glob->buff->firstname;
1067 while( ( temp = entry ) )
1069 entry = ( struct ReqEntry * ) entry->re_Next;
1071 if( !entry )
1073 break;
1076 if( entry->re_Type == ASSIGN )
1078 volentry.Type = DLT_DIRECTORY;
1079 volentry.Name = entry->re_Name;
1081 if( !CallHookPkt( glob->filterhook, glob->freq, &volentry ) )
1083 temp->re_Next = entry->re_Next;
1084 FreeVecPooled( glob->buff->pool, entry );
1085 entry = temp;
1086 glob->buff->currentnum--;
1092 *glob->winaddr = glob->reqwin;
1095 /****************************************************************************************/
1097 BOOL REGARGS FindCurrentPos (GlobData *glob, char *name, int size, int ctype)
1099 BOOL success;
1101 MarkHidden (glob);
1102 success = FindEntry (glob->buff, name, size, ctype, ( int * ) &glob->buff->pos, FIND_EXACT) ? TRUE : FALSE;
1103 glob->buff->gotopos = glob->buff->pos;
1105 return (success);
1108 /****************************************************************************************/
1110 void REGARGS NewDir (GlobData *glob)
1112 UnLockReqLock (glob);
1113 SetWindowTitles (glob->reqwin, glob->title, (char *)~0);
1114 FreeReqBuffer (glob->req);
1115 ClearDisplayList (glob);
1116 glob->newdir = TRUE;
1117 glob->clicked = ~0;
1119 if (glob->freq)
1121 SetFileDirMode (glob->buff, glob->flags);
1122 glob->file_id = glob->buff->file_id;
1123 glob->directory_id = glob->buff->directory_id;
1127 /****************************************************************************************/
1129 void REGARGS ShowDisks(GlobData *glob)
1132 if (!glob->disks)
1134 UnLockReqLock (glob);
1135 FreeReqBuffer (glob->req);
1136 ClearAndInitReqBuffer (glob);
1137 glob->exnext = FALSE;
1138 glob->disks = TRUE;
1139 AddDiskNames (glob, glob->volumerequest);
1140 AdjustScroller (glob);
1141 UpdateDisplayList (glob);
1142 PrintFiles (glob);
1143 glob->buff->sorted = TRUE;
1144 glob->selectedpos = -1;
1148 /****************************************************************************************/
1150 void REGARGS UpdateNumSelGad (GlobData *glob)
1152 int top;
1153 char str[6];
1155 if (glob->numselectedgad)
1157 Dofmt (str, "%4ld", &glob->numselected);
1159 SetAPen (glob->reqrp, glob->pens[TEXTPEN]);
1160 SetBPen (glob->reqrp, glob->pens[BACKGROUNDPEN]);
1161 SetDrMd (glob->reqrp, JAM2);
1163 top = glob->numselectedgad->TopEdge + 3;
1165 Move (glob->reqrp, glob->numselectedgad->LeftEdge + glob->numselectedoff + 8,
1166 top + glob->reqfont->tf_Baseline);
1167 Text (glob->reqrp, str, 4);
1169 SetDrMd (glob->reqrp, JAM2);
1170 SetAPen (glob->reqrp, glob->pens[BACKGROUNDPEN]);
1172 RectFill (glob->reqrp, glob->reqrp->cp_x,
1173 top,
1174 glob->numselectedgad->LeftEdge + glob->numselectedgad->Width - 3,
1175 top + glob->fontheight - 1);
1179 /****************************************************************************************/
1181 /*****************
1182 * Font requester *
1183 *****************/
1185 /****************************************************************************************/
1187 static struct Region *MyInstallRegion (struct Window *win, struct Region *reg, int refresh)
1189 struct Region *oldregion;
1191 LockLayerInfo(&win->WScreen->LayerInfo);
1193 if (refresh) GT_EndRefresh (win, FALSE);
1195 oldregion = InstallClipRegion (win->WLayer, reg);
1196 if (refresh) GT_BeginRefresh (win);
1198 UnlockLayerInfo(&win->WScreen->LayerInfo);
1200 return (oldregion);
1203 /****************************************************************************************/
1205 void REGARGS ShowFontSample (GlobData *glob, int refresh, int dowait)
1207 struct DiskfontBase *DiskfontBase = glob->diskfontbase;
1208 struct TextFont *font;
1209 struct Rectangle rect;
1210 struct Region *oldregion, *region;
1211 char *message = "0123 aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ";
1212 UWORD *cmap = NULL;
1213 ULONG style = glob->fontstyle, count = glob->colcount;
1214 APTR winlock = NULL;
1216 if (dowait) winlock = rtLockWindow (glob->reqwin);
1218 if (glob->flags & FREQF_SCALE)
1219 glob->fontreq->Attr.ta_Flags &= ~FPF_DESIGNED;
1221 if (!(font = OpenDiskFont (&glob->fontreq->Attr)))
1223 font = glob->reqfont;
1224 message = GetStr (glob->catalog, MSG_COULDNT_OPEN_FONT);
1225 style = 0;
1228 rect.MinX = glob->fontdisplayleft;
1229 rect.MaxX = glob->fontdisplayright;
1230 rect.MinY = glob->fontdisplaytop;
1231 rect.MaxY = glob->fontdisplaytop + glob->sampleheight - 1;
1233 if ( ( region = NewRegion() ) )
1235 OrRectRegion (region, &rect);
1237 oldregion = MyInstallRegion (glob->reqwin, region, refresh);
1239 SetFont (glob->reqrp, font);
1240 SetSoftStyle (glob->reqrp, style, ~0);
1241 SetAPen (glob->reqrp, glob->pens[TEXTPEN]);
1242 SetBPen (glob->reqrp, glob->pens[BACKGROUNDPEN]);
1244 if (font->tf_Style & FSF_COLORFONT)
1246 struct ColorFontColors *cfc;
1248 cfc = ((struct ColorTextFont *)font)->ctf_ColorFontColors;
1249 if (cfc)
1251 count = cfc->cfc_Count;
1252 cmap = cfc->cfc_ColorTable;
1256 if (glob->flags & FREQF_CHANGEPALETTE)
1258 if (cmap) LoadRGB4 (glob->vp, cmap, count);
1259 else LoadCMap (glob->vp, glob->colormap);
1262 if (!refresh) SetRast (glob->reqrp, glob->pens[BACKGROUNDPEN]);
1264 Move (glob->reqrp, glob->fontdisplayleft,
1265 glob->fontdisplaytop + (glob->sampleheight - font->tf_YSize) / 2
1266 + font->tf_Baseline);
1267 Text (glob->reqrp, message, strlen(message));
1269 MyInstallRegion (glob->reqwin, oldregion, refresh);
1270 DisposeRegion (region);
1272 SetFont (glob->reqrp, glob->reqfont);
1273 SetSoftStyle (glob->reqrp, 0, ~0);
1276 /*endshowsample:*/
1277 CloseFont (font);
1278 if (dowait) rtUnlockWindow (glob->reqwin, winlock);
1281 /****************************************************************************************/
1283 /***********************
1284 * ScreenMode requester *
1285 ***********************/
1287 /****************************************************************************************/
1289 ULONG ASM myGetDisplayInfoData (
1290 OPT_REGPARAM(a1, UBYTE *, buf),
1291 OPT_REGPARAM(d0, unsigned long, size),
1292 OPT_REGPARAM(d1, unsigned long, tagID),
1293 OPT_REGPARAM(d2, unsigned long, displayID))
1295 return (GetDisplayInfoData (FindDisplayInfo (displayID),
1296 buf, size, tagID, displayID));
1299 /****************************************************************************************/
1301 int REGARGS GetModeData (GlobData *glob, ULONG id, int *mon)
1303 struct MonitorInfo monitorinfo;
1304 ULONG propflags;
1305 int modewidth, stdmode = TRUE;
1306 char *str, *monstr;
1308 if ((myGetDisplayInfoData ((UBYTE *)&glob->diminfo,
1309 sizeof (struct DimensionInfo), DTAG_DIMS, id) <= 0) ||
1310 (myGetDisplayInfoData ((UBYTE *)&glob->dispinfo,
1311 sizeof (struct DisplayInfo), DTAG_DISP, id) <= 0))
1313 return (FALSE);
1316 modewidth = glob->diminfo.Nominal.MaxX - glob->diminfo.Nominal.MinX + 1;
1317 propflags = glob->dispinfo.PropertyFlags;
1319 if ((glob->flags & SCREQF_GUIMODES) && !(propflags & DIPF_IS_WB))
1320 return (FALSE);
1322 *mon = ((id & MONITOR_ID_MASK) >> 16) - 1;
1324 if (myGetDisplayInfoData ((UBYTE *)&glob->nameinfo,
1325 sizeof (struct NameInfo), DTAG_NAME, id) <= 0)
1327 str = glob->nameinfo.Name;
1328 if ((myGetDisplayInfoData ((UBYTE *)&monitorinfo, sizeof (struct MonitorInfo), DTAG_MNTR, id) > 0)
1329 && monitorinfo.Mspc)
1331 monstr = monitorinfo.Mspc->ms_Node.xln_Name;
1332 while (*monstr > '.') *str++ = ToUpper (*monstr++);
1333 *str++ = ':';
1336 DofmtArgs (str, "%ld x %ld", modewidth,
1337 glob->diminfo.Nominal.MaxY - glob->diminfo.Nominal.MinY + 1);
1339 if (propflags & DIPF_IS_HAM)
1341 StrCat (str, GetStr (glob->catalog, MSG_DASH_HAM));
1342 stdmode = FALSE;
1345 if (propflags & DIPF_IS_EXTRAHALFBRITE)
1347 StrCat (str, GetStr (glob->catalog, MSG_DASH_EHB));
1348 stdmode = FALSE;
1351 if (propflags & DIPF_IS_LACE)
1352 StrCat (str, GetStr (glob->catalog, MSG_DASH_INTERLACED));
1356 /* check property flags using mask */
1357 if ((propflags & glob->propertymask) != (glob->propertyflags & glob->propertymask))
1358 return (FALSE);
1360 /* check if depth larger than minimum depth */
1361 if (glob->diminfo.MaxDepth < glob->mindepth) return (FALSE);
1363 /* GUI modes ? */
1364 if (glob->flags & SCREQF_GUIMODES)
1366 return (stdmode && (modewidth >= 640));
1369 /* include non-standard modes ? */
1370 if (!(glob->flags & SCREQF_NONSTDMODES)) return (stdmode);
1372 return (TRUE);
1375 /****************************************************************************************/
1377 void REGARGS SetTextGad (GlobData *glob, struct Gadget *gad, char *text)
1379 if (!gad) return;
1381 myGT_SetGadgetAttrs (gad, glob->reqwin, NULL, GTTX_Text, (IPTR) text,
1382 TAG_END);
1385 /****************************************************************************************/
1387 void REGARGS SetSizeGads (GlobData *glob)
1389 if (glob->usedefwidth) glob->width = glob->defwidth;
1390 if (glob->usedefheight) glob->height = glob->defheight;
1391 if (glob->width > glob->maxwidth) glob->width = glob->maxwidth;
1392 if (glob->width < glob->minwidth) glob->width = glob->minwidth;
1394 my_SetIntegerGadget (glob->reqwin, glob->widthgad, glob->width);
1396 if (glob->height > glob->maxheight) glob->height = glob->maxheight;
1397 if (glob->height < glob->minheight) glob->height = glob->minheight;
1399 my_SetIntegerGadget (glob->reqwin, glob->heightgad, glob->height);
1402 /****************************************************************************************/
1404 LONG REGARGS IntGadgetBounds (GlobData *glob, struct Gadget *gad,
1405 LONG min, LONG max)
1407 LONG val;
1409 val = ((struct StringInfo *)gad->SpecialInfo)->LongInt;
1411 if (val > max)
1413 val = max;
1414 my_SetIntegerGadget (glob->reqwin, gad, val);
1417 if (val < min)
1419 val = min;
1420 my_SetIntegerGadget (glob->reqwin, gad, val);
1423 return (val);
1426 /****************************************************************************************/
1428 int overscantrans[] = { 0, 3, 4, 1 };
1430 /****************************************************************************************/
1432 void REGARGS GetModeDimensions (GlobData *glob)
1434 struct Rectangle *rect;
1436 if (glob->modeid != INVALID_ID)
1438 rect = &(&glob->diminfo.Nominal)[overscantrans[glob->overscantype]];
1439 glob->defwidth = rect->MaxX - rect->MinX + 1;
1440 glob->defheight = rect->MaxY - rect->MinY + 1;
1442 else glob->defwidth = glob->defheight = 0;
1445 /****************************************************************************************/
1447 void BuildColStr (char *colstr, LONG colors, ULONG id)
1449 colors = 1 << colors;
1451 if (id & HAM)
1452 colors = (colors == 128 ? 4096 : 16777216L);
1454 if (id & EXTRA_HALFBRITE )
1455 colors = 64;
1457 if (colors <= 9999)
1459 DofmtArgs (colstr, "%ld", colors);
1460 return;
1463 colors /= 1024;
1464 if (colors <= 999)
1466 DofmtArgs (colstr, "%ldK", colors);
1467 return;
1470 colors /= 1024;
1472 DofmtArgs (colstr, "%ldM", colors);
1475 /****************************************************************************************/
1477 void REGARGS UpdateDepthDisplay (GlobData *glob, int depth, ULONG id)
1479 BuildColStr (glob->currcolstr, depth, id);
1481 myGT_SetGadgetAttrs (glob->currcolgad, glob->reqwin, NULL, GTTX_Text, (IPTR) glob->currcolstr,
1482 TAG_END);
1485 /****************************************************************************************/
1487 void REGARGS UpdateDepthGad (GlobData *glob)
1489 UpdateDepthDisplay (glob, glob->depth, glob->modeid);
1491 myGT_SetGadgetAttrs (glob->depthgad, glob->reqwin, NULL, GTSL_Min, glob->currmindepth,
1492 GTSL_Max, glob->currmaxdepth,
1493 GTSL_Level, glob->depth,
1494 GA_Disabled, (glob->currmindepth == glob->currmaxdepth),
1495 TAG_END);
1498 /****************************************************************************************/
1500 void REGARGS DisplayModeAttrs (GlobData *glob)
1502 if (glob->modeid != INVALID_ID)
1504 int maxdepth = glob->diminfo.MaxDepth, mindepth = 1;
1506 if( maxdepth < 0 || maxdepth > 24 )
1508 maxdepth = 24;
1511 if (glob->depth > maxdepth || !(glob->flags & SCREQF_DEPTHGAD))
1512 glob->depth = maxdepth;
1514 /* if (glob->modeid & HAM) mindepth = maxdepth = glob->depth = 12; */
1515 /* if (glob->modeid & EXTRA_HALFBRITE) mindepth = maxdepth = glob->depth = 6; */
1517 if (glob->depthgad)
1519 if (glob->modeid & EXTRA_HALFBRITE)
1521 mindepth = maxdepth;
1524 if (glob->modeid & HAM)
1526 mindepth = 7;
1528 if (maxdepth == 6)
1529 ++maxdepth;
1532 glob->currmaxdepth = maxdepth; glob->currmindepth = mindepth;
1534 if (glob->currmaxdepth > glob->maxdepth) glob->currmaxdepth = glob->maxdepth;
1535 if (glob->currmindepth < glob->mindepth) glob->currmindepth = glob->mindepth;
1536 if (glob->depth > glob->currmaxdepth) glob->depth = glob->currmaxdepth;
1537 if (glob->depth < glob->currmindepth) glob->depth = glob->currmindepth;
1539 UpdateDepthGad (glob);
1540 BuildColStr (glob->maxcolstr, glob->currmaxdepth, glob->modeid);
1541 myGT_SetGadgetAttrs (glob->maxcolgad, glob->reqwin, NULL,
1542 GTTX_Text, (IPTR) glob->maxcolstr, TAG_END);
1544 SetSizeGads (glob);
1546 } /* if (glob->modeid != INVALID_ID) */
1549 /****************************************************************************************/